I have a main YouTube video and some related videos at the bottom. YouTube video is loaded from a costum video name parameter in my url. If a video name exists YouTube iframe is loaded on page load but if a video name dosen't exists YT iframe isn't loaded until the user clicks a related video at the bottom. If the user clicks an related video the iframe is loaded and the same function onPlayerReady, and onPlayerStateChange should be used as the iframe was loaded from the begining. How can I insert the iframe in page and use the same function I use as it was loaded from the beginning. ?
player.js
var tag = document.createElement('script'),
firstScriptTag = document.getElementsByTagName('script')[0],
player;
tag.src = "https://www.youtube.com/player_api";
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
height: height,
width: width,
videoId: yt_id,
playerVars: {
wmode: "transparent",
controls: 0,
showinfo: 0,
rel: 0,
modestbranding: 1,
iv_load_policy: 3 //anottations
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
};
function onPlayerReady(event) {
//code here
//I want to use this code even when the player is loaded after the page is loaded (when the user clicks a related video at the bottom)
}
function onPlayerStateChange(event) {
//here too
}
insert_frame.js
var tag = document.createElement('script'),
firstScriptTag = document.getElementsByTagName('script')[0],
player;
tag.src = "https://www.youtube.com/player_api";
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
player = new YT.Player('ytplayer', {
height: height,
width: width,
videoId: yt_id,
playerVars: {
wmode: "transparent",
controls: 0,
showinfo: 0,
rel: 0,
modestbranding: 1,
iv_load_policy: 3 //anottations
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
How can I insert the iframe in page and use the same function I use as
it was loaded from the beginning. ?
If i understand correctly, you want to do that because some videos ID on the url may be false and the player iframe will not play the video.
Well you don't need insert a frame just because a video ID exist when use click on a related videoo the bottom, use onError parameter from YouTube Player API.
This event fires if an error occurs in the player. The API will pass
an event object to the event listener function. That object's data
property will specify an integer that identifies the type of error
that occurred. ...
If the videoID on the url doesn't exist an error will be send. Just hide the player for example and show it when the user click on a related video on the bottom.
With this solution you only need to load the player one and only one time without insert a frame into the code even if the id is wrong. A sample solution.
I made you a little example with a wrong videoID :
HTML
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="player"></div>
</body>
</html>
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);
// 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: 'l-gQLqv9f4',
events: {
'onError': onPlayerError,
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
$('#player').show();
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
}
}
function stopVideo() {
player.stopVideo();
}
function onPlayerError() {
console.log("error on the video id. Iframe is hiding");
$('#player').hide(); //or do what you want
}
Live demo: http://jsbin.com/mihikiqoma/1/edit?html,js,output
Related
I am trying to get a youtube iframe inside to put on amazon mechanical Turk.
However, if the youtube player <div> is placed inside it doesn't fire the event "onStateChange".
Here is a minimal code to reproduce. In this case, OnStateChange doesn't fire when video is paused:
<!DOCTYPE html>
<html>
<body>
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<crowd-form>
<div id="player"></div> <!-- This doesn't print YOLO on StateChange-->
</crowd-form>
<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: {
'onStateChange': onPlayerStateChange
}
});
}
// 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) {
console.log('Yolo')
}
</script>
</body>
</html>
In this case OnStateChange does fire when video is paused, but I need it inside to put on mechanical Turk.
<!DOCTYPE html>
<html>
<body>
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<div id="player"></div> <!-- This does print YOLO on StateChange-->
<crowd-form>
</crowd-form>
<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: {
'onStateChange': onPlayerStateChange
}
});
}
// 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) {
console.log('Yolo')
}
</script>
</body>
</html>
I was wondering why this is happening and how this could be resolved.
Thanks.
I am new to coding and I am trying to learn how to use the youtube IFRAME to control embded videos. The following code is mostly from youtube's api documentation. The only thing I added were the buttons and event listeners that are attached to them.
Can someone explain to me why "play" button that I have created can't start the video?
// 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: '250',
width: '300',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
document.getElementById('pause').onclick = function() {
player.pauseVideo();
};
document.getElementById('play').onclick = function() {
player.playVideo();
};
<html>
<body>
<div><button id= "pause">Pause</button></div>
<div><button id= "play">Play</button></div>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
</body>
It seems that the documentation of the iFrame API is either outdated or completely wrong.
The function which should initialize the player onYouTubeIframeAPIReady() will never fire thus a click on the play/pause buttons won't work because the variable player is undefined.
To workaround this, you have to wait until the script you're loading into the freshly created <script> element has finished loading and inside the callback function you need to initialize the YT component by a call to it's own ready() function. This isn't mentioned anywhere.
Well, get rid of the complete onYouTubeIframeAPIReady function and replace it with this:
tag.onload = function() {
YT.ready(function() {
player = new YT.Player('player', {
height: '250',
width: '300',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
}
});
});
};
After searching and finding many similar questions, I can't find the correct answer. So I'm working with the YouTube Iframe API, and I know that autoplay etc. won't work for mobiles. And I have created a element that displays on mobiles, so when the user click that button, it should play the video. But I only get this message: "Try restarting your device if playback does not start soon".
var playElement = document.createElement("div");
playElement.style.display = "none";
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
playElement.style.display = "block";
}
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player(child, {
width: '100%',
height: '100%',
videoId: youtubeID,
playerVars: {
'iv_load_policy': 3,
'enablejsapi': 1,
'disablekb': 1,
'autoplay': 1,
'loop': 0,
'controls': 0,
'showinfo': 0,
'rel': 0,
'mode': 'transparent'
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
playElement.onclick = function() {
player.playVideo();;
};
Anyone that does have an actual working solution?
Remember player refers to a div with the ID 'player'. You can start with the example code on youtube api doc. It will autoplay when the video has loaded. You can add your playerVar options as well.
A note for mobile video autoplay. You can have it autoplay but it has to be muted. So you can try adding player.mute() when you it loads and setup a click handler to unmute it again if that is what you prefer.
<!DOCTYPE html>
<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: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars
});
}
// 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>
If the youtube playVideo is triggered by postMessage, the onStateChange will not be fired. (http://jsfiddle.net/nedvedyy/smx92nq0/). Any one runs into it before?
<script src="jquery-1.10.2.min.js"></script>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<button class="button">BUTTON</button>
<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: '0Bmhjf0rKe8',
playerVars: {
'controls': 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) {
alert(event);
}
$(".button").on("click", function() {
document.getElementById('player').contentWindow.postMessage(JSON.stringify({
'event': 'command',
'func': 'playVideo',
'args': []
}), "*");
});
</script>
Strangely, if the playVideo is called like below, the onStageChange can be captured.
onPlayerReady=function(event) {
console.log("hey Im ready");
event.target.playVideo();
}
Did you complete your homework here? Go through complete manual, your solution is there from where you pasted.
https://developers.google.com/youtube/iframe_api_reference
I'm experimenting with the Youtube player but I can't get it to mute by default.
function onPlayerReady() {
player.playVideo();
// Mute?!
player.mute();
player.setVolume(0);
}
How do I mute it from the start?
Fiddle
Update:
JavaScript Player API is deprecated.
Use iframe Embeds instead.
Turns out player.mute() works fine. It only needed the parameter enablejsapi=1. Initial test in the fiddle didn't work because the player initiation had an error. The following works.
HTML:
<iframe id="ytplayer" type="text/html" src="https://www.youtube-nocookie.com/embed/zJ7hUvU-d2Q?rel=0&enablejsapi=1&autoplay=1&controls=0&showinfo=0&loop=1&iv_load_policy=3" frameborder="0" allowfullscreen></iframe>
JS:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
player.mute();
player.playVideo();
}
Fiddle
Credit to Gagandeep Singh and Anton King for pointing to enablejsapi=1
All above answers didn't work for me for some reason. It might be weird wordpress theme that I had to use or depreciated methods at Youtube API, I'm not sure. The only way of muting the player was to insert the code below into tag.
// Loads 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;
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
videoId: 'YOUR_VIDEO_ID',
playerVars: {
autoplay: 1,
controls: 1,
disablekb: 1,
hl: 'ru-ru',
loop: 1,
modestbranding: 1,
showinfo: 0,
autohide: 1,
color: 'white',
iv_load_policy: 3,
theme: 'light',
rel: 0
},
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event){
player.mute();
}
<div id="ytplayer"></div>
It's important to note that YouTube API mandates you run this within your markup directly within a <script> tag, or via a standard document.onLoad() native listener and not as a named function.
Otherwise it will not natively bind the onYouTubeIframeAPIReady() function to the DOM.
Try below code
var youtubeplayer = iframe.getElementById('ytplayer');
youtubeplayer .setVolume(0);
And below is your fiddle updated version,
NOTE: Must include enablejsapi=1 in video url
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
player.playVideo();
// Mute?!
//player.mute(); instead of this use below
event.target.mute();
//player.setVolume(0);
}
DEMO
Hope this helps...