YouTube Player API - Seek and then play - javascript

I'm having an issue when trying to use .seekTo() with the YouTube Player API. The first time I set the .seekTo() the video will correctly seek to the value (e.g. 4 seconds) and then play [without me issuing .playVideo()]. The video is stopped when I call .seekTo() the 2nd time and the video plays from the start. I want to be able to start the video again from the seek location.

<!DOCTYPE html>
<html>
<head>
<scriptm src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="player"></div>
<div>
<button id="btnSeek" data-seek="30.7">Seek 30</button>
<button id="btnSeek" data-seek="60">Seek 60</button>
<button id="btnSeek" data-seek="90">Seek 90</button>
<button id="btnSeek" data-seek="180">Seek 180</button>
</div>
<script>
$.getScript('//www.youtube.com/iframe_api');
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '-HjpL-Ns6_A',
playerVars: { 'start': 159, 'autoplay': 1, 'controls': 1, 'showinfo': 0, 'rel': 0 },
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
}
});
}
var done = false;
function onPlayerStateChange(evt)
{
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function onPlayerReady(evt) {
// doesn't work here
// player.seekTo(30);
// lets make ure we have a function
//alert("typeof(player.SeekTo) = " + typeof(player.seekTo));
}
function stopVideo() {
player.stopVideo();
}
$(function() {
$(document).on('click', '#btnSeek', function() {
if(player.getCurrentTime() == player.getDuration())
{
player.playVideo();
}
player.seekTo($(this).data('seek'), true);
});
});
</script>
</body>

Related

Youtube API: Dynamic naming and looping

I apologize in advance, I am not very good with scripting, so I hope this isn't too basic of a request.
I am in a situation where I need to have multiple looping clickable youtube video. I do not want to use the embeddable playlist looping option because it has a few seconds of black where it refreshes the video in the playlist, which in this case would be itself.
I found a few articles on here that show you how to do create multiple videos dynamically using a data attribute, and how to loop specific times within a youtube video, but when I try to combine these, I get an error, which I am assuming is a scope issue but have no idea how to fix. Below is my code, along with the links to each original fiddles.
The error I am receiving is:
"Uncaught ReferenceError: players is not defined"
<div style="position: relative;display:block;width: fit-content;margin:0 auto;">
<a href="#"><div style="width: 100%;height:100%;position:absolute;"></div>
</a>
<div class="video-container">
<div data-id="YE7VzlLtp-4"></div>
</div>
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
function onYouTubeIframeAPIReady() {
var players = document.querySelectorAll('.video-container div')
for (var i = 0; i < players.length; i++) {
new YT.Player(players[i], {
videoId: players[i].dataset.id,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
'autoplay': 1,
'loop': 1,
'controls': 0,
'showinfo': 0,
'modestbranding': 1}
});
}
}
function onPlayerReady(event) {
loopStart();
players.playVideo();
}
function loopStart() {
players.seekTo(7); // Start at 7 seconds
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
setTimeout(loopStart, 5000); // After 5 seconds, restart the loop
}
}
</script>
Multiple Videos using Data Attribute Example:
https://jsfiddle.net/nightcoregirl/jyha6xj5/
Looping Example:
http://jsfiddle.net/pbosakov/Lo6gwtff/
Thanks in advance for any isight!
Your specific issue is scope of variable players. players is not visible in onPlayerReady. To retrieve the player from event object, use event.target :
Javascript
function onYouTubePlayerAPIReady() {
players = document.querySelectorAll('.video-container div')
for (var i = 0; i < players.length; i++) {
var player = new YT.Player(players[i], {
videoId: players[i].dataset.id,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
'autoplay': 1,
'loop': 1,
'controls': 0,
'showinfo': 0,
'modestbranding': 1
}
});
}
}
function onPlayerReady(event) {
loopStart(event.target);
event.target.playVideo();
}
function loopStart(player) {
player.seekTo(7); // Start at 7 seconds
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
setTimeout(function() {
loopStart(event.target);
}, 5000); // After 5 seconds, restart the loop
}
}
HTML
<script src="https://www.youtube.com/iframe_api"></script>
<div class="video-container">
<div data-id="YE7VzlLtp-4"></div>
</div>
<div class="video-container">
<div data-id="3IXKIVZ9T-U"></div>
</div>
Check this fiddle

YouTube API loadVideoById some times not working?

I am working on this code. Some times the videos play well but some times it's showing a white screen and I am getting this type of error message:
player.loadVideoById is not a function.
My HTML code:
<i class="fa fa-play-circle-o" id="play_btn" onclick="playyoutubevideo('<?php echo $topic_names1['youtube_video_id']?>');"></i>
This is my javascript code:
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
videoId: $('#video_id').val(),
playerVars: { 'fs':'0' },
events: {
'onStateChange': onPlayerStateChange
}
});
}
// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
$('#popup_close').click();
}
}
function playyoutubevideo(video_id)
{
$("body").css("position", "fixed");
if(player)
{
var fn = function(){ player.loadVideoById(video_id); }
setTimeout(fn, 500);
}
$(".pos_popup").removeClass("none1");
$(".pos_popup1").removeClass("none1");
}
If anyone knows the mistake, please help me to solve this issue.

