AngularJS和Youtube,在视频播放完毕后调用脚本

时间:2015-06-04 23:53:35

标签: javascript angularjs youtube

我试图在youtube播放视频时调用一个函数。 我已经设置了这样的视图:

<div class="row">
    <div class="col-md-6">

        <div id="player" ts-video-player></div>

    </div>
</div>

然后我决定建立一个这样的指令:

.directive('tsVideoPlayer', ['$state', function ($state) {


    // autoplay video
    function onPlayerReady(event) {
        console.log('autoplay');

        event.target.playVideo();
    }

    // when video ends
    function onPlayerStateChange(event) {
        if (event.data === 0) {
            console.log('finsihed');

            alert('done');
        }
    }

    return {
        restrict: 'A',
        link: function (scope, element) {

            console.log('set up player');
            console.log(element.attr('id'));

            function onYouTubePlayerAPIReady() {

                console.log('Creating player');

                var player = new YT.Player(element.attr('id'), {
                    height: '390',
                    width: '640',
                    videoId: 'GE2BkLqMef4',
                    events: {
                        'onReady': onPlayerReady,
                        'onStateChange': onPlayerStateChange
                    }
                });
            }
        }
    }
}])

我已将此脚本包含在index.html文件中:

<script src="http://www.youtube.com/player_api"></script>

但没有任何反应。 我的控制台日志显示“设置视频播放器”和播放器ID,但 onYouTubePlayerAPIReady 永远不会被调用。

有人能帮助我吗?

1 个答案:

答案 0 :(得分:1)

原因可能是因为您定义的函数位于链接函数闭包的指令中。 YouTube API无法访问该方法。你需要把它放在窗口对象上。你可以用两种方式:

1)创建一个全局函数并通过事件通知

在您的body标记结束之前,将该函数放在全局范围内并获取角度rootScope元素并广播事件:

<script>
  function onYouTubePlayerAPIReady(){
    angular.element(document).ready(function(){
       var rootScope = angular.element(document).injector().get('$rootScope');
       rootScope.$broadcast('onYouTubePlayerAPIReady');
    });
  }
</script>
<script src="http://www.youtube.com/player_api"></script>

并在您的指令中订阅此事件。

.directive('tsVideoPlayer', [function () {


    // autoplay video
    //....

    return {
        restrict: 'A',
        link: function (scope, element) {
           //....
            scope.$on('onYouTubePlayerAPIReady', function() {
              console.log('Creating player');
               var player = new YT.Player(element.attr('id'), {
                  .....
                });
            });
        }
    }
}]);

<强> Demo

2)检查指令本身的状态

另一种方法是检查YT对象及其loaded状态并执行必要的操作。

.directive('tsVideoPlayer', ['$window', function ($window) {

    return {
        restrict: 'A',
        link: function (scope, element) {
            console.log(YT.loaded);

            if (!YT) {
                console.log('playerNotLoaded');
                $window.onYouTubePlayerAPIReady = onPlayerRady;
            } else if (YT.loaded) {
                onPlayerRady();
            } else {
                YT.ready(onPlayerRady);
            }

            function onPlayerRady() {
                console.log('Creating player');
                var player = new YT.Player(element.attr('id'), {
                    height: '390',
                    width: '640',
                    videoId: 'GE2BkLqMef4',
                    events: {
                        'onReady': onPlayerReady,
                            'onStateChange': onPlayerStateChange
                    }
                });
            }

            console.log(YT.loaded);
            // autoplay video
            function onPlayerReady(event) {
                console.log('autoplay');

                event.target.playVideo();
            }

            // when video ends
            function onPlayerStateChange(event) {
                if (event.data === 0) {
                    console.log('finsihed');

                    alert('done');
                }
            }

        }
    }
}]);

<强> Demo