Auto playing random youtube videos is not working every time - javascript

This is working just fine, however it seems to only auto play every now and then. When I try to load the website through incognito it doesn't auto play at all:
I'm wondering if it is even the code or it's just because YouTube is limiting something
(function(window, document, undefined) {
'use strict';
function removeElement(array, element) {
return array.filter(function(el) {
return el !== element
});
}
function changeVideo() {
if (player.getCurrentTime() >= delay) {
var currentVideo = player.getVideoData().video_id,
randomVideo = removeElement(videoPlaylist, currentVideo)[Math.floor(Math.random() * (videoPlaylist.length - 1))];
player.loadVideoById(randomVideo);
}
}
function onPlayerStateChange(event) {
clearInterval(repeat);
if (event.data === 1) {
repeat = setInterval(changeVideo, 500);
}
}
window.onYouTubeIframeAPIReady = function() {
var randomVideo = videoPlaylist[Math.floor(Math.random() * videoPlaylist.length)];
player = new YT.Player('player', {
height: '315',
width: '560',
videoId: randomVideo,
playerVars: {
'autoplay': 1,
'controls': 0,
'showinfo': 0,
'iv_load_policy': 3
},
events: {
'onStateChange': onPlayerStateChange
}
});
}
var tag = document.createElement('script'),
player,
videoPlaylist = ['wfF0zHeU3Zs', 'WNcsUNKlAKw', '9E6b3swbnWg'],
delay = 10, //s
repeat;
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
})(window, document);

Browsers are blocking auto play for when the sound is on.
https://www.theverge.com/2018/5/3/17251104/google-chrome-66-autoplay-sound-videos-mute
https://www.theverge.com/2019/3/19/18272377/firefox-66-release-date-news-features-autoplaying-videos
A way around this might be to mute the video until the user moves their mouse over the video. (I think this is a common solution but correct me if I'm wrong)
You also have to think about the fact that users might not want to have the video autoplaying depending on what kind of website this is implemented into.
The reason it sometimes seems to be working for you is because chrome is learning that you want audio on the website you're creating but for example for me it is never playing.

Related

TypeError: player.currentTime is not a function error in videojs

I have a working player in videojs and I'm trying to get the current position of the progress bar, In the documentation provided by videojs they use myPlayer.currentTime() to get and set the time in seconds but it is not working for me.
My code:
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", {
host: "https://www.youtube.com",
/* no need to specify player
size here since it is handled
by the player-size div */
videoId: video_id,
playerVars: {
enablejsapi: 1,
playsinline: 1,
start: 0,
disablekb: 0
},
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
console.log("player state: " + player.getPlayerState());
if (player.getPlayerState() == 2){
console.log("STOPED AT:" + player.currentTime()); // This is where i want to log the current time of the playing video
}
}
function updateVideoId(video_id) {
player.loadVideoById(video_id, -1);
}
function stopVideo() {
player.stopVideo();
}
function onPlayerReady(event) {
document.getElementById("play").addEventListener("click", function() {
player.playVideo();
});
}
What am I doing wrong?
The code above is YouTube's API, not Video.js.
If you want to play a YouTube video in Video.js and use Video.js's API, you need to use the YouTube tech for Video.js

Youtube iFrame API in ES6 / modules