Need to refresh the page to see a YouTube live event that has just begun

I’m using YT.player to show live events on the website : http://www.solarimpulse.com/rtw
Since youtube changes the display of live event the countdown on the YT.player is not dynamic anymore. I need to reload the page to see the countdown going down. And worse than that when I start the live event nothing append in the player, I need to reload the page to see the video.
Last year the countdown and the player was working fine, I didn’t change the code since then :
var player = {
playVideo: function (container, videoId) {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
window.onYouTubePlayerAPIReady = function () {
player.loadPlayer(container, videoId);
};
$.getScript('//www.youtube.com/player_api');
} else {
player.loadPlayer(container, videoId);
}
},
loadPlayer: function (container, videoId) {
youtubePlayerSatcom = new YT.Player(container, {
playerVars: {
controls: 1,
rel: 0,
autoplay: 1,
playsinline: 1,
modestbranding: 1, // disable watch on youtube
fs: 1, // fullscreen
cc_load_policy: 0,
iv_load_policy: 3, // annotations
showinfo: 0 // don't show loading
},
height: '100%',
width: '100%',
videoId: videoId,
events: {
'onStateChange': function (event) {
if (event.data === 0) {
youtubePlayerSatcom.loadVideoById(videoId, 0);
}
}
}
});
}
};
player.playVideo('satcom-player', videoId);
How can I fix that ?
Thank you for your help.
I made a small fix to reload the video if it hasn't started yet. It's not very clean as the player get black and load again but it works. The countdown get dynamic like that.
$.doTimeout('youtube_notplaying', 20*1000, function () {
if (typeof youtubePlayerSatcom != 'undefined') {
if (youtubePlayerSatcom.getPlayerState() == -1) {
if (debug_interface) console.log('load '+videoId);
youtubePlayerSatcom.loadVideoById(videoId);
} else if (youtubePlayerSatcom.getPlayerState() != -1) {
return false; // stop timeout
}
}
return true; // repeat
}, true);

YouTube API pause video on mouseleave [duplicate]

I have created a function which inserts an YouTube iframe when user hovers on a div and then when mouse leaves the div the video is paused. Everything works fine but the video is paused only the first time and when you click play again and then leave div it dosen't pause. Any ideas? Thanks.
Fiddle: http://jsfiddle.net/508oknm7/27/
var tag = document.createElement('script'),
firstScriptTag = document.getElementsByTagName('script')[0];
tag.src = "https://www.youtube.com/player_api";
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
$(".video_wrap").on({
mouseenter: function () {
player = new YT.Player($(this).children().attr('id'), {
height: '240',
width: '320',
videoId: '-NschES-8e0',
playerVars: {
wmode: "transparent",
controls: 0,
showinfo: 0,
rel: 0,
modestbranding: 1,
iv_load_policy: 3 //anottations
},
events: {
'onReady': onPlayerReady
}
});
function onPlayerReady(event) {
player.setVolume(10);
event.target.playVideo();
}
},
mouseleave: function () {
player.pauseVideo();
}
});

Lose context of this when youtube constructor method is called

I have created a youtube player using the youtube iframe api, I am listening for the ENDED event but I've realised that I lose the reference to this which becomes the window but I'm really unsure how to resolve this. I've tried binding this to the contsructor etc but with no joy whatesoever so could really do with you guys help.
JS
startPlayer: function (videoId) {
var instance = this;
console.log('startPlayer', instance);
if( instance.flags.isPlaying ) {
instance.selectors.playerCtn.empty();
instance.flags.isPlaying = false;
}
instance.selectors.playerCtn.append('<div id="player"></div>');
instance.player = new YT.Player('player', {
height: '390',
width: '640',
videoId: videoId,
events: {
'onReady': this.onPlayerReady,
'onStateChange': this.onPlayerStateChange
}
});
instance.flags.isPlaying = true;
},
onPlayerStateChange: function (event) {
console.log('onPlayerStateChange');
var instance = this;
console.log(instance); //undefined??
if (event.data == YT.PlayerState.PLAYING) {
console.log('PLAYING...');
}
if (event.data == YT.PlayerState.PAUSED) {
console.log('PAUSED...');
}
if (event.data == YT.PlayerState.ENDED) {
console.log('what is this', instance);
// if instance.counter === instance.playlist
if (instance.counter === instance.playlist) {
console.log('you\'ve come to the end of your playlist');
// Display message or go back to first?
return;
}
// Increase the counter
instance.counter++
// Set the new current element
instance.current = instance.selectors.listItems[instance.counter];
console.log(instance.counter);
console.log(instance.current);
// Get the new current element data-id
var videoId = instance.current.attr('data-id');
// Start the player
startPlayer(videoId);
}
if (event.data == YT.PlayerState.BUFFERING) {
console.log('BUFFERING...');
}
}
Test page http://go.shr.lc/1lh2dmu
events: {
'onReady': this.onPlayerReady.bind(this),
'onStateChange': this.onPlayerStateChange.bind(this)
}
Besides, why var instance = this;? this is quite shorter to type and you aren't using instance in any closure.

Categories

Resources