嵌入的YouTube视频无法重播

时间:2014-01-08 17:39:49

标签: javascript html iframe video youtube

奇怪的一点:嵌入的YouTube视频,一旦播放(通过点击'播放'或在页面加载时自动播放)将无法播放。

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

以下是代码:

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

你可以在this fiddle看到它。

3 个答案:

答案 0 :(得分: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也可能导致结论是,即使它是透明的,你也不能在玩家的任何部分覆盖任何东西......)。

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

答案 1 :(得分: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

的链接

答案 2 :(得分:0)

也许是这样的:

JsFiddle

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

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