I'm trying to load a YT video via the api. This official tutorial snippet works basically out of the box when I output it directly onto a page. It's a different story when I try and incorporate it into my JS workflow with modules / webpack.
Questions:
How do I make these methods (play / mute / setLoop / stop / etc) available globally?
How do I create the script tag first and then run the onYouTubeIframeAPIReady function?
Thanks all. Hope this isn't a completely useless question!
<script>
// 1. Load up the script tag
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 2. Creates an <iframe> (and YouTube player) after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('a-spot-video-background', {
width: '1280',
height: '720',
videoId: 'T8v-gQeQZJY',
playerVars: {
autoplay: 1,
controls: 0,
modestbranding: 1,
rel: 0,
showinfo: 0,
loop: 1,
disablekb: 1,
color: 'white'
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 3. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.mute();
event.target.playVideo();
event.target.setLoop();
}
// 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, 10000);
player.playVideo();
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
First question is answered in comment. This answers to second one:
function loadScript(scriptUrl, globalName) {
if (globalName && window[globalName])
return Promise.resolve();
return new Promise((resolve, reject) => {
let scr = document.createElement('script');
scr.type = "text/javascript";
scr.src = scriptUrl;
document.getElementsByTagName('head')[0].appendChild(scr);
scr.onload = (() => {
!globalName || window[globalName] ?
resolve() : reject(Error('window.' + globalName + ' undefined'));
});
scr.onerror = () => reject(Error('Error loading ' + globalName||scriptUrl));
});
}
var url = "https://code.jquery.com/jquery-3.3.1.min.js";
loadScript(url, "$")
.then(() => console.log('jQuery loaded. Now I can call any jQuery method.'));
or you can use just script.onload event listener without promise. I like promise version because it gives you some additional options and has clear flow (without nesting or referencing across whole file).

How to play a random video from a list?

I have a list of videos in an array and I want to be able to make the player play another video from the list after the current one ends. The problem I'm having is that it repeats the same video once its ends instead of selecting a new video to play. I've been looking for similar questions and havent been able to find anything to make it work. Any advice would be appreciated!
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.
function rotateYT() {
var videos = [
'be0T_owA1PU',
'Kp7eSUU9oy8',
'Th0V-fxo9CE',
];
var index=Math.floor(Math.random() * videos.length);
return videos[index];
}
var player;
function onYouTubeIframeAPIReady() {
var videoID = rotateYT();
player = new YT.Player('player', {
height: '300',
width: '300',
videoId: videoID,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.setPlaybackRate(1);
event.target.playVideo();
}
// 5. This should play another random video
function onPlayerStateChange(event) {
if(event.data === 0) {
event.target.setShuffle(true);
event.target.playVideo();
}
}
I probably put the code in wrong so here is the jsfiddle ive been working on
https://jsfiddle.net/bbasham/L20k7x1o/2/
Your issue is that you are not telling the YT player to use a playlist of videos. Instead, you are only setting one video ID at a time, therefore, the shuffle method would not work. You need to update your method so that you swap the video ID before restarting:
// 5. This should play another random video
function onPlayerStateChange(event) {
if(event.data === 0) {
//event.target.setShuffle(true); //useless unless the player has a playlist
event.target.loadVideoById( rotateYT() );
event.target.playVideo();
}
}
That will cause the player to grab a new video and set it as the source before restarting the player. Alternatively you could provide a playlist and then use shuffle.
Documentation

Youtube play button issue

I have embedded a YouTube video on my Shopify store, but as we know it doesn't auto play on mobiles and tabs so I have used YouTube API to play it on external click as I don't like the big red button
But cant make it disappear, issue is I already have text positioned over the video so cant use an overlay image like most of solutions.
My code:
<div class="video-wrapper">
<div id="bucklesburyVideo"></div>
</div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('bucklesburyVideo', {
playerVars: {
'playlist': 'f8BxdOvj1Ho',
'loop': 1,
'autoplay': 1,
'controls': 0,
'showinfo': 0,
'wmode': 'opaque'
},
videoId: 'f8BxdOvj1Ho',
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.mute();
var playButton = document.getElementById("play-button");
playButton.addEventListener("click", function() {
player.playVideo();
});
var pauseButton = document.getElementById("pause-button");
pauseButton.addEventListener("click", function() {
player.pauseVideo();
});
}
</script>
If you check the IFrame API and its player parameter, there is no instruction or method there that can show you on how to hide the big red play button of the YouTube. So what can I suggest you is to use a custom CSS to hide or adjust the location of the Play button.
Check this thread if it can help you.
For more information, check the other solution in this SO question.

How can I play two Youtube videos without linking to a playlist?

I'm very new to Javascript. I'm embedding a youtube iframe here:
http://www.heartlandpokertour.com/indexbeta.php
Using this documentation:
http://code.google.com/apis/youtube/iframe_api_reference.html
I would like a second video to play, looped, after the first one is finished. I'm unable to set specific video parameters if I try and link/set the video id to a Youtube playlist.
I'm assuming I need to setup an event listener and function to trigger when YT.PlayerState.ENDED (or 0) is broadcast, but NO IDEA how to do this.
Update: Here is the current code I'm using for the player:
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '258',
width: '406',
videoId: 'MsTQNZmq5Pk',
playerVars: { 'autoplay': 0, 'rel': 0, 'showinfo': 0, 'egm': 0, 'showsearch': 0, },
events: {
'onStateChange': onPlayerStateChange,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
player.stopVideo();
player.videoId = 'c5dTlLk5_x8';
player.playVideo();
}
}
</script>
In the first code listing on the api website, this event might help you:
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
You could change it to something like this (not tested I'm afraid):
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
player.stopVideo();
player.videoId = 'some id';
player.playVideo();
}
}
This would be the most logical in my opinion, but then again I'm not sure whether different videos can be played within one player instance. I've never come across your scenario I'm afraid.
Edit: You could try creating a new instance of the player. So basically you'd just create a new player, which will play the second video:
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
player.stopVideo();
player = new YT.Player('player', {
height: '258',
width: '406',
videoId: 'some id',
playerVars: { 'autoplay': 0, 'rel': 0, 'showinfo': 0, 'egm': 0, 'showsearch': 0, },
events: {
//'onStateChange': onPlayerStateChange, // not add this line because it would again create a new player after the second has stopped I guess!
}
});
player.playVideo();
}
}
I have got this working on my site, first you can stop the current video playing, then load in a new video with the loadVideoById() function from the Youtube API
function swapVideo() {
player.stopVideo();
player.loadVideoById(youtube_id);
}

Categories

Resources