最近几天,YouTube嵌入API出现了一个问题。问题是,当你使用官方API嵌入视频时,它根本不允许你访问API。当你试图访问API时,你会在日志(IOS)上收到错误消息,如果你试图通过API播放视频,视频就会变黑。如果你通过API加载,但你不使用API,用户可以通过点击播放视频。
该问题在以下浏览器上持续存在:
iPad和iPhone上的IOS 7 SafariiPad和iPhone上的IOS 7 Chrome安卓4 Chrome
(我的播放按钮使用API播放视频,这会产生错误)JSfiddle:http://jsfiddle.net/frdd8nvr/6/
错误消息:
Unable to post message to https://www.youtube.com. Recipient has origin http://fiddle.jshell.net.
postMessage[native code]:0
Jwww-widgetapi.js:26:357
Nwww-widgetapi.js:25
(anonymous function)[native code]:0
html5player.js:1201:97
Blocked a frame with origin "https://www.youtube.com" from accessing a frame with origin "http://jsfiddle.net". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match.
一些调试信息:
正如我所看到的API在网站上创建iframe。src有时是http,有时是https。
http://www.youtube.com/embed/ZPy9VCovVME?enablejsapi=1&origin=http%3A%2F%2Fiddy.jshell.net&自动播放=0&modestbranding=1&wmode=不透明&forceSSL=错误
我的测试表明,大多数时候YouTube服务器只是位置:https://...请求到https url,但大约10%的人为http请求提供了适当的内容。
我认为这个问题与强制https有关,但我无法找到解决方案。你也有同样的经历吗?你有解决这个问题的办法吗?这是YouTube上的漏洞吗?
我的测试代码:
<div id="myvideo"></div>
<button id="play-button">Play</button>
JS:
var tag = document.createElement("script");
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
onYouTubeIframeAPIReady = function () {
var vars = {
enablejsapi: 1,
origin: window.location.protocol + "//" + window.location.host,
autoplay: 0,
modestbranding: 1,
wmode: "opaque",
forceSSL: false
};
if (+(navigator.platform.toUpperCase().indexOf('MAC') >= 0 && navigator.userAgent.search("Firefox") > -1)){
vars.html5 = 1;
}
var playerobj = new YT.Player('myvideo', {
videoId: 'ZPy9VCovVME',
wmode: 'opaque',
playerVars: vars,
events: {
onReady: function(){
$('#play-button').on('click', function(){
playerobj.playVideo();
});
//playerobj.playVideo();
},
onStateChange: function(state){
switch(state.data){
case YT.PlayerState.PLAYING:
break;
//case YT.PlayerState.PAUSED:
case YT.PlayerState.ENDED:
break;
}
}
}
});
}
首先,我认为这是以下问题的重复:YouTube IFrame API播放方法没有';在某些安卓平板电脑上触摸前无法工作
我可以在YouTube播放器演示页面上重现同样的问题。
错误
无法将消息发布到https://www.youtube.com.收件人有来源http://fiddle.jshell.net.
只发生在你的jsfiddle上。在演示页面上,这个错误没有发生,因此您观察到的错误似乎与控制台中记录的错误无关。我在安卓4.4.4上用chrome检查了一下。
解决方案
我有一个肮脏的解决方法,它适用于Android 4.4.4(Nexus5)和4.1.2(S2)上的chrome。我没有iOS设备来测试这个。解决方法在我的手机上有效,因为视频总是在我第二次点击播放按钮时开始。
http://jsfiddle.net/kjwpwpx8/6/
在之前调用过一次playVideo函数后,我总是可以在单击事件时启动视频。在我的变通方法中,我在页面上放了两个iframe。一个是隐藏的,而另一个是可见的。如果页面是通过移动浏览器查看的,我会调用OnReady事件后第二个视频的playVideo功能。由于浏览器阻止此操作,视频将无法播放。
现在,当按下播放按钮时,第一个视频将被隐藏并停止,第二个视频将可见,并再次调用playVideo功能。
这是重要的代码:
var playerOptions = {
videoId: 'ZPy9VCovVME',
wmode: 'opaque',
playerVars: vars,
events: {}
};
var playerobj1 = new YT.Player('myvideo1', playerOptions);
var playerobj2 = null;
playerOptions.events.onReady = function(){
$('#play-button').on('click', function(){
$("#videowrapper .video1wrapper").hide();
playerobj1.stopVideo();
$("#videowrapper .video2wrapper").show();
playerobj2.playVideo();
});
if(isMobileBrowser)
playerobj2.playVideo();
};
playerobj2 = new YT.Player('myvideo2', playerOptions);