YouTube API pause video on mouseleave [duplicate] - javascript

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();
}
});

Related

YouTube Player API - Seek and then play

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>

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

Add/loop multiple videos, player names and events via YouTube API dynamically?

I'm trying to make an array of players to pass to new YT.Player. I keep getting 'player1' undefined, and the iFrame never gets added to the stated 'playerInfo.id'.
My code, without player2 or player3 included for simplicity:
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 playerInfoList = [
{playerName: 'player1', id: 'container1', videoId: 'WPvGqX-TXP0', eventId: 'playerOneReady'},
{playerName: 'player2', id: 'container2', videoId: 'Yj0G5UdBJZw', eventId: 'playerTwoReady'},
{playerName: 'player3', id: 'container3', videoId: '9gTw2EDkaDQ', eventId: 'playerThreeReady'}];
var players = new Array();
function onYouTubeIframeAPIReady() {
if (typeof playerInfoList === 'undefined') return;
for (var i = 0; i < playerInfoList.length; i++) {
var generatePlayers = createPlayer(playerInfoList[i]);
players[i] = generatePlayers;
}
}
function createPlayer(playerInfo) {
playerInfo.playerName = new YT.Player(playerInfo.id, {
height: '390',
width: '640',
videoId: playerInfo.videoId,
events: {
'onReady': playerInfo.eventId
}
});
}
// When the Players are ready.
var duration1;
function playerOneReady() {
duration1 = player1.getDuration();
}
function play(playerNum) {
playerNum.seekTo(0);
playerNum.playVideo();
}
$('#player1-trigger').click(function(){
play(player1);
}
I'm not sure why it keeps coming back as undefined. I have a simpler structure that works fine, but it involves adding each player manually, and I'm trying to make it more dynamic/efficient. Although this is more efficient than dynamic.
from what i'm seeing you made a mistake in the function createPlayer. while you're trying to make a player with the name player1 you're actually saving the new YT.player on the location of playerInfo.playername. it would be better to save in te players list directly like this:
function onYouTubeIframeAPIReady() {
if (typeof playerInfoList === 'undefined') return;
for (var i = 0; i < playerInfoList.length; i++) {
var generatePlayers = createPlayer(playerInfoList[i],i);
}
}
function createPlayer(playerInfo, locationInList) {
players[locationInList] = new YT.Player(playerInfo.id, {
height: '390',
width: '640',
videoId: playerInfo.videoId,
events: {
'onReady': playerInfo.eventId
}
});
}
and then when calling for the players use:
$('#player1-trigger').click(function(){
play(players[1]);
}
For the future I would suggest when making code more efficient/dynamic/readable to make multiple smaller changes and to test after every change if the code still works. That way it's easier to find what has broken.

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);

Pause YouTube video on mouseleave

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();
}
});

Categories

Resources