Youtube javascript load another video when video ends - javascript

I want to play another video, which I will get from my database, but I try it with some sample, which is not working at all, here is my sample code:
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady(id) {
if (id == null) {var t = '0Bmhjf0rKe8';}
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: t,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
event.target.playVideo();
}
// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
// Here I want to call function again, function executes, but video will not played
onYouTubePlayerAPIReady('yeDkcSZta2Y');
}
}
There you can see, when video ends I call onYouTubePlayerAPIReady() with new video ID, it executes as well, but video do not play. I think it will be because the onPlayerReady() do not executes, or something.
How to fix this, or what change to work it properly?

Here is an example that works. Call queueVideo() to load a string containing comma separated video ids of all the videos that you want to play or just one video. When there are no video left in the queue, this plays the default video '0Bmhjf0rKe8'. I never use onPlayerReady(). In fact, if I remember correctly, it was never called so I implemented using the technique shown below.
<script type="text/javascript">
// 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);
//
// Replaces the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
var videosQueuedCount;
function onYouTubePlayerAPIReady() {
videosQueuedCount = 1;
var vars = {
autoplay: 1,
enablejsapi: 1,
controls: 1
}
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
playerVars: vars,
videoId:'0Bmhjf0rKe8',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
}
function playVideo(VID) {
window.top.scrollTo(0,410);
videosQueuedCount = 1;
player.loadVideoById(VID);
}
function queueVideo(queuedCount,VID) {
window.top.scrollTo(0,410);
videosQueuedCount = queuedCount;
player.loadPlaylist(VID);
player.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
videosQueuedCount -= 1;
if (videosQueuedCount < 1) {
videosQueuedCount = 1;
playVideo('0Bmhjf0rKe8');
}
}
}
</script>
<div class="video-container"><div id="ytplayer"></div></div>

Related

getPlaylist returns an array with only one video when using the Youtube IFrame API

I'm trying to make a webpage that will load a given Youtube playlist and play a random video from it.
I'm struggling getting the playlist information from the API as when I run
player.getPlaylist()
the API returns an array of one element (the currently cued video) every time, regardless of the cued video or playlist.
My JavaScript is an almost 100% copy/paste from the API documentation and I can't work out why I can't get the full list of videos in the playlist.
<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', {
height: '390',
width: '640',
playerVars: {
listType: 'playlist',
list: 'PLbIZ6k-SE9SiarIg09JXUdK2kDX5_OB25',
autoplay: 0,
controls: 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log(event.target.getPlaylist());
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED && !done) {
done = true;
console.log('Video Finished');
stopVideo();
}
}
function stopVideo() {
player.stopVideo();
}
</script>
Can anybody lend a hand and point to my mistake or in the right direction?
It seems the playlist is not actually cued when loaded this way but only the first video. This is confirmed by getPlaylist() returning only one video and the onStateChange event not firing once the player has loaded.
We can however force the player to cue the playlist with cuePlaylist(). What is described below can be seen in this JSFiddle.
We modify the constructor to load nothing:
playerVars: {
autoplay: 0,
controls: 1
},
We modify onPlayerReady() to cue the playlist:
function onPlayerReady(event) {
event.target.cuePlaylist({
listType: 'playlist',
list: 'PLbIZ6k-SE9SiarIg09JXUdK2kDX5_OB25',
});
}
We modify onPlayerStateChange() to check for the CUED state and get the playlist when it fires:
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.CUED) {
console.log(event.target.getPlaylist());
}
if (event.data == YT.PlayerState.ENDED && !done) {
done = true;
console.log('Video Finished');
stopVideo();
}
}
After which the console outputs this:
Array [ "j_OyHUqIIOU", "PK8dsAeMmPk", "lfvceHUBWnU", "Xz5z1hBxejg",
"OubvTOHWTms", "5WKU7gG_ApU", "XjwO9InuFJk", "lNqChN3WHh8" ]

Youtube iFrame APi won't fire onPlayerStateChange function

