(YouTube API): YT.Player doesnt work playVideo - youtube

I need to develop autoplay when user visit the page, actually apply code snippet as provided in google doc:
https://developers.google.com/youtube/iframe_api_reference
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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: '360',
width: '640',
videoId: 'M7lc1UVf-VE',
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 stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
and it doesn't work properly, video doesn't play/
I've tried to put event.target.playVideo(); in setTimeout with delay 1000, 2000, 3000, but this experiment is failed as well - video didn't play
Could you help, please?

I assume your problem is the autoplay policy most browsers implement.
It prevents autoplay in most cases.
One exception is that autoplay works when the video sound is muted. Maybe that is something that works for your use case.
For further reference visit:
https://developer.chrome.com/blog/autoplay/
https://support.mozilla.org/en-US/kb/block-autoplay
https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/

Related

Inconsistent behavior with loop=1 on iframe

I am having a very frustrating experience trying to get videos to loop consistently using a basic iframe. I am not interacting with the API via code. I simply have an iframe with autoplay=1,mute=1,loop=1. I've tried using stand-alone videos and I've tried playlists (with list=[ID],listType=playlist) and I keep running into the same problem. Sometimes the player will loop the video and sometimes it will not. Every time I think I have it figured out and I'm ready to deploy the app, I test it again and the video fails to loop.
Windows 10
Chrome 71.0.3578.98
Angular 6.0.3
You can choose any of these options:
Check my answer where I described how you can set your URL for create a playlist (using a single videoId) and simulate a loop.
Use the YouTube iframe Player API for set your video and (once the video ended), call the playVideo() function for play the current video = hence, creating a loop.
This is the code: - unfortunately, you can't see it working here, but, you can see the working jsfiddle1
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// Variables of the divs (where the YouTube iframe will load):
var player;
function onYouTubeIframeAPIReady() {
// Div player:
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'xPCZEoGJi_4',
playerVars: {
'autoplay': 1,
'loop': 1,
'mute': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 5. The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
// When the video ends, it will play again.
// See: https://developers.google.com/youtube/iframe_api_reference?hl=en#Events
if (event.data == YT.PlayerState.ENDED) {
player.playVideo();
}
}
// Div "player" - The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<div id="player"></div>
1 If the video (once has loaded) hasn't play, you have to play manually the video - this is due some kind of restrictions that jsfiddle has.

Youtube video playable using the default embed, but not playable with the youtube api

I have some YT videos to play in the VB Webbrowser, but playing it gives me the 'This video contains content from VEVO. It is restricted from playback on certain sites or applications' error. But when I try playing it using the default embed code provided in the Youtube link itself it plays perfectly. Example:
<iframe width="560" height="315" src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe>
On the custom HTML page made, this is the code I used
function main(vidid)
{
// 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;
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('player', {
height: '200',
width: '300',
playerVars: {
autoplay: 1,
enablejsapi : 1,
origin: "https://www.youtube.com",
vq: 'medium'},
videoId: vidid,
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 stopVideo() {
player.stopVideo();
}
}
Is there something that I'm missing, or is the video just blocked for API users? My apologies if my question is too bad.
Found the source of the problem. Turns out that I was hosting the webpage on PC, which Youtube doesn't allow. After I uploaded my html page to a web server, it works perfectly.

JavaScript pause button for YouTube video that has been cloned?

Ive made a pause button for a YouTube video. This worked fine however now I need to clone the video. This is due to how the carousel that im using works and also so the video can be displayed in a Lightbox.
Below is a simplified version of my code. Now the pause button only works on the first video. How can I make a button that will pause all cloned videos?
http://jsfiddle.net/36vr2kjv/2/
<p class="trigger">Trigger</p>
<p class="trigger2">Trigger2</p>
<div class="player-wrap">
<div id="player"></div>
</div>
<div id="player2"></div>
var player;
$(function() {
// 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.
onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
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 stopVideo() {
player.stopVideo();
}
$('.trigger').click(function(){
//this works
player.pauseVideo()
});
return player;
});
$(function() {
setTimeout(function(){
$('.player-wrap').clone().appendTo('#player2');
}, 2000);
});
$(function() {
$('.trigger2').click(function(){
// this does not work
player.pauseVideo()
});
});
Actually there is concept of deep cloning and shallow cloning. Shallow cloning does not copy events hence you have to use deep cloning. Where ever you are using clone() instead use clone(true).
For example in above code snippet you can use:
$(function() {
setTimeout(function(){
$('.player-wrap').clone(true).appendTo('#player2');
}, 2000);
});
Issue Description:
What's happening in your code is you are cloning and creating two IDs within a single DOM load, which means your javascript will have conflicting IDs to deal with. The other issue being that the youtube API creation function binds to an ID and not a class.
So after you've cloned your iframe, your original function (held in player) is now pointed at two places... hence the confusion.
Solution:
To combat this, we can use a placeholder. Based on the Youtube Player API Reference, Youtube allows for loading videos to a player object.
player.loadVideoById(videoId:String,
startSeconds:Number,
suggestedQuality:String):Void
[See Youtube API#Queueing_Functions]
We can use classes and object references to reach your goal:
player;
placeholder;
playerCount = 1;
$(function() {
// ... Previous code ... //
/**
* Assuming you have more than one video to play,
* the function will change to allow for incrementing the ids
* of each player made. [UNIQUE IDS]
*/
onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
player = new YT.Player('player-'+playerCount, {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
placeholder = new YT.Player('placeholder', {
height: '390',
width: '640',
});
/**
* Now add a generic class so we can find all of these elements,
* and bind the object to a data instance for access later.
*/
$('#player-' + playerCount).addClass('youtube-player').data('YoutubeAPI', player);
playerCount++;
}
The placeholder comes into play now, when you carousel fires it's beforeChange event, you can access the player element from within the current/next/previous slide using the carousel's event handler and running a $(event.target).find('youtube-player') (or something like that, APIs are different, so YMMV) and access the player instance using $(event.target).find('youtube-player').data('YoutubeAPI') (or whatever you named your data variable).
Then you just find the video id from the original object (using the access scheme from above and taking the id from the youtubeAPI object) and load the video into the placeholder using the API call from above.

onStateChange not being fired in safari or firefox [duplicate]

As of today, I'm having some difficulty getting the YouTube iFrame API onStateChange to fire in Firefox.
This appears to be a new problem - projects using the same code with the same API that were working fully last week are now not firing their onStateChange events. This issue only seems to affect Firefox - Chrome and Internet Explorer are working fully.
Is this a known bug, and is there a workaround available if it is?
(There's a similar question here, but it appears to be for a temporary bug on YouTube's side that has now been fixed. The solution posted there also doesn't seem to fix this issue.)
As an example, here's a fiddle using the basic example from Google. The player should stop after six seconds, but doesn't:
http://jsfiddle.net/wf4NW/
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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',
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 stopVideo() {
player.stopVideo();
}
</script>
This appears to be an issue with the YouTube flash player. When flash is used (which seems to be the default) the API does not work.
However, when HTML5 mode is requested, the stateChange event does fire.
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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: {
html5: 1
},
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 stopVideo() {
player.stopVideo();
}
</script>
Here is the OP's jsfiddle, but modified to use the HTML5 player. With the HTML5 player, the video does pause after 6 seconds like it should.

How to handle YouTube video events (started, finished, etc) in uiwebview iOS

Currently I'm using the new iframe API to embed a YouTube video inside the uiwebview on the iPad and I've been able to make it auto play without user interactions.
In the iframe API it is described how to use the onstatechange event but in my application it doesn't seem to work and unfortunately I can't see any debug in uiwebview.
I just want to able able to detect when the video ends, have you got any advice on it?
Has anyone got it to work?
Have you tried (from the documentation) to assign an integer to the event of a movie ending?:
onStateChange This event fires whenever the player's state changes.
The data property of the event object that the API passes to your
event listener function will specify an integer that corresponds to
the new player state. Possible data values are:
-1 (unstarted)
0 (ended)
1 (playing)
2 (paused)
3 (buffering)
5 (video cued).
When the player first loads a video, it will broadcast an unstarted
(-1) event. When a video is cued and ready to play, the player will
broadcast a video cued (5) event. In your code, you can specify the
integer values or you can use one of the following namespaced
variables:
YT.PlayerState.ENDED
YT.PlayerState.PLAYING
YT.PlayerState.PAUSED
YT.PlayerState.BUFFERING
YT.PlayerState.CUED
So, something like:
if(event.data==YT.PlayerState.ENDED){
//do stuff here
}
To detect when the video ends then the video has the state of 0 or YT.PlayerState.ENDED
Here's a link to jsfiddle a link!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page 1</title>
</head>
<body>
<h1>Video page</h1>
<br>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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: 'ussCHoQttyQ',
playerVars: {
'autoplay': 0,
'controls': 0,
'showinfo': 0,
'rel': 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),
// -1 unstarted
// 0 ended
// 1 playing
// 2 paused
// 3 buffering
// 5 video cued
var done = false;
function onPlayerStateChange(event) {
console.log(event);
if (event.data == YT.PlayerState.ENDED) {
alert(1);
}
}
</script>
</body>
</html>
May this http://code.google.com/apis/youtube/js_api_reference.html#SubscribingEvents can help you
It may be connected with autoplay-policy in your browser (it's disabled by default in mobile browsers).
If your browser is chrome you can start it with additional commandline flag --autoplay-policy=no-user-gesture-required - it worked for me.
you need to make use of JavaScript for that.
Refer this link : https://developers.google.com/youtube/js_api_reference

Resources