【问题标题】:Embedded YouTube videos won't replay嵌入的 YouTube 视频不会重播
【发布时间】:2014-01-08 17:39:49
【问题描述】:

奇怪的一点:嵌入的 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 看到它的实际效果。

【问题讨论】:

    标签: javascript html iframe video youtube


    【解决方案1】:

    所以看来问题与视频长度无关;这是flash播放器的问题。如果加载了 Flash 播放器,并且根本没有用户与控件交互,那么当播放器完成时,它不会重新加载 iframe(尽管它引发了“视频结束”事件......当你尝试reload 它不会发出正确的调用来重新加载视频,因此永远无法重新开始播放)。您也可以测试更长的视频;如果您开始观察它们并且不使用擦洗条,它们将表现出相同的行为。同样,在您的非常短的视频中,如果您开始播放然后稍微擦洗一下(甚至在时间上向后),这将触发 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 也可能导致结论是你不能在播放器的任何部分覆盖任何东西,即使它是透明的......)。

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

    【讨论】:

    • 感谢您的详尽解释。对我来说,这是一个影响所有嵌入式 YouTube 视频的(相当严重的)错误,这让我觉得很疯狂,但我一直无法在网上的任何地方找到对它的参考。
    • 测试 AIR 实现也会遇到这个问题(即使是 HTML5 案例)。该解决方案也适用于这种情况。 (这不是我的评论,而是来自新用户的评论,建议作为编辑
    【解决方案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的链接

    【讨论】:

    • 我希望我能给你的答案一些奖励:它很巧妙。不过,就我的目的而言,@jlmcdonald 的答案完全符合我的要求,同时使用了非常少量的代码。不过感谢您的回复!
    【解决方案3】:

    可能是这样的:

    JsFiddle

    这不是一个完美的解决方案,因为您与 iframe 之外的视频交互,但也许它会让您继续前进(更改 src 将始终重新加载视频)。

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

    【讨论】:

      猜你喜欢
      • 2013-07-21
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2021-04-23
      • 2022-06-30
      • 1970-01-01
      • 2017-05-20
      相关资源
      最近更新 更多