YouTube在IOS和Android上嵌入了API问题

Rol*_*oós 7 javascript youtube-api

最近几天,YouTube嵌入API出现了问题.问题是,当您使用官方API嵌入视频时,它只是不允许您访问API.当您尝试访问API时,您在日志(IOS)上收到错误消息,如果您尝试通过API播放视频,则视频会消失.如果您通过API加载它,但不使用API​​,则用户可以通过点击播放视频.

该问题在以下浏览器中仍然存在:

iPad和iPhone上的IOS 7 Safari IOS 7 iPad和iPhone上的Chrome Android 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.
Run Code Online (Sandbox Code Playgroud)

一些调试信息:

我看到API在网站上创建iframe.src有时是http,有时是https.

http://www.youtube.com/embed/ZPy9VCovVME?enablejsapi=1&origin=http%3A%2F%2Ffiddle.jshell.net&autoplay=0&modestbranding=1&wmode=opaque&forceSSL=false

我的测试表明,大多数时候YouTube服务器只是LOCATION:https:// ...对https网址的请求,但大约10%他们用适当的内容提供了http请求.

我想某个问题与强制https有关,但我无法弄清楚解决方案.你有相同的经历吗?你有解决这个问题的方法吗?这是YouTube的错误吗?

我的测试代码:

<div id="myvideo"></div>
<button id="play-button">Play</button>
Run Code Online (Sandbox Code Playgroud)

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;
                        }
                    }
                }
            });
}
Run Code Online (Sandbox Code Playgroud)

PSa*_*tra 2

首先,我认为这与以下问题重复:YouTube IFrame API play method does not work before touch on some Android pictures

我可以在YouTube 播放器演示页面上重现相同的问题。

错误

无法将消息发布到https://www.youtube.com。收件人来源为http://fiddle.jshell.net

仅发生在您的 jsfiddle 上。在演示页面上,没有发生此错误,因此您观察到的错误似乎与控制台中记录的错误无关。我在 Android 4.4.4 上用 chrome 检查了这一点。

解决方法

我有一个肮脏的解决方法,适用于 Android 4.4.4 (Nexus5) 和 4.1.2 (S2) 上的 Chrome。我没有 iOS 设备来测试这个。该解决方法适用于我的手机,因为视频总是在我第二次单击播放按钮时开始。

http://jsfiddle.net/kjwpwpx8/6/

在调用 playVideo 函数一次之后,我总是可以在点击事件上启动视频。在我的解决方法中,我在页面上放置了两个 iframe。一个是隐藏的,而另一个是可见的。如果通过移动浏览器查看页面,我会在 OnReady-Event 之后调用第二个视频的 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);
Run Code Online (Sandbox Code Playgroud)