How to stop video after X button is clicked - javascript

Currently, the video does not player.stopVideo(); in the code.
To reproduce: Click 1 svg play button, then click the X and you will see that.
How is that fixed in the code so that the same video stops after clicking the X?
Updated Codes:
Click Run, not update to test JSitor code:
Also, autoplay works inside JSitor: https://jsitor.com/qYKcpdB0tj
Backup copy: https://jsfiddle.net/0q63tr2m/
const videoPlayer = (function makeVideoPlayer() {
const players = [];
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/player_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onPlayerReady(event) {
const player = event.target;
player.setVolume(100);
}
function addPlayer(video, settings) {
const defaults = {
height: 360,
host: "https://www.youtube-nocookie.com",
videoId: video.dataset.id,
width: 640
};
defaults.events = {
"onReady": onPlayerReady
};
You can see the video still playing here:

What you have to do is as follow:
Add an id to your iframe element like so: id="iframe"
Remove player.stopVideo(); from createStopHandler function
On your createStopHandler function, add following code(if you want your video to stop and not pause, then change the func snippet "func":"pauseVideo" into "func":"stopVideo"):
var frame = document.getElementById("iframe");
frame.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
This should do it. Here you can see it working: https://jsfiddle.net/vjbex6t1/8/

function addClickToHome(goHome) {
goHome.forEach(function addEventHandler(goHome) {
goHome.addEventListener("click", homeClickHandler);
//STOP PLAYER AFTER HOME IS CLICKED
});
}
Initialize some variable with player globally and stop it when button is pressed to home

You can try this out,
var videoURL = $('#playerID').prop('src');
videoURL = videoURL.replace("&autoplay=1", "");
$('#playerID').prop('src','');
$('#playerID').prop('src',videoURL);

Related

I can't get Youtube API to work in Squarespace

I'm trying to control a youtube iframe in my squarespace website. I want it to autoplay when the page loads and then if I scroll and it's not in the viewport anymore, I want it to pause.
Here is what I did:
This is my iframe:
<iframe id="ytplayer" width="560" height="315" src="https://www.youtube.com/embed/uuRC8Pmud3o?enablejsapi=1&rel=0&showinfo=0&controls=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
And this is my script:
<script>
// 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);
// This function YouTube player
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// The API calls this function when the player's state changes.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
done = true;
}
// Loop the video
if (event.data == YT.PlayerState.ENDED) {
player.playVideo();
}
}
// On scroll Pause/Play the video player
$(window).scroll(function() {
var top_of_element = $("#ytplayer").offset().top;
var bottom_of_element = $("#ytplayer").offset().top + $("#ytplayer").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).height();
var top_of_screen = $(window).scrollTop();
if((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
// The element is visible, trigger play click event
player.playVideo()
}
else {
// The element is not visible, trigger pause click event
player.pauseVideo()
}
});
</script>
I tried adding the script to squarespace using many ways but it's not working. Where has the script to be injected?
What's wrong with my code?
According to Youtube IFRAME API, just add autoplay=1 at the end of your URL like:
<iframe id="ytplayer" type="text/html" width="640" height="360"
src="https://www.youtube.com/embed/M7lc1UVf-VE?autoplay=1&origin=http://example.com"
frameborder="0"></iframe>
I think this is also confirmed in the squarespace forum.
I have just figured this out.
Squarespace creates it's own players and also it dynamically creates iframes so it's a bit complicated. Also getting player using DOM element doesn't seems to work and all iframe elements have the same id = "player" so that adds up to the problem.
The code below is what I have come to literally 5min ago.
Just copy/paste to the header code injection in the Squarespace config.
What it does is it acquire all the original YouTube API players as soon as possible and pause playback to avoid horrible lag when my old GPU tries to video-decode all those video instances. Then I have a code which plays the video when it appears on the screen and pauses videos that are not visible anymore. Now it plays smoothly and I can add even more videos. In my case you can see one full-screen video at a time as you scroll down. I have 7x 720p videos stacked up. It looks cool, but I found out that my GPU is lagging badly when more than 5 videos were used, initially I was thinking that it's a network speed problem but my task manager showed 100% on GPU video-encoding. So far worked on Firefox and Chrome.
I have just managed to make this work so there is a lot of testing and tweaking to be done.
USE ON YOUR OWN RISK ! :)
<script type="text/javascript">
// Prepare YouTube iframe API ..
// this is probably redundant, but works fine
var tag = document.createElement ('script');
tag.id = 'iframe-api';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName ('script')[0];
firstScriptTag.parentNode.insertBefore (tag, firstScriptTag);
// When Iframe is ready ..
var iframes = [];
var players = [];
function onYouTubeIframeAPIReady () {
// console.log ("onYouTubeIframeAPIReady");
var player_containers = document.querySelectorAll (".sqs-video-background.content-fill");
for (var i = 0; i < player_containers.length; i ++) {
player_containers [i].addEventListener ("DOMNodeInserted", function (e) {
var node = e.target;
if (node.tagName.toUpperCase () === "IFRAME") {
// console.log ("PLAYER : " + node.id + " TAG : " + node.tagName);
iframes.push (node);
// unfortunately it seems that we cannot catch the player creation event so
// the actual players are probably created after this code
// by calling this function we can catch previous players early on
// except the last one
initPlayers ();
}
}, false);
}
}
function initPlayers () {
// they have all the same id (!!!)
// however it seems it picks the last created one so not the same one over and over
// I didn't touched this, it works so far
var player = YT.get ("player");
if (player !== undefined) {
players.push (player);
pausePlayer (player);
}
}
function playPlayer (player) {
// this happends when player is not fully initialized yet
if (typeof player.pauseVideo === "function") {
player.playVideo ();
} else {
// if the player is not ready yet catch the event
player.addEventListener ('onReady', function (event) {
player.playVideo ();
});
}
}
function pausePlayer (player) {
// this happends when player is not fully initialized yet
if (typeof player.pauseVideo === "function") {
player.pauseVideo ();
} else {
// if the player is not ready yet catch the event
player.addEventListener ('onReady', function (event) {
player.pauseVideo ();
});
}
}
function isInViewport (element, edge) {
var h = window.innerHeight; // viewport height
var r = element.getBoundingClientRect (); // elements bounding rect in viewport coordinates
// console.log ("top : " + r.top);
// console.log ("bottom : " + r.bottom);
// console.log ("height : " + h);
// add extra margin to the viewport to ensure that
// big enough portion of the object is already visible
var e = h * Math.min (edge, 0.4); // relative viewport factor, max 40%
var top = r.top - e;
var bottom = r.bottom - e;
h = h - e*2;
return (!((top > h) || (bottom < 0)));
}
window.onload = function(e){
// console.log ("loaded");
initPlayers (); // to catch the last one !
// console.log ("players : " + players.length);
function onScroll () {
for (var i = 0; i < players.length; i ++) {
var player = players [i];
var iframe = player.getIframe ();
var container = iframe.parentNode;
if (isInViewport (container, 0.0)) {
playPlayer (player); } else {
pausePlayer (player);
}
}
}
// in the case object is already in the viewport
onScroll ();
window.addEventListener ("resize", onScroll);
window.addEventListener ("scroll", onScroll);
}
</script>

