Problems with Youtube Iframe Api to start playing video on Chrome
Asked Answered
H

3

14

I have following starting setup:

var player;
function onYouTubeIframeAPIReady() {
   player = new YT.Player('player', {
      events: {
         'onReady': onPlayerReady,
         'onStateChange': onPlayerStateChange
      }
   });
}

Then in onPlayerReady handler I added event listener to button which is outside iframe:

function onPlayerReady(event) {
   button.addEventListener('click', () => event.target.playVideo());
}

In onPlayerStateChange I'm just logging what is happening:

function onPlayerStateChange(event) {
    console.log(event.data);
}

After hitting that button in Chrome (v.72.0.3626.119) there are 3 entries in console: -1 (UNSTARTED), 3 (BUFFERING), -1 (UNSTARTED). When I try to hit button again nothing happens. This works perfectly in Firefox, IE giving in console: -1 (UNSTARTED), 3 (BUFFERING),1 (PLAYING) and simply video starts playing.

Do you have any idea how to solve it?

Hordein answered 1/3, 2019 at 12:16 Comment(1)
I'm behind on my JS, but should there be curly brackets around event.target.playVideo() ? I'm having the same problem right now - it stopped working on code that has worked for years - so it might not be you. Edit: I think it's a Google problem. Even the demo page at developers.google.com/youtube/youtube_player_demo doesn't work. Edit 2: I also noticed that player.playVideo() is returning the Player object. The docs say it has no return (void).Piapiacenza
B
16

You have to add in the onPlayerReady function this line:

event.target.playVideo();

As is shown in the documentation:

Example:

// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
  event.target.playVideo();
}

I can't say for sure why, but, in Google Chrome, for autoplay the video, you need to set the value 1 to the mute parameter, otherwise, autoplay the video wont work.

Example:

function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    height: '360',
    width: '640',
    videoId: '<YOUR_VIDEO_ID>',
    playerVars: {
      'autoplay': 1,
      'loop': 1,
      'mute': 1 // N.B. here the mute settings.
    },
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

You can check this jsfiddle for guide yourself how you can set custom controls for play/pause your embed video.

Bimah answered 1/3, 2019 at 18:13 Comment(8)
There is a playVideo() call in the original question. It's called when someone clicks a "play" button. Your fiddle exhibits the same behaviour that OP has: clicking the "play" link does nothing.Piapiacenza
@JohnB it is because the video is not muted. In the linked jsfiddle, if you mute the video and press the "play" button, it will play/pause the video.Bimah
That is absolutely it, thanks. I missed that in your answer. Sorry about the downvote - SO won't let me change it to an upvote.Piapiacenza
@JohnB no problem at all and thank you for your kindness :)Bimah
Mute parameter did the trick! Looks like it has to be set 1 now even on Firefox.Shingly
OMG thank you!! ?autoplay=1&mute=1 after the videoId in the angular youtube player component totally fixed the autoplay issue I was having, with &mute=1 being absolutely necessary. Oh, and by the way, that does not cause the audio to be muted -- which I don't want anyway. So, great, awesome, but my question is: This can't be intentional, can it? I mean, the requirement for mute=1 has to be some kind of bug, doesn't it? So eventually I would guess they're going to make a change to "fix" things... and then all our stuff will stop working again?Thief
FFS! Spent hours trying to get it to autoplay and finally came across this. mute: 1 ... Went back to Doco and no mention of this....Wharton
@Thief sorry for the late reply. I don't have the link, but, here on Stack Overflow I did read about Google Chrome restrictions for videos to autoplay. You could search and see the original post - which has the link to the original source.Bimah
H
1

I have sent a key after load html, and it works for me.

KeyEvent k = new KeyEvent();
k.WindowsKeyCode = 0x0D;
k.FocusOnEditableField = true;
k.IsSystemKey = false;
k.Type = KeyEventType.Char;
webytb.GetBrowser().GetHost().SendKeyEvent(k);
Hamlen answered 27/10, 2019 at 17:19 Comment(1)
Uncaught ReferenceError: KeyEvent is not definedLeaky
L
1

