如何在iPad上使用Youtube iFrame API修复“如果播放不能立即开始,请尝试重启设备”?

时间:2015-11-24 20:07:31

标签: javascript ios youtube youtube-api youtube-javascript-api

我创建了一个小的YouTube流媒体脚本,随机播放YouTube音乐视频或从队列中播放。它在几个月内一直运行良好,直到本周,它似乎不想在使用iPad / iPhone时加载视频。我得到了以下错误:

  

如果不立即开始播放,请尝试重启设备

我尝试了什么:

我尝试过Safari,Chrome,Firefox和Opera,但他们都错了。我已经尝试清除网站数据/缓存,重启设备,重新启动设备。什么都行不通。奇怪的是,它在Windows桌面上运行得非常好,这使我相信它不是代码中的错误,而是通过API或Safari改变的东西。我的代码最近没有被编辑,这可能导致它停止工作。

我尝试使用jsconsole.com进行调试,没有任何可疑的弹出窗口。在某些情况下,播放器将加载,视频的标题将显示,图像也将显示,但在大约30秒后,上面的错误将与加载微调器一起显示。

我知道playVideo();在iOS设备上无效(自动播放)。这很好,再一次,脚本以前工作过,我只需要按第一个视频播放。但现在,似乎iOS正试图自动播放视频。所以,我还通过删除playVideo()调用进行测试,问题仍然存在。

在iPad 2,iPad mini和iPhone 4上进行了测试(所有设备都配备了最新的iOS,并且之前都有效)。

我很茫然,并试图在周末之前为家庭聚会修复此问题:)所以我很感激任何帮助或暗示可能导致iOS失败的原因。

以下是javascript代码:

// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// 3. This function creates an <iframe> (and YouTube player)
//    after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        height: '390',
        width: '640',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
        }
    });
}

// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
    check_queue_timer = setTimeout(check_queue(),3000);
}

// 5. The API calls this function when the player's state changes.
//    The function indicates that when playing a video (state=1),
//    the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
    if (event.data === 0) {
        // TRACK AS DONE, REFRESH QUEUE AND GET NEXT SONG
        // POST TO WRITE TO FILE
        $.ajax({
            type: 'POST',
            url: site_url+'ajax_next_track',
            dataType: 'json',
            data: 'queue_id='+$('#queue_id').val(),
            cache: false,
            success:
            function(data){

                if(data.status == 'success'){
                    $("#queue_table").empty();
                    if(data.queue.length == 0){
                        check_queue_timer = setTimeout(check_queue(),3000);
                    }
                    $.each(data.queue, function(i, item) {
                        if(i == 0){
                            event.target.loadVideoById(item.video_id);
                            event.target.playVideo();
                            $('#queue_id').val(item.queue_id);
                        }
                        $('#queue_table').append('<tr><td>'+item.title+'</td></tr>');
                    });
                }
                else{
                    console(data.message);
                }
            },
            error:
            function( jqXHR, textStatus, errorThrown ){
                $('#error_msg').html('Something broke.').fadeIn();
            }

        });
    }
}
function stopVideo() {
    player.stopVideo();
}

function check_queue(){
    $.ajax({
        type: 'POST',
        url: site_url+'ajax_next_track',
        dataType: 'json',
        data: 'no_delete=1',
        cache: false,
        success:
        function(data){

            if(data.status == 'success'){
                $("#queue_table").empty();
                if(data.queue.length == 0){
                    clearTimeout(check_queue_timer);
                    check_queue_timer = setTimeout(check_queue(),3000);
                }
                $.each(data.queue, function(i, item) {
                    if(i == 0){
                        player.loadVideoById(item.video_id);
                        player.playVideo();
                        $('#queue_id').val(item.queue_id);
                        clearTimeout(check_queue_timer);
                    }
                    $('#queue_table').append('<tr><td>'+item.title+'</td></tr>');
                });
            }
            else{
                console(data.message);
            }
        },
        error:
        function( jqXHR, textStatus, errorThrown ){
            $('#error_msg').html('Something broke.').fadeIn();
        }

    });
}

更新1(2015年11月25日)

我决定从头开始使用https://developers.google.com/youtube/iframe_api_reference上的示例代码。似乎loadVideoById()不再适用于iPad。它在此之前。如果我不包含loadVideoById()或playVideo(),它可以工作。理想情况下,我希望它能与loadVideoById()一起使用。

4 个答案:

答案 0 :(得分:7)

我试图解决这个问题几个小时就撞到电脑上......这就是我发现的。

这是因为Apple严格的iOS限制:网页只能在直接回复用户反馈时开始播放音频/视频。 (请注意,此限制仅影响页面上播放的第一次时间音频/视频。)

通常,要解决Apple的限制,确保play()调用直接在事件处理程序(例如,单击处理程序)中发生就足够了。这适用于Web Audio API和普通HTML5视频 - 但有关YouTube播放器的内容无法阻止其在YouTube上使用。

因此,YouTube的解决方案显然是要求用户点击YouTube视频本身以启动播放。从那时起,您可以使用YouTube iframe API(播放,暂停,搜索等)来控制它。但是,在用户点击视频之后,您无法使用API​​控制YouTube视频。

为了获得万无一失的用户体验,您可以隐藏所有播放器控制用户界面,并告诉用户点击YouTube视频本身即可开始播放。然后,一旦用户点击了一次视频,就可以激活你的用户界面。当然,您应该将其设计为仅适用于iOS。

感谢头痛,Apple!

答案 1 :(得分:5)

我有一个类似的问题,并进行了一些挖掘,结果Apple已经删除了通过脚本等自动播放嵌入项目的能力,因此最终用户不会意外地耗尽他们的数据。用户需要自己触发播放按钮。

解决此问题的最佳方法是检查用户是在移动设备还是桌面设备上并设置变量(true / false)。

这就是我做的事情

&#13;
&#13;
var mobileDevice = false;
if(typeof window.orientation !== 'undefined'){
	var mobileDevice = true;
}

if(!mobileDevice) ytPlayer.playVideo();
&#13;
&#13;
&#13;

希望这有帮助。

Source (https://developer.apple.com)

  

防止用户通过蜂窝网络进行未经请求的下载   费用,嵌入式媒体无法在Safari上自动播放   iOS-用户始终启动播放。

此处有更多答案 - YouTube API not working with iPad / iPhone / non-Flash device

答案 2 :(得分:1)

如果问题是其他两个答案(Adrian&amp; Junior)所说的那么应该通过访问UIWebView(或WKWebView)并设置mediaPlaybackRequiresUserAction标志来轻松解决。如果您推出自己的解决方案或使用官方框架(https://github.com/youtube/youtube-ios-player-helper)。

,则可以执行此操作

夫特

let playerView = YTPlayerView()
playerView.webView.mediaPlaybackRequiresUserAction = false

答案 3 :(得分:0)

我在将DPS音频应用程序安装到笔记本电脑后遇到了问题。这些应用将我现有的音频驱动程序修改为&#34;扬声器(数字电站)&#34; 音频设备。

通过阅读Reddit帖子,我将音频设备替换为我的笔记本电脑的来源。因此,这个问题已经解决了。