Skip to content
Advertisement

Embedded YouTube videos won’t replay

Strange one: embedded YouTube videos, once played (either by clicking ‘play’ or autoplaying on page load) will not play again.

I’m using the standard iFrame embed copied straight from YouTube. This happens with several different short videos and across all browser/OS combinations I’ve tested (Chrome/Safari/Firefox/IE on Windows/Mac).

Here’s the code:

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

and you can see it in action at this fiddle.

Advertisement

Answer

So it appears that the issue is NOT related to video length; it’s a problem with the flash player. If the flash player is loaded, and there is no user interaction with the controls at all, then when the player finishes it will not reload the iframe (despite the fact that it raises the ‘video ended’ event … when you try to reload it won’t issue the right call to reload the video and hence can never restart playback). You can test longer videos as well; if you start watching them and don’t use the scrub bar, they’ll exhibit the same behavior. Likewise, on your very short video, if you start playback and then scrub a bit (even backwards in time), that will trigger an iframe reload (akin to what @SuperMan noted), and so when the video finishes, then the reload will work just fine.

This is most likely a recently introduced bug in the Flash player, and it is not present in the HTML5 player; so if your use case allows it, the simplest solution would be to force the HTML5 player by appending ?html5=1 to the source of your iframe.

However, if having the flash player as a possibility is an iron clad requirement, then you can hack your code to force it to reload itself when finished (rather than waiting for a user to hit the reload or replay button).

<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>

Note that this requires giving your iframe an id attribute, so that you can bind to it with the iframe API.

This also avoids having to overlay any DOM elements over the video (which is not in any way a bad solution as long as you don’t have any odd wmode requirements; a very strict reading of the YouTube TOS might also lead to the conclusion that you can’t overlay anything over any portion of the player even if it’s transparent…).

One drawback of my solution is that it won’t display the ‘related videos’ at the end of the video, so if that’s a deal breaker then this is a no-go (in other words, my solution is more akin to adding the rel=0 attribute to your iframe source).

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement