【问题标题】:Youtube iframe Api and Angularjs routeYoutube iframe Api 和 Angularjs 路由
【发布时间】:2015-10-27 23:55:10
【问题描述】:

我遇到了与 angularjs 一起使用的 Youtube Iframe Api 的问题。

我认为问题在于“onYouTubeIframeAPIReady”函数的调用。

我将 angularjs 与路由一起使用,当路由更改时该函数不会触发,但是当我按下 F5 时,播放器已加载。

有没有办法让 angularjs 与路由和 youtube API 一起工作?

我没有设法在代码中添加更多文件,但“pageX.htm”看起来像这样:

<button ng-click="video()">Create</button>
<div youtube-player id="test-playerX" ></div>

还有“index.htm”的代码

<!DOCTYPE html>
<html ng-app="sc">
  <body>

    Homepage - <a href="#page1">Page1</a> - <a href="#page2">Page2</a>

    <div ng-view></div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
    <script src="https://code.angularjs.org/1.4.3/angular-route.min.js"></script>
    
    <script>
      var sc = angular.module('sc', ['ngRoute']);

      sc.config(['$routeProvider', function($routeProvider) {
        $routeProvider
          .when('/page1', {
            templateUrl: 'page1.htm'
          })
          .when('/page2', {
            templateUrl: 'page2.htm'
          })
      }]);

            // Run
      sc.run(['$rootScope', function($rootScope) {

                var tag = document.createElement('script');

                // This is a protocol-relative URL as described here:
                //     http://paulirish.com/2010/the-protocol-relative-url/
                // If you're testing a local page accessed via a file:/// URL, please set tag.src to
                //     "https://www.youtube.com/iframe_api" instead.
                tag.src = "http://www.youtube.com/iframe_api";
                var firstScriptTag = document.getElementsByTagName('script')[0];
                firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
            }]);


      sc.service('youtubePlayerApi', ['$window', '$rootScope', '$log', function ($window, $rootScope, $log) {
        var service = $rootScope.$new(true);

        // Youtube callback when API is ready
        $window.onYouTubeIframeAPIReady = function () {
            $log.info('Youtube API is ready');
            service.ready = true;
            service.createPlayer();
        };

        service.ready = false;
        service.playerId = null;
        service.player = null;
        service.videoId = "sGPrx9bjgC8";
        service.playerHeight = '390';
        service.playerWidth = '640';

        service.bindVideoPlayer = function (elementId) {
            $log.info('Binding to player ' + elementId);
            service.playerId = elementId;
        };

        service.createPlayer = function () {
            $log.info('Creating a new Youtube player for DOM id ' + this.playerId + ' and video ' + this.videoId);
            return new YT.Player(this.playerId, {
                height: this.playerHeight,
                width: this.playerWidth,
                videoId: this.videoId
            });
        };

        service.loadPlayer = function () {
            // API ready?
            if (this.ready && this.playerId && this.videoId) {
                if(this.player) {
                    this.player.destroy();
                }

                this.player = this.createPlayer();
            }
        };

        return service;
      }]);

      sc.directive('youtubePlayer', ['youtubePlayerApi', function (youtubePlayerApi) {
          return {
              restrict:'A',
              link:function (scope, element) {
                  youtubePlayerApi.bindVideoPlayer(element[0].id);
              }
          };
      }]);
      
      sc.controller('replaycontroller', function ($scope,youtubePlayerApi) {
              $scope.video = function () {
                youtubePlayerApi.createPlayer();
                console.log("test");
              }

          });
    </script>


  </body>
</html>

任何帮助表示赞赏:)

[编辑]:我更新了代码来测试函数 createPlayer 并确认播放器在更改页面时正在工作

