I am trying to make a custom youtube playlist based on the example here.
However, the youtube player gets "jammed" and skips videos (in my case the middle video is skipped). The code is supposed to iterate through the arrays below and play one video at a time with each video having separate start/end times.
How would one go about making this work properly. (note that the code below needs to be uploaded to a website to work. Apparently from a local computer, it does not work) Here is the code I am using:
<html>
<body>
<div id="ytplayer"></div>
<script>// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var i = 0;
var videoId_arr = ['O57DyNMRGY8','-Yh2QGJBd2U','M7lc1UVf-VE'];
var startSeconds_arr = [41,26,17];
var endSeconds_arr = [50,40,30];
// Replace the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
var playerConfig = {
height: '360',
width: '640',
videoId: videoId_arr[i],
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 1, // Show pause/play buttons in player
showinfo: 1, // Hide the video title
modestbranding: 0, // Hide the Youtube Logo
fs: 1, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 3, // Hide the Video Annotations
start: startSeconds_arr[i],
end: endSeconds_arr[i],
autohide: 0, // Hide video controls when playing
},
events: {
'onStateChange': onStateChange
}
};
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', playerConfig);
}
function onStateChange(state) {
if (state.data === YT.PlayerState.ENDED) {
i++;
if(typeof videoId_arr[i] === 'undefined')
return;
player.loadVideoById({
videoId: videoId_arr[i],
startSeconds: startSeconds_arr[i],
endSeconds: endSeconds_arr[i]
});
}
}
</script>
</body>
</html>
I have tested your code and I figured out that the state is changing for some unknown reasons very quickly. The state has sometimes the value 0
which equals YT.PlayerState.ENDED
although the video was not played.
You can see it by console logging state.data
within the onStateChange
function.
A small change fixed the problem:
function onStateChange(state) {
var _video_url = state.target.getVideoUrl();
var _video_id = _url.split('v=')[1];
var _current_index = videoId_arr.indexOf(_video_id) +1;
console.log('State: ', _video_id, _current_index, state );
// ensure that the video has been played
if (state.data === YT.PlayerState.ENDED && player.getCurrentTime() >= endSeconds_arr[i]) {
i++;
if(typeof videoId_arr[i] === 'undefined'){
i = 0; // rest the counter
return;
}
}
}
For the code to run properly you should disable browser plugins like Video Resumer
or similar - since they can change the state of a youtube video or resumes the videos from where you stopped them last