AngularJS 和 Youtube,在视频播放完毕后调用脚本
AngularJS and Youtube, call a script when video finishes playing
我正在尝试在 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>
但是没有任何反应。
我的控制台日志显示 'setting up video player' 和播放器 ID,但 onYouTubePlayerAPIReady 从未被调用。
有人可以帮我吗?
原因可能是因为您定义的函数位于链接函数闭包的指令中。 YouTube api 无法访问该方法。您需要将其放入 window 对象。您可以通过以下几种方式:
1) 创建全局函数并通过事件通知
就在你的 body 标签结束之前,将函数放在全局范围内并获取 angular 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'), {
.....
});
});
}
}
}]);
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');
}
}
}
}
}]);
我正在尝试在 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>
但是没有任何反应。 我的控制台日志显示 'setting up video player' 和播放器 ID,但 onYouTubePlayerAPIReady 从未被调用。
有人可以帮我吗?
原因可能是因为您定义的函数位于链接函数闭包的指令中。 YouTube api 无法访问该方法。您需要将其放入 window 对象。您可以通过以下几种方式:
1) 创建全局函数并通过事件通知
就在你的 body 标签结束之前,将函数放在全局范围内并获取 angular 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'), {
.....
});
});
}
}
}]);
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');
}
}
}
}
}]);