YouTube iframe API and WordPress - javascript

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

Related

Youtube javascript load another video when video ends

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>

Youtube iFrame API how do I invoke IframeAPIReady function after getting list of videos

I am making simple Youtube Video Player myself, and I'd like to know how to invoke onYouTubeIframeAPIReady() after I get a list of videos.
What I like to do is display the first video in list as initial video.
In my html somewhere:
<script src="//www.youtube.com/iframe_api"></script>
This is initial iframe embed code from official sample code:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player-box', {
// height: '390',
// width: '640',
videoId: {FIRST_VIDEO_ID},
events: {
'onReady': onPlayerReady,
// 'onStateChange': onPlayerStateChange
}
});
}
Here is how I get a list of vids:
$.getJSON(
'https://www.googleapis.com/youtube/v3/videos',
{
part: 'snippet',
id: {VIDEO_IDs},
key: {MY_API_KEY},
},
function(data) {
var items = data.items;
console.log(data);
// cannot put onYouTubeIframeAPIReady here...
}
);
I guess I cannot put onYouTubeIframeAPIReady() as $.getJSON's callback, since it is called outside the script.
I kinda solve this problem myself.
I wrapped everything inside var onYouTubeIframeAPIReady = function() {...
Here's how I done:
var onYouTubeIframeAPIReady = function() {
var videos = '{VIDEO_ID1}, {VIDEO_ID2}, {VIDEO_ID3}';
$.getJSON(
'https://www.googleapis.com/youtube/v3/videos',
{
part: 'snippet',
id: videos,
key: {MY_API_KEY},
},
function(data) {
var items = data.items;
console.log(items);
$.each(items, function(i, video){
console.log(video);
});
var player;
player = new YT.Player('player-box', {
// height: '390',
// width: '640',
videoId: {INITIAL_VIDEO_ID},
events: {
'onReady': onPlayerReady,
// 'onStateChange': onPlayerStateChange
}
});
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
// console.log(event.data);
// if (event.data == YT.PlayerState.PLAYING && !done) {
// everytime change vids playing for 6secs then stop
if (event.data == YT.PlayerState.PLAYING) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
}//$.getJSON callback
}

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?

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