so I'm using the Youtube iFrame API to give me an alert when the video stops playing with the following code:
<div id="player"></div>
<script type="text/javascript">
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', {
height: '390',
width: '640',
videoId: '0Bmhjf0rKe8',
playerVars: {
'autoplay': 1,
'controls': 1,
'html5': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
var playerReady = false;
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
playerReady = true;
}
// 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.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
alert('done');
}
}
I tried this same code on jsfiddle: (http://jsfiddle.net/QtBlueWaffle/8bpQ8/1/) and it works fine there. Doesn't work on my local machine though. Any ideas?

YouTube iframe API and WordPress

I'm trying the following code on WordPress post page:
<div id="player"></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', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
playerVars: { 'autoplay': 1, 'controls': 0 },
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.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function playVideo() {
player.playVideo();
}
function pauseVideo() {
player.pauseVideo();
}
function stopVideo() {
player.stopVideo();
}
function loadVideoById(val) {
player.loadVideoById(val, 0, "large");
}
</script>
However, nothing was displayed.
This kind of code injection is better done with a Shortcode. Instead of document.createElement, just use wp_enqueue_script to load the Iframe API and the rest of the script is printed by the shortcode. PHP heredoc makes easy to build large configurable HTML strings.
Shortcode usage inside the post/page would be: [ytplayer id="M7lc1UVf-VE"]
add_shortcode( 'ytplayer', 'print_yt_player' );
function print_yt_player( $atts ) {
wp_enqueue_script( 'yt-iframe', 'https://www.youtube.com/iframe_api' );
$yt_id = $atts['id'];
$html = <<<HTML
<div id="player"></div>
<script>
var player, done = false;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '$yt_id',
playerVars: { 'autoplay': 1, 'controls': 0 },
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function playVideo() {
player.playVideo();
}
function pauseVideo() {
player.pauseVideo();
}
function stopVideo() {
player.stopVideo();
}
function loadVideoById(val) {
player.loadVideoById(val, 0, "large");
}
</script>
HTML;
return $html;
}
Most likely, <p> tags are being inserted when the page/post is saved. Two options:
Disable wpautop
Include the script compressed (on a single line), like this:
<div id="player"></div>
<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",{height:"390",width:"640",videoId:"M7lc1UVf-VE",playerVars:{autoplay:1,controls:0},events:{onReady:onPlayerReady,onStateChange:onPlayerStateChange}})}function onPlayerReady(a){a.target.playVideo()}var done=!1;function onPlayerStateChange(a){a.data!=YT.PlayerState.PLAYING||done||(setTimeout(stopVideo,6E3),done=!0)}function playVideo(){player.playVideo()}function pauseVideo(){player.pauseVideo()}function stopVideo(){player.stopVideo()}function loadVideoById(a){player.loadVideoById(a,0,"large")};</script>`

Selecting a random element of array to set a Youtube videoId API

I'm trying to set up an array of videoId's to be able to choose from to be randomly loaded. I tried to add the videos array as a videoId, and it didn't work. I'm kind of a JS newb, so I'm not really sure what it is I should be passing back for this. I got as far as this:
<div id="player"></div>
<script>
function rotateYT() {
var videos = [
'ZMnjkcvjN-E',
'RFQfSMbLCWw',
];
var index=Math.floor(Math.random() * videos.length);
}
// 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', {
height: '300',
width: '300',
videoId: videos[index], //where I'm trying to get the random videos
events: {
'onReady': onPlayerReady,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
event.target.mute();
event.target.setPlaybackQuality('small');
}
</script>
The function needs to return the selected video ID:
function rotateYT() {
var videos = [
'ZMnjkcvjN-E',
'RFQfSMbLCWw',
];
var index=Math.floor(Math.random() * videos.length);
return videos[index];
}
Then you need to call it in onYouTubeIframeAPIReady:
function onYouTubeIframeAPIReady() {
var videoID = rotateYT();
player = new YT.Player('player', {
height: '300',
width: '300',
videoId: videoID,
events: {
'onReady': onPlayerReady,
}
});
}

how to show magnific-popup when youtube video finish

i need to show a popup when youtube video finish it works fine for the alert() but when i tried to make magnific popup instead if the alert it dosen't work here is my code
<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', {
height: '600',
width: '600',
videoId: 'id',
playerVars: { 'autoplay':"0", 'controls':"1" },
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
var playerReady = false;
function onPlayerReady(event) {
playerReady = true;
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED ) {
$.magnificPopup.open({
items: {
src: 'mylink to the pic'
},
type: 'image'
// You may add options here, they're exactly the same as for $.fn.magnificPopup call
// Note that some settings that rely on click event (like disableOn or midClick) will not work here
}, 0); }
}
</script>

Categories