Exit YouTube fullscreen video

I'm loading YouTube videos using JS API. I can play, pause and go fullscreen with external controls but I can't exit fullscreen with double click on the video.
Using the code below try this:
load the video with button
go fullscreen using internal iframe button
double click on video (you will exit fullscreen)
Now my problem:
load the video with button
go fullscreen using external button
double click on video (nothing happens unless you press ESC key)
How can I do this? I need to exit fullscreen by double click (besides using ESC key)
fiddle: https://jsfiddle.net/cs8tnvkh/
HTML
<button id="btn_load">load video</button>
<button id="btn_play">play</button>
<button id="btn_pause">pause</button>
<button id="btn_fullscreen">fullscreen</button>
<div id="video_player">
<div id="video"></div>
</div>
JS
const YOUTUBE_LINK = "https://www.youtube.com/embed/#VIDEO?wmode=transparent&autoplay=1&rel=0&controls=1&enablejsapi=1&html5=1";
const YOUTUBE_VIDEO_ID = "mPyLF7NxZyY";
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('video', {
height: '480',
width: '720',
events: {
// call this function when player is ready to use
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
$("#btn_play").click(function() {
player.playVideo();
});
$("#btn_pause").click(function() {
player.pauseVideo();
});
$("#btn_fullscreen").click(function() {
var iframe = $('#video')[0];
var requestFullScreen = iframe.requestFullScreen || iframe.mozRequestFullScreen || iframe.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(video)();
}
});
}
var tag = document.createElement('script');
tag.src = "//www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
$(document).ready(function() {
$("#btn_load").click(function() {
var video_src = YOUTUBE_LINK.replace("#VIDEO", YOUTUBE_VIDEO_ID);
$("#video_player iframe").attr("src", video_src);
});
});

onReady not firing for embedded youtube iframe

I am having issues getting the youtube api working. The API itself loads and the onYouTubeIframeAPIReady() function gets called, but the onReady doesn't work.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady() {
log('API')
log(document.getElementById('yt-pilezspnvu'));
var player = new YT.Player('yt-pilezspnvu', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
log(event);
}
function onPlayerStateChange(event) {
log(event);
}
The code above isn't wrapped in any functions or anything. The errors in the picture below are just my adblock stuff. I've tried adding origin=http://example.com as pointed out in this thread https://stackoverflow.com/a/20505337/736967 but still not working.
I think that you need some extra bits that are missing.
Try adding in this to your code.
ytplayer = new YT.Player('ytplayer', {
height: '385',
width: '640',
videoId: '[your-videoID]',
playerVars: {'wmode': 'opaque', 'autohide': 1 , 'enablejsapi': 1 , 'origin': 'http://www.yousite.com', 'rel': 0},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
}
playerVars has many parts and you can use or not. But you definatly need to have something load into the player. VideoID or PlayList. Else nothing will happen.
I had a similar issue with an overlay image being clicked and the onReady event never seemed to fire even though all the other events did; obvious through console logs in each.
The issue was apparently a race event. Clicking the overlay image should remove the image and start the YouTube video playing. I also have several videos on the same page. The click event to play the video should be placed inside the onReady event instead of the click event firing the play event. I have trimmed this down as much as I could as our DOM has several elements inside the video container, including the overlay image, captions, etc.
Here is my solution:
var player = new Array;
window.onYouTubeIframeAPIReady = function() {
// Loop through the existing video iframes designated with the inital string 'vidframe_' in the id
jQuery('iframe[id^="vidframe_"]').each(function (i, val) {
var $this = $(this); // iframe container
var $vidWrapper = $this.closest('.video-wrapper');
// Make sure it is a YouTube video. This data attribute is set when the iframe is created by my code
if( $vidWrapper.data("video-source") == "youtube" )
{
// Initialize each YouTube video present
player[i] = new YT.Player($this.attr('id'), {
events: {
onReady: function(event) {
// Set the click event listener here
$vidWrapper.on("click", function() {
// Target the overlay image
// 'this' is now the .video-wrapper image element
var imgOver = $(this).find('figure');
// Remove image overlay
if( imgOver )
imgOver.fadeOut();
// Target the right player
player[i].playVideo();
});
}
}
});
}
});
};
I hope this helps anyone else who may be searching for an errorless onReady event not seemingly working. This css-tricks article is what really gave me the best clue.

Dynamic youtube iframe in javascript and jQuery

I'm going crazy, trying to fix this and it wont work the way I want it to work,ahhh I feel like a child :/
var videoID;
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
videoID = sessionStorage.getItem("key");
var onYouTubeIframeAPIReady = function(){
player = new YT.Player('player', {
height: '315',
width: '560',
videoId: videoID,
events: {
'onReady': onPlayerReady
}
});
}
//The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
console.log(videoID);
}
function searchQuery() {
//Declare selectors
var queryContainer = $('div.search-box ul');
var searchBox = $('div#search-bar input[type=search]');
//Declare variables from input elements :)
var search = $(searchBox).val();
var checker = search.length;
//Check if the input is empty string
if(search!=''){
//Declare the YoutubeAPI link with youtube APIkey
var theAPI = "https://www.googleapis.com/youtube/v3/search?part=snippet&q="+search+"&maxResults=15&key=AIzaSyA9ej5NSrEqzex76U_xE3PPJlb2rELrW9M";
//Get JSON string from YoutubeAPI link
$.getJSON(theAPI, function(data){
//Append 5 titles to the div
for(var i=0; i<=5; ++i){
//Using the kind property from YoutubeAPI determine is it a profile or video
if(data.items[i].id.kind === 'youtube#video'){
$(queryContainer).append('<li><p>' +data.items[i].snippet.title+'</p></li>');
}else if(data.items[i].id.kind === 'youtube#channel'){
$(queryContainer).append('<li><p>' +data.items[i].snippet.title+'</p></li>')
}
}
$('div.search-box a').on('click', function(){
$('div#player-box').empty();
$('div#player-box').append('<div id="player"></div>');
sessionStorage.setItem('key', $(this).data("id"));
onYouTubeIframeAPIReady();
});
});
//Check if the input value is changing, if it does cleares the previous output
if(checker){
$(queryContainer).empty();
}
}else{
$(queryContainer).empty();
return false;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="player"></div>
here is a question:
function onYouTubeIframeAPIReady(){
player = new YT.Player('player', {
height: '315',
width: '560',
videoId: videoID,
events: {
'onReady': onPlayerReady
}
});
}
How to delete this player object and create a new one on a click event?
I really want this working, please someone help :)
Is there a specific reason you want to destroy the player object and recreate it? If your goal is to just load a new video, you could always do this:
$('div.search-box a').on('click', function(){
player.loadVideo($(this).data("id"));
sessionStorage.setItem('key', $(this).data("id"));
});
(you might need to declare the player variable in such a way that your click handler could access its scope, whether that be as a global, etc.)
However, if you really need to destroy the player itself and recreate it, I wonder if the problem lies in the fact that, on your click, you aren't changing the value of the 'videoID' variable (which the onYouTubePlayerAPIReady function needs to instantiate the new player); rather, you only change the value of the sessionStorage key.

Pause youtube and/or vimeo video in Iframe when onblur with javascript

I would like to pause the video when the user click on another tab in their browser. I have tried to do this with Youtube and Vimeo.
This is the basic idea behind the javascript:
For Youtube:
//YouTube
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 youtubePlayer;
var onYouTubeIframeAPIReady = function() {
youtubePlayer = new YT.Player('youtube', {
height: '390',
width: '640',
videoId: 'sXtekwuT8R0',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
};
var onPlayerReady = function(event) {
event.target.playVideo();
};
var onPlayerStateChange = function(event) {
if (event.data == YT.PlayerState.PLAYING) {
parent.focus();
window.onblur = function() {
status.text("You went away!");
youtubePlayer.stopVideo();
};
}
};
For Vimeo (using their Froogaloop library):
$(function() {
//Vimeo
var iframe = $('#vimeo');
var vimeoPlayer = $f(iframe[0]);
var status = $('#status');
vimeoPlayer.addEvent('ready', function() {
vimeoPlayer.addEvent('play', function(){
status.text("Playing!");
parent.focus();
window.onblur = function() {
status.text("You went away!");
vimeoPlayer.api("pause");
};
});
});
});
Here are some codepen examples of these attempts:
Youtube:
http://codepen.io/earlonrails/pen/jugAm
Vimeo:
http://codepen.io/earlonrails/pen/KBAmd
Both examples will work if after I click the play button, I click on the parent document of the iframe then click a different window or tab. The Youtube example will also work when it is first loaded, but not if you click the play then pause then play. I believe both of these problems are due to the fact that you are clicking the iframe, therefore the event either is trigger at the same time or cannot be triggered because the event can't be captured there. I thought using the postMessages sent through the iframes along with callbacks would make this work, but alas I have not been able to figure this out.
Need to set the current window before adding the event callback and use this window variable in the callback function. IE
var myWindow = window;
vimeoPlayer.addEvent('play', function(){
status.text("Playing!");
myWindow.focus();
myWindow.onblur = function() {
status.text("You went away!");
vimeoPlayer.api("pause");
};
});
These can be confirmed and tested at the previously linked codepen examples:
Youtube: http://codepen.io/earlonrails/pen/jugAm
Vimeo: http://codepen.io/earlonrails/pen/KBAmd
I guess the window when clicked in the iframe would be setting onblur on the iframe window, which would then never get called, but I still can't explain why when you click play on the iframe, then click the body of the page, then click a different tab then it works. Perhaps the callback is being fired more than once from the iframe or the postMessage is being fired or still in some buffer.

Categories

Resources