【问题讨论】:

    标签: angularjs youtube-iframe-api


    【解决方案1】:

    正如 Karan Kapoor 在最后一条评论中所说,将 youtube api 与 angularjs 一起使用的最佳方法是使用 github.com/brandly/angular-youtube-embed

    【讨论】:

      【解决方案2】:

      好的,我找到了一个解决方案,它远不是最干净的,但它有效。

      我承认,当您更改路由时,在控制器中,youtube api 已经初始化。所以控制器只是创建了播放器。

      当请求 F5 或第一次加载时,我们必须触发 onYouTubeIframeAPIReady 以实例化播放器。

      代码如下:

      <!DOCTYPE html>
      <html ng-app="sc">
        <body>
      
          Homepage - <a href="#page1">Page1</a> - <a href="#page2">Page2</a>
      
          <div ng-view></div>
      
          <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
          <script src="https://code.angularjs.org/1.4.3/angular-route.min.js"></script>
          
          <script>
            var sc = angular.module('sc', ['ngRoute']);
      
            sc.config(['$routeProvider', function($routeProvider) {
              $routeProvider
                .when('/page1', {
                  templateUrl: 'page1.htm',
                  controller: 'replaycontroller'
                })
                .when('/page2', {
                  templateUrl: 'page2.htm'
                })
            }]);
      
                  // Run
            sc.run(['$rootScope', function($rootScope) {
                     var tag = document.createElement('script');
      
                      // This is a protocol-relative URL as described here:
                      //     http://paulirish.com/2010/the-protocol-relative-url/
                      // If you're testing a local page accessed via a file:/// URL, please set tag.src to
                      //     "https://www.youtube.com/iframe_api" instead.
                      tag.src = "http://www.youtube.com/iframe_api";
                      var firstScriptTag = document.getElementsByTagName('script')[0];
                      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
                     
                  }]);
      
      
            sc.service('youtubePlayerApi', ['$window', '$rootScope', '$log', function ($window, $rootScope, $log) {
              var service = $rootScope.$new(true);
      
              // Youtube callback when API is ready
              $window.onYouTubeIframeAPIReady = function () {
                  $log.info('Youtube API is ready');
                  service.ready = true;
                  service.createPlayer();
              };
      
              service.ready = false;
              service.playerId = null;
              service.player = null;
              service.videoId = "sGPrx9bjgC8";
              service.playerHeight = '390';
              service.playerWidth = '640';
      
              service.getStatus = function () {
                return service.ready;
              };
      
              service.bindVideoPlayer = function (elementId) {
                  $log.info('Binding to player ' + elementId);
                  service.playerId = elementId;
              };
      
              service.createPlayer = function () {
                  $log.info('Creating a new Youtube player for DOM id ' + this.playerId + ' and video ' + this.videoId);
                  return new YT.Player(this.playerId, {
                      height: this.playerHeight,
                      width: this.playerWidth,
                      videoId: this.videoId
                  });
              };
      
              service.loadPlayer = function () {
                  // API ready?
                  if (this.ready && this.playerId && this.videoId) {
                      if(this.player) {
                          this.player.destroy();
                      }
      
                      this.player = this.createPlayer();
                  }
              };
      
              return service;
            }]);
      
            sc.directive('youtubePlayer', ['youtubePlayerApi', function (youtubePlayerApi) {
                return {
                    restrict:'A',
                    link:function (scope, element) {
                        youtubePlayerApi.bindVideoPlayer(element[0].id);
                    }
                };
            }]);
      
            sc.controller('replaycontroller', function ($scope,youtubePlayerApi) {
              if (youtubePlayerApi.getStatus() == true) {
                youtubePlayerApi.bindVideoPlayer("test-player1");
                youtubePlayerApi.createPlayer();
              }
            });
      
              
          </script>
      
      
        </body>
      </html>

      【讨论】:

      • 你最后是怎么用的?如何将它与同一页面上的多个 youtube 视频一起使用?所以基本上我会将所有 youtube 视频 ID 放在一个数组中,我想在页面上将它们初始化为 ng-repeat 中的视频,然后分别捕获每个视频的事件。知道如何做到这一点吗?
      • 你好,终于我不再使用 youtube api 而是使用 youtube iframe 标签......在 angularjs 应用程序上实现 youtube api 真的很不容易。对不起,我没有帮助
      • 找到了最好的方法。如果您想自己实现它,请使用 Google 的 iFrame API。或使用角度回购github.com/brandly/angular-youtube-embed。我用的是后者。 :)
      • 谢谢你,我会尽快尝试
      【解决方案3】:

      我遇到了同样的问题,我所做的是将脚本重置为 null,然后再次设置:

      init() {
          if (window["YT"]) {
              window["YT"] = null;
              this.tag = document.createElement("script");
              this.tag.src = "https://www.youtube.com/iframe_api";
              this.firstScriptTag = document.getElementsByTagName("script")[0];
              this.firstScriptTag.parentNode.insertBefore(this.tag, this.firstScriptTag);
          }
          this.tag = document.createElement("script");
          this.tag.src = "https://www.youtube.com/iframe_api";
          this.firstScriptTag = document.getElementsByTagName("script")[0];
          this.firstScriptTag.parentNode.insertBefore(this.tag, this.firstScriptTag);
          window["onYouTubeIframeAPIReady"] = () => this.startVideo();
      }
      

      【讨论】:

        猜你喜欢
        • 2019-12-06
        • 1970-01-01
        • 2013-10-19
        • 2018-04-28
        • 1970-01-01
        • 2023-03-10
        • 2016-02-21
        • 2015-04-02
        • 2013-10-22
        相关资源
        最近更新 更多