首页 文章

嵌入的YouTube视频无法重播

提问于
浏览
1

奇怪之一:嵌入的YouTube视频,一旦播放(通过单击“播放”或在页面加载时自动播放)将无法再次播放 .

我正在使用直接从YouTube复制的标准iFrame嵌入 . 这种情况发生在几个不同的短视频和我测试过的所有浏览器/操作系统组合中(Windows / Mac上的Chrome / Safari / Firefox / IE) .

这是代码:

<iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen></iframe>

你可以在this fiddle看到它的实际效果 .

3 回答

  • 3

    因此,问题似乎与视频长度无关;这是flash播放器的问题 . 如果加载了Flash播放器,并且根本没有用户与控件的交互,那么当播放器完成时它将不会重新加载iframe(尽管事实上它会引发'视频结束'事件...当你尝试重新加载它不会发出重新加载视频的正确调用,因此永远不会重新开始播放) . 您也可以测试更长的视频;如果您开始观看它们并且不使用擦洗条,它们将表现出相同的行为 . 同样,在非常短的视频中,如果你开始播放然后擦洗一点(甚至倒退时间),那将触发iframe重新加载(类似于@SuperMan注意到的),所以当视频完成时,重新加载将工作得很好 .

    这很可能是最近在Flash播放器中引入的错误,它不存在于HTML5播放器中;因此,如果您的用例允许,最简单的解决方案是通过将?html5 = 1附加到您的iframe源来强制HTML5播放器 .

    但是,如果将Flash播放器作为一种可能性是一个铁板的要求,那么你可以破解你的代码以强制它在完成后重新加载(而不是等待用户点击重新加载或重放按钮) .

    <html>
    <body>
    <script>
          var tag = document.createElement('script');
          tag.src = "https://www.youtube.com/iframe_api";
          var firstScriptTag = document.getElementsByTagName('script')[0];
          firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
          var player;
          function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
              events: {
                    onStateChange: 'onPlayerStateChange'
              }
            });
          }
    
          function onPlayerStateChange(event) {
            if (event.data===YT.PlayerState.ENDED) {
                    event.target.cueVideoById(event.target.getVideoData().video_id);
            }
          }
    
    </script>
    <iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen id="player"></iframe>
    </body>
    </html>
    

    请注意,这需要为iframe提供id属性,以便您可以使用iframe API绑定到该属性 .

    这也避免了必须覆盖视频上的任何DOM元素(只要您没有任何奇怪的wmode要求,这绝不是一个糟糕的解决方案;严格阅读YouTube TOS也可能导致结论你不能在玩家的任何部分覆盖任何东西,即使它是透明的......) .

    我的解决方案的一个缺点是它不会在视频结尾显示“相关视频”,所以如果这是一个交易破坏者,那么这是不行的(换句话说,我的解决方案更类似于添加您的iframe源的rel = 0属性) .

  • 2

    好吧,我不知道如何解决这个问题,但这是一个解决方法 . 一般的想法是在视频完成时在重新加载按钮上放置一个div,当单击div时视频会重新加载,因为普通方法不起作用 .

    这是我使用的代码,在代码中div为蓝色用于可视化目的

    <!DOCTYPE html>
    <html>
        <body>
            <div id="player_prop" style="position:relative;"><iframe id="player" type="text/html" width="640" height="390"
                src="http://www.youtube.com/embed/OuSdU8tbcHY?enablejsapi=1"
                frameborder="0"></iframe></div>
            <script>
                // 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', {
                    events: {
                      'onReady': onPlayerReady,
                      'onStateChange': onPlayerStateChange
                    }
                  });
                }
    
                // 4. The API will call this function when the video player is ready.
                function onPlayerReady(event) {
                  event.target.playVideo();
                }
    
                // 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.
    
    
    
                //from mantish http://stackoverflow.com/questions/3452546/javascript-regex-how-to-get-youtube-video-id-from-url
                function youtube_parser(url){
                    var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
                    var match = url.match(regExp);
                    if (match&&match[2].length==11){
                        return match[2];
                    }else{
                        //error
                    }
                }
                //end of Lasnvs code
    
                function restart_vid()
                {
                    el = document.getElementById("fake_replay_button");
                    vid_id = youtube_parser(document.getElementById('player').src);
                    player.loadVideoById(vid_id);
                    el.parentNode.removeChild(el);
                }
    
                function fakeplay()
                {
                    el = document.getElementById("player_prop");
                    var xPos = el.offsetLeft
                    var yPos = el.offsetHeight - 30;
                    var pseudoPlay = document.createElement('div');
                    pseudoPlay.setAttribute('style', 'background-color:blue; cursor:pointer; display:block; width:55px; height:25px; position:absolute; top:'+yPos+'px;');
                    pseudoPlay.setAttribute('onclick','restart_vid()');
                    pseudoPlay.setAttribute('id','fake_replay_button');
                    el.appendChild(pseudoPlay);
                }
                function onPlayerStateChange(event) 
                {
                    if(event.data==YT.PlayerState.ENDED)
                    {
                        fakeplay();    
                    }
                }
    
            </script>
        </body>
    </html>
    

    要使用此代码,您只需复制并粘贴脚本部分,而不是仅使用此代码

    <iframe width="420" height="315" src="//www.youtube.com/embed/OuSdU8tbcHY" frameborder="0" allowfullscreen></iframe>
    

    给它一个id = player,通过在src的末尾添加?enablejsapi = 1启用jsapi并将iframe包含在id = player_prop的div中,确保div具有属性position:relative,或者按钮的对齐方式会关闭,它应该是这样的

    <div id="player_prop" style="position:relative;">
    <iframe id="player" type="text/html" width="640" height="390" src="http://www.youtube.com/embed/OuSdU8tbcHY?enablejsapi=1" frameborder="0"></iframe>
    </div>
    

    当然这里是Fiddle的链接

  • 0

    也许是这样的:

    JsFiddle

    这不是一个完美的解决方案,因为你会与iframe之外的视频交互,但也许它会让你前进(改变src会一直重新加载视频) .

    $('iframe').attr("src", "//www.youtube.com/embed/OuSdU8tbcHY?autoplay=1"); //  restarts the video
    

相关问题