From this answer, Google Chrome need the allow="autoplay" attribute on iframe to let JS controls the player or make auto play function work.

This is required if you manually use <iframe> instead of <div> tag.

Example:
Attention! Please note that it maybe not work if the result iframe of this site don't have allow="autoplay" attribute on iframe. Copy and paste HTML & JavaScript into your .html file is the best way to test that it is really working.

var player;


/**
 * Load YouTube API JavaScript
 */
function loadYTAPIScript() {
  console.log('loading YouTube script.');
  let tag = document.createElement('script');
  tag.src = 'https://www.youtube.com/iframe_api';
  firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}


/**
 * On YouTube iframe API ready
 * 
 * This function will be called automatically by YouTube.
 */
function onYouTubeIframeAPIReady() {
  console.log('function `onYouTubeIframeAPIReady` was called.');
  player = new YT.Player('player', {
    events: {
      'onError': onError,
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}


function onError(event) {
  console.error('YouTube API error!', event);
} // _onError


/**
 * On player ready.
 *
 * This is callback function from `onReady` event in `onYouTubeIframeAPIReady()`.
 */
function onPlayerReady(e) {
  console.log('function `onPlayerReady` was called from `onReady` event callback.', e);
  listClickButtons();
}


/**
 * On player state change.
 *
 * This is callback function from `onStateChange` event in `onYouTubeIframeAPIReady()`.
 */
function onPlayerStateChange(e) {
  console.log('function `onPlayerStateChange` was called from `onStateChange` event callback.', e);
  let state = e.target.getPlayerState();
  let stateText = '';
  if (state === -1) {
    stateText = 'unstarted';
  } else if (state === YT.PlayerState.ENDED) {
    stateText = 'ended';
  } else if (state === YT.PlayerState.PLAYING) {
    stateText = 'playing';
  } else if (state === YT.PlayerState.PAUSED) {
    stateText = 'paused';
  } else if (state === YT.PlayerState.BUFFERING) {
    stateText = 'buffering';
  } else if (state === YT.PlayerState.CUED) {
    stateText = 'cued';
  }
  console.log('State text: ', stateText);
}


/**
 * Listen on click buttons to controls the video.
 * 
 * This method was called from `onPlayerReady()`.
 */
function listClickButtons() {
  console.log('Listen click buttons.');
  let isPlayed = false;
  let playpauseBtn = document.getElementById('yt-playpause');
  let stopBtn = document.getElementById('yt-stop');
  playpauseBtn.addEventListener('click', (e) => {
    e.preventDefault();
    console.log('User click on play/pause button.');
    if (isPlayed === false) {
      player.playVideo();
      isPlayed = true;
    } else {
      player.pauseVideo();
      isPlayed = false;
    }
  });
  stopBtn.addEventListener('click', (e) => {
    e.preventDefault();
    console.log('User click on stop button.');
    player.stopVideo();
  });
}




document.addEventListener('DOMContentLoaded', (e) => {
  console.log('DOM ready.');
  loadYTAPIScript();
});
<iframe id="player" 
  width="560" height="315" 
  src="https://www.youtube.com/embed/1L904pgYbOE?enablejsapi=1" 
  title="YouTube video player" 
  allow="autoplay" 
  allowfullscreen=""
></iframe>
<!--
The `iframe` URL (`src` attribute) must contain enablejsapi=1 query string to let JS API work.
The `iframe` must contain `allow="autoplay"` attribute to allow JS controls the player.
-->


<div class="yt-controllers">
  <button id="yt-playpause" type="button">
    Play/Pause
  </button>
  <button id="yt-stop" type="button">
    Stop
  </button>
</div>

See full code on jsfiddle.

Reference:

  1. Iframe
  2. Iframe allow features list
  3. YouTube Iframe API
Leaky answered 5/1, 2022 at 6:37 Comment(1)
Thank you, this solution allow="autoplay" fixed the issue from me on Chrome/EdgeSow

© 2022 - 2024 — McMap. All rights reserved.