embedding multiple Youtube livestream and manage display with buttons - javascript

I am trying to setup a website page where 2 permanent live streams (from 2 different channels) are embedded. 2 buttons are present on the page, allowing the user to display 1 video or the other.
However I can't manage to make this work. I am now trying with regular youtube embed, but only one is displaying, the buttons don't have any effect. Also the autoplay doesn't seem to work...
I already tried the Livestream part, this works well, but not with 2 livestreams.
Any advice where to look into. Thank you !
function showcam(num) {
for (let i = 1; i < 2; i++) {
document.getElementById("camera" + i).style.display = 'none';
}
document.getElementById("camera" + num).style.display = '';
console.log(num)
}
iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
max-width: 100%;
z-index: -5;
}
<div id="cameramenu">
<ul>
<button id=button1 onclick="showcam(1)">
<li> camera 1 </li>
</button>
<br>
<button id=button1 onclick="showcam(2)">
<li> camera 2 </li>
</button>
</div>
<div id=cameravideo>
<div id=camera1>
<iframe id=camera1 title="Live-stream of the machine" src="https://www.youtube.com/embed/hgZqTIOzOp4?autoplay=1&modestbranding=1&color=red&showinfo=1" playsinline>
</iframe>
</div>
<div id=camera2>
<iframe id=camera2 title="Live-stream of the crowd" src="https://www.youtube.com/embed/CA5-UT_6Cxs?autoplay=1&modestbranding=1&color=red&showinfo=1" playsinline>
</iframe>
</div>
</div>

You have to use the iframe api in order to be able to control the video. From there, you'll be able to add more than 1 video and do make your own play buttons or toggle between them. If you need further help, I can try and give you an example that toggles between 2 videos.
https://developers.google.com/youtube/iframe_api_reference
https://jsfiddle.net/842u0f6v/
<!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
}
});
}
// 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>

Related

Play multiple audio tracks sequentially, not simultaneously

I'm trying to use the <audio> tag, and I want to have as many tracks playing as I add. But now they play at the same time, can I somehow make them play sequentially?
<audio id="audio1" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus1.mp3"></audio>
<audio id="audio2" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus.mp3"></audio>
<div id="pp" style="cursor: pointer;" onclick="pVid();"><img src="img/heart.png"></div>
<script type="text/javascript">
function pVid() {
var audio1 = document.getElementById("audio1");
var audio2 = document.getElementById("audio2");
audio1.paused ? audio1.play() : audio1.pause();
audio2.paused ? audio2.play() : audio2.pause();
}
</script>
I found one solution, it works but not the way I want
var sounds = new Array(new Audio("music/mus1.mp3"), new Audio("music/mus.mp3"));
var i = -1;
pVid();
function pVid() {
i++;
if (i == sounds.length) return;
sounds[i].addEventListener('ended', pVid);
sounds[i].play();
}
Here everything just plays right away, but I want to be able to play the tracks myself through the button and pause at any time. This is done in the first version, but there all the tracks play at the same time
Use audio events as much as possible. We can use freesound.org for testing.
let sounds = new Array(new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"), new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"));
let current = random(0);
let paused = true;
// set event handlers on all audio objects
for (let s of sounds) {
s.addEventListener('ended', ended);
s.addEventListener('play', play);
s.addEventListener('pause', pause);
}
updateVolume()
// handle button click
function playPause() {
if (paused) {
sounds[current].play();
btn.innerText = 'pause';
paused = false;
} else {
sounds[current].pause();
btn.innerText = 'play';
paused = true;
}
}
function ended(e) {
document.getElementById(current + '').classList.remove('playing');
document.getElementById(current + '').classList.remove('paused');
/*i++;
if (i >= sounds.length) //loop
i = 0;
*/
current = random(current); // shuffle
paused = true;
playPause();
}
function play() {
document.getElementById(current + '').classList.add('playing');
document.getElementById(current + '').classList.remove('paused');
}
function pause() {
document.getElementById(current + '').classList.add('paused');
document.getElementById(current + '').classList.remove('playing');
}
function random(i) {
let next = i;
while (next == i)
next = Math.floor(Math.random() * sounds.length);
return next;
}
function updateVolume() {
for (let s of sounds) {
s.volume = volume.value;
}
}
#list {
margin-top: 1rem;
border: 1px solid gray;
width: 100px;
}
#controls {
position: fixed;
right: 2rem;
top: 1rem;
width: 50px;
}
#volume {
width: 150px;
height: 20px;
transform-origin: 75px 75px;
transform: rotate(-90deg) translateY(50%);
}
.playing {
background-color: lightblue;
}
.paused {
background-color: wheat;
}
<Button id=btn onClick='playPause()'>play</Button>
<div id=list>
<div id='0'>Guitar</div>
<div id='1'>Drum</div>
<div id='2'>Violin</div>
<div id='3'>Guitar</div>
<div id='4'>Drum</div>
<div id='5'>Violin</div>
</div>
<div id=controls>
<label for="volume">Volume</label><br>
<input id=volume type="range" id="volume" name="volume" min="0" max="1" step='.1' value='.5' onInput='updateVolume()'>
</div>
I don't know why no one mentioned the onended event
<audio id="aud1" onended="playaud2()" src="whatever.mp3"> <!--first audio-->
<audio id="aud2" src="whatever.mp3"> <!--second audio-->
<script>
//the onended event calls a function when the audio finishes playing
function playaud2() {
document.getElementById("aud2").play()}
</script>
As simple :)
Audio files
For testing, I used a few free sound-effects audio files from https://www.freesoundeffects.com.
To make it work in all browsers it is recommended by w3c to use the <audio>-tag with <source> tags.
Solution
I added some arbitrary sound files and buttons. The buttons will reset all the audios that are currently playing then play the sounds in the data-track attributes.
data-track syntax:
track-a // will play track a
track-a;track-b // will play track a followed by track b
track-a+track-b // will play track a and b simultaniously
track-a+track-b;track-c // as above but add track c to the end
You could do something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
audio {
display: block;
}
</style>
<script defer type="application/javascript">
let activeTimeout;
function init(player) {
player.innerHTML = `play ${player.dataset.label}`;
player.addEventListener('click', clickHandler);
}
function reset(audio) {
clearTimeout(activeTimeout);
audio.pause();
audio.currentTime = 0;
}
function dequeue(tracks) {
console.log("Queue:", tracks);
if (tracks.length >= 1) {
const track = tracks.pop();
const multiTrack = track.split('+');
let maxDuration = 0;
multiTrack.forEach((it) => {
const audio = document.querySelector(`[data-audio="${it}"]`);
maxDuration = Math.max(maxDuration, audio.duration);
audio.play();
});
activeTimeout = setTimeout(() => {
dequeue(tracks);
}, maxDuration * 1000);
}
}
function clickHandler(e) {
const allAudios = document.querySelectorAll('[data-audio]');
const trackAttr = this.dataset.track;
const tracks = trackAttr.split(';');
if (tracks) {
allAudios.forEach(reset);
dequeue(tracks.reverse()); // reverse to make the pop-operations faster
} else {
console.log('No track defined!');
}
}
window.addEventListener('load', function() {
const players = document.querySelectorAll('[data-player]');
players.forEach((it) => init(it));
});
</script>
</head>
<body>
<audio data-audio="applause" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_426807.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="bark" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89478.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="chirp" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89489.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<button data-player data-label="bark!" data-track="bark" />
<button data-player data-label="chirp!" data-track="chirp" />
<button data-player data-label="applause!" data-track="applause" />
<button data-player data-label="applause then bark!" data-track="applause;bark" />
<button data-player data-label="bark then chirp then bark again!" data-track="bark;chirp;bark" />
<button data-player data-label="applause then chirp!" data-track="applause;chirp" />
<button data-player data-label="applause with chirp then bark!" data-track="applause+chirp;bark" />
</body>
</html>
Yes, you can check if you have an element with a simple truthy/falsy check:
if (!slider) return;

How to disable "related videos" from an embedded youtube playlist

I need to embed a Youtube playlist on an iframe. I don't want the user to be able to exit this playlist, so I need to disable the "related video" and "more video" features (the one that shows more videos when the video is stopped and the one that shows them when the video is finished).
I've tested some workarounds but they only used to work for single videos (not playlist) and most of them stopped working after they changed the way ?rel=0 behaves. Is there any way to do this?
This is my code:
.rep {
position: absolute;
top: 0px;
left: 0px;
width: 1280px;
height: 640px;
z-index: 6;
}
<iframe class="rep" src="https://www.youtube.com/embed/videoseries?list=PLUl4u3cNGP63gFHB6xb-kVBiQHYe_4hSi" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
EDIT: The videos must be shown in order, therefore I can't use rel to display only videos from the playlist. Plus, if you click on them a youtube page outside of the iframe will appear.
If I look through the YouTube Embedded Players and Player Parameters docs, there is no such thing to order the more videos section if you pause the video.
The two parameters I suggest to get near as possible to your goal is:
You can add:
listType=playlist
rel=0 to turn off related videos from the more videos section.
Note: The behaviour of rel=0 will be removed after September 25, 2019.
Conclusion:
It seems like what you want to achieve is not possible. With the default embed iframe of YouTube.
You might want to consider to look to other players with playlist options. Something like JW Player note that you need a licence for this player, JW Player playlist docs. I did some reading on JW Player as well, they currently don't support YouTube videos.
But maybe there are other players that have the same functionally for free.
If you add &rel=0 at the end of playlist link - in related videos will be showed only videos from your playlist. Example:
<iframe class="rep" src="https://www.youtube.com/embed/videoseries?list=PLUl4u3cNGP63gFHB6xb-kVBiQHYe_4hSi&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
If you remove &rel=0 from the link, it show random videos from youtube
Update for 2021
Youtube now seems to have a loop function that can be used to git rid of “related videos”. What it does basically is that when your video ends, it restarts again instead of showing (un)related videos. It worked perfectly in my case. Here is the code:
https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1
Please make sure to replace both VIDEO_ID in the code with your video ID. N̲o̲ N̲e̲e̲d̲ for creating a playlist
Example of full iframe code with player controls being enabled
<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1" title="YouTube video player" rel="0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Example of full iframe code with player controls being disabled
<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID?playlist=VIDEO_ID&loop=1&controls=0" title="YouTube video player" rel="0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
Here is a work around not the best but it will stop them annoy recommendations. It loops the playlist never giving youtube a chance to stop and give you there recommendations to get users back to youtube. This has worked well for me. If you see it plays my list in the loop and then plays the next, all without ever bringing up the recommendations. if you stop it it just stays there. Hope it helps they key is 0&loop
https://codesandbox.io/s/adoring-tereshkova-nwv8i
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app"></div>
<iframe width="100%" height="425" src="https://www.youtube.com/embed/HdEN2JinZVE?autoplay=&showinfo=0&loop=1&list=PLvNxGp1V1dOwpDBl7L3AJIlkKYdNDKUEs&rel=0" frameborder="0" allowfullscreen></iframe>
<script src="src/index.js">
</script>
</body>
</html>
It can not be done after September 25, 2018. The effect of the change is that you will not be able to disable related videos. Below is the YouTube official post link of it.
Official Link: https://developers.google.com/youtube/player_parameters#release_notes_08_23_2018
Thanks
I just found a great website that found a fix for your problem. The code is a bit long, but I think it works. They have an example if you scroll up a bit. https://www.maxlaumeister.com/blog/hide-related-videos-in-youtube-embeds/#hideyt-embed-code
<!-- https://maxl.us/hideyt -->
<style>
.hytPlayerWrap {
display: inline-block;
position: relative;
}
.hytPlayerWrap.ended::after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
cursor: pointer;
background-color: black;
background-repeat: no-repeat;
background-position: center;
background-size: 64px 64px;
background-image: url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==);
}
.hytPlayerWrap.paused::after {
content: "";
position: absolute;
top: 70px;
left: 0;
bottom: 50px;
right: 0;
cursor: pointer;
background-color: black;
background-repeat: no-repeat;
background-position: center;
background-size: 40px 40px;
background-image: url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSIxNzA2LjY2NyIgaGVpZ2h0PSIxNzA2LjY2NyIgdmlld0JveD0iMCAwIDEyODAgMTI4MCI+PHBhdGggZD0iTTE1Ny42MzUgMi45ODRMMTI2MC45NzkgNjQwIDE1Ny42MzUgMTI3Ny4wMTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+);
}
</style>
<div class="hytPlayerWrapOuter">
<div class="hytPlayerWrap">
<iframe width="640" height="360" src="https://www.youtube.com/embed/`**YOUR VIDEO ID HERE**`?rel=0&enablejsapi=1" frameborder="0"></iframe>
</div>
</div>
<script>
"use strict";
document.addEventListener('DOMContentLoaded', function () {
if (window.hideYTActivated) return;
let onYouTubeIframeAPIReadyCallbacks = [];
for (let playerWrap of document.querySelectorAll(".hytPlayerWrap")) {
let playerFrame = playerWrap.querySelector("iframe");
let tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
let firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
let onPlayerStateChange = function (event) {
if (event.data == YT.PlayerState.ENDED) {
playerWrap.classList.add("ended");
} else if (event.data == YT.PlayerState.PAUSED) {
playerWrap.classList.add("paused");
} else if (event.data == YT.PlayerState.PLAYING) {
playerWrap.classList.remove("ended");
playerWrap.classList.remove("paused");
}
};
let player;
onYouTubeIframeAPIReadyCallbacks.push(function () {
player = new YT.Player(playerFrame, {events: {'onStateChange': onPlayerStateChange}});
});
playerWrap.addEventListener("click", function () {
let playerState = player.getPlayerState();
if (playerState == YT.PlayerState.ENDED) {
player.seekTo(0);
} else if (playerState == YT.PlayerState.PAUSED) {
player.playVideo();
}
});
}
window.onYouTubeIframeAPIReady = function () {
for (let callback of onYouTubeIframeAPIReadyCallbacks) {
callback();
}
};
window.hideYTActivated = true;
});
</script>
In my case this is working you can try this :
https://www.youtube-nocookie.com/embed/{videoId}?rel=0&showinfo=0
Unfortunately, external CSS or JS can't be applied to iframe videos or iframe contents in a webpage.
For now, you can add rel=0 parameter to the video URL in iframe code. As per youtube documentations, rel=0 parameter will be disabled after Sep 25 2019.
Here is an example with rel=0 parameter
<iframe width="560" height="315" src="https://www.youtube.com/embed/J8Rt6HSzrqY&rel=0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
You can also use the playlist feature or parameter. See example below:
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?list=PLx0sYbCqOb8TBPRdmBHs5Iftvv9TPboYG&rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
Above code is taken from Official Youtube Support documents. You can add only one video in the list so that it does not play any other video after the current video finishes.
Based on the work of Maximillian Laumeister hideyt I forged a JS which can be included anywhere and autoamtically wraps its magic around every embedded youtube iframe you have.
hideYTrel.js
"use strict";
if (document.readyState !== 'loading') init();
else document.addEventListener('DOMContentLoaded', init);
function init() {
if (window.runOnce) return;
if (typeof YT === 'undefined') {
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 iframes = [];
for (var iframe of document.querySelectorAll("iframe[src]")) {
var src = iframe.getAttribute("src");
if (src.includes("youtube.com/embed/")) {
if(!src.includes("enablejsapi=1"))
if(src.includes("?"))
iframe.setAttribute("src", src + "&enablejsapi=1");
else
iframe.setAttribute("src", src + "?enablejsapi=1");
iframes.push(iframe);
}
}
var overlayStyles = {
display: "none",
content:"",
position: "absolute",
left: 0,
right: 0,
cursor: "pointer",
backgroundColor: "black",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
};
window.onYouTubeIframeAPIReady = function() {
iframes.forEach(function(iframe) {
var overlay = document.createElement('div');
for (var style in overlayStyles) {
overlay.style[style] = overlayStyles[style];
}
var wrapper = document.createElement('div');
wrapper.style.display = "inline-block";
wrapper.style.position = "relative";
iframe.parentNode.insertBefore(wrapper, iframe);
wrapper.appendChild(overlay);
wrapper.appendChild(iframe);
var onPlayerStateChange = function(event) {
if (event.data == YT.PlayerState.ENDED) {
overlay.style.backgroundImage = "url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjgiIGhlaWdodD0iMTI4IiB2aWV3Qm94PSIwIDAgNTEwIDUxMCI+PHBhdGggZD0iTTI1NSAxMDJWMEwxMjcuNSAxMjcuNSAyNTUgMjU1VjE1M2M4NC4xNSAwIDE1MyA2OC44NSAxNTMgMTUzcy02OC44NSAxNTMtMTUzIDE1My0xNTMtNjguODUtMTUzLTE1M0g1MWMwIDExMi4yIDkxLjggMjA0IDIwNCAyMDRzMjA0LTkxLjggMjA0LTIwNC05MS44LTIwNC0yMDQtMjA0eiIgZmlsbD0iI0ZGRiIvPjwvc3ZnPg==)";
overlay.style.backgroundSize = "64px 64px";
overlay.style.top = 0;
overlay.style.bottom = 0;
overlay.style.display = "inline-block";
} else if (event.data == YT.PlayerState.PAUSED) {
overlay.style.backgroundImage = "url(data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEiIHdpZHRoPSIxNzA2LjY2NyIgaGVpZ2h0PSIxNzA2LjY2NyIgdmlld0JveD0iMCAwIDEyODAgMTI4MCI+PHBhdGggZD0iTTE1Ny42MzUgMi45ODRMMTI2MC45NzkgNjQwIDE1Ny42MzUgMTI3Ny4wMTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+)";
overlay.style.backgroundSize = "40px 40px";
overlay.style.top = "40px";
overlay.style.bottom = "50px";
overlay.style.display = "inline-block";
} else if (event.data == YT.PlayerState.PLAYING) {
overlay.style.display = "none";
}
};
var player = new YT.Player(iframe, {
events: {
'onStateChange': onPlayerStateChange
}
});
wrapper.addEventListener("click", function() {
var playerState = player.getPlayerState();
if (playerState == YT.PlayerState.ENDED) {
player.seekTo(0);
} else if (playerState == YT.PlayerState.PAUSED) {
player.playVideo();
}
});
});
};
window.runOnce = true;
}
Jsfiddle: https://jsfiddle.net/pv75zjoh
I found out that if the youtube channel the video is from has less than (I don't know how many exactly but definitely more than 20 and less than 40) videos and the iframe youtube url has the rel=0 attribute, it won't show the related videos section at all.

I need help getting autoplay to work via [getElementById]

My code: https://jsfiddle.net/m656xw8s/24/
I've been trying to get autoplay to work, can someone show me what the correct code would be? Using the code I provided. Using [getElementById]
var player = document.getElementById('player').autoplay; document.getElementById('player').innerHTML = true;
<button id="playButton" style="border:none; width: 200px; height: 200px; cursor: pointer; font-family:Tahoma; font-weight: bold;font-size:14px; background-color:red;color:blue;" onclick="
var player = document.getElementById('player').autoplay;
document.getElementById('player').innerHTML = true;
var player = document.getElementById('player').volume='1.0';
var button = document.getElementById('playButton');
var player = document.getElementById('player');
if (player.paused) {
playButton.style.backgroundColor = 'red';
player.play();
} else {
playButton.style.backgroundColor = 'red';
player.pause();
}">
</button>
<audio id="player" style="display:none;">
<source src='http://hi5.1980s.fm/;' type='audio/mpeg' />
</audio>
Set the autoplay then load.
http://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_av_prop_autoplay
Update:
document.getElementById('playButton').addEventListener('click', autoPlayToggle);
document.getElementById('autovolume_range').addEventListener('change', changeVol);
//Only getElementById once!
var player = document.getElementById("player");
var autoplaytext = document.getElementById("autoplay_text");
var autovolumetext = document.getElementById("autovolume_range");
//Boolean from localstorage to keep state of the player
var autoPlayOn = autoplaytext.value = (localStorage.getItem("keepAutoPlay") === "true");
var setVolumeOn = autovolumetext.value = parseFloat(localStorage.getItem("keepVolume"));
player.volume = setVolumeOn;
player.autoplay = autoPlayOn;
player.load();
//Force play if it dosen't autoplay after refresh
if (player.autoplay == true) {
player.play();
} else {
player.pause();
}
//Function
//When the user refreshes the page it will keep the autoplay state
function autoPlayToggle() {
if (player.paused) {
player.play();
player.autoplay = true;
} else {
player.pause();
player.autoplay = false;
}
//Show the state in a text box
autoplaytext.value = player.autoplay;
//Save updated state to your local disk
localStorage.setItem("keepAutoPlay", autoplaytext.value);
}
//Save state of volume
function changeVol() {
player.volume = this.value;
localStorage.setItem("keepVolume", this.value);
}
<button id="playButton" style="border:none; width: 200px; height: 200px; cursor: pointer; font-family:Tahoma; font-weight: bold;font-size:14px; background-color:red;color:blue;">
</button>
<audio id="player" style="display:none;" >
<source src='http://hi5.1980s.fm/;' type='audio/mpeg'/>
</audio>
AutoPlay: <input id="autoplay_text" />
AutoVolume: <input type="range" step="0.1" min="0.0" max="1.0" id="autovolume_range" />
https://jsfiddle.net/LeroyRon/dtnrdjd5/
You only need to add attribute auto play to your audio tag see the updated code below; Based on your code you are redeclaring player multiple times see the updated code below. Your auto play is triggered on button click based on your code, you may want to separate the javascript codes to the button and just trigger a method indicated on your button click event.
You will need to use removeAttribute to remove the autoplay from your audio element. I added the code on how to do it below.
//player declared outside of the audioPlay method to make it accessible inside the audioPlay method
var player = document.getElementById('player');
//auto play set outside playAudio method outside of the button click event method
player.setAttribute('autoplay', '');
//to set autoplay false uncomment the code below
//player.removeAttribute('autoplay');
//playAudio is triggered on button click event
function playAudio(){
player.setAttribute('volume', 1.0);
var button = document.getElementById('playButton');
if (player.paused) {
playButton.style.backgroundColor = 'red';
player.play();
} else {
playButton.style.backgroundColor = 'red';
player.pause();
}
}
<button id="playButton" style="border:none; width: 200px; height: 200px; cursor: pointer; font-family:Tahoma; font-weight: bold;font-size:14px; background-color:red;color:blue;" onclick="
playAudio()">
</button>
<audio id="player" style="display:none;">
<source src='http://hi5.1980s.fm/;' type='audio/mpeg' />
</audio>

Is there a way to use the Youtube API using less code?

I did some tests to find a way to play an embed video from youtube and it stops others videos of the page that is playing in the moment.
I reached the following code:
<!DOCTYPE html>
<html>
<head>
<title>Youtube players test</title>
<style type="text/css" >
li {
list-style: none;
margin-bottom: 10px;
}
</style>
<script type="text/javascript" src="jquery-2.1.3.min.js"></script>
</head>
<body>
<ul id="videos">
<li>Video1</li>
<iframe id="player1" class="video" type="text/html" width="400" height="225" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1"
frameborder="0" allowfullscreen></iframe>
<li>Video2</li>
<iframe id="player2" class="video" width="400" height="225" src="https://www.youtube.com/embed/3TAUnYZpMbA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<li>Video3</li>
<iframe id="player3" class="video" width="400" height="225" src="https://www.youtube.com/embed/9U38GB2qVWA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var primteste = document.getElementsByTagName('script')[0];
primteste.parentNode.insertBefore(tag, primteste);
var players = new Array();
function onYouTubeIframeAPIReady() {
players[0] = new YT.Player('player1', {
events: {
'onStateChange': onPlayer1StateChange
}
});
players[1] = new YT.Player('player2', {
events: {
'onStateChange': onPlayer2StateChange
}
});
players[2] = new YT.Player('player3', {
events: {
'onStateChange': onPlayer3StateChange
}
});
}
function onPlayer1StateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
var x = 0;
for (i=0;i<3;i++) {
if (i == x) {
i++;
}
players[i].stopVideo();
}
}
}
function onPlayer2StateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
var x = 1;
for (i=0;i<3;i++) {
if (i == x) {
i++;
}
players[i].stopVideo();
}
}
}
function onPlayer3StateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
var x = 2;
for (i=0;i<3;i++) {
if (i == x) {
i++;
}
players[i].stopVideo();
}
}
}
</script>
</body>
</html>
The code above satisfies my initial intention of play/stop videos and here goes my question. I did with only three videos and It's not too great for three, but I have a page that has more than 20 embed videos and with the way I coded I will have to code the same for each one of the videos what it will take lines and lines. Because I thought a lot and I couldn't figure out a simpler way to do it.
Could someone gives me a light about this situation? Is there someone that sees a better way to do the same?
Thanks
Call the same onPlayerStateChange callback for all your players and stop all but the current player. To check if this is the current player, use event.target != players[i].
Here's your example with a few tweaks.
<!DOCTYPE html>
<html>
<head>
<title>Youtube players test</title>
<style type="text/css">
li {
list-style: none;
margin-bottom: 10px;
}
</style>
<script type="text/javascript" src="jquery-2.1.3.min.js"></script>
</head>
<body>
<ul id="videos">
<li>
<h4>Video 1</h4>
<iframe id="player1" class="video" width="400" height="225" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</li>
<li>
<h4>Video 2</h4>
<iframe id="player2" class="video" width="400" height="225" src="https://www.youtube.com/embed/3TAUnYZpMbA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</li>
<li>
<h4>Video 3</h4>
<iframe id="player3" class="video" width="400" height="225" src="https://www.youtube.com/embed/9U38GB2qVWA?enablejsapi=1" frameborder="0" allowfullscreen></iframe>
</li>
</ul>
<script type="text/javascript">
// Insert youtube API
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var primteste = document.getElementsByTagName('script')[0];
primteste.parentNode.insertBefore(tag, primteste);
var players = [];
function onYouTubeIframeAPIReady() {
// Populate 'players' with all the youtube iframes
var videoIframes = document.getElementsByClassName('video');
for(var i=0; i<videoIframes.length; i++){
players.push(
new YT.Player(videoIframes[i], { // here we can pass an iframe element or an id
events: {
'onStateChange': onPlayerStateChange
}
})
);
}
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
for (i=0; i<players.length; i++) {
// Stop all but the current player (the one that triggered the event)
if(players[i] != event.target){
players[i].stopVideo();
}
}
}
}
</script>
</body>
</html>
This code will automatically add new players to the players array as long as the iframe holding the player has the class .video.
You don't need to have an id for each iframe but I left them there just in case you're using them somewhere else.
function _getOnPlayerChangeHandler(playerIndex) {
return function (event) {
if (event.data === YT.PlayerState.PLAYING) {
var i;
for (i = 0; i < players.length; i++) {
if (i !== playerIndex) {
players[i].stopVideo();
}
}
}
};
}
function _createPlayer (selector, playerIndex) {
return new YT.Player(selector, {
onStateChange: _getOnPlayerChangeHandler(playerIndex)
});
}
players[0] = _createPlayer('player1', 0);
players[1] = _createPlayer('player2', 1);
players[2] = _createPlayer('player3', 2);
If you have more information about the player in the event object, you may not even have to create the handler from a factory like the one I've made.

Add email Signup Form when the video ends

I am trying to call an email sign up form when the video ends. My problem I don't know how to call the form inside the javascript, so far what I have achieved is to call an alert when the video ends.
Can someone please help me with this?
<video id="myVideo" controls="controls" width="300" height="150">
<source src="http://movie.webm" type="video/webm" />
<source src="your_video_file.ogg" type="video/ogg" />
Your browser does not support HTML5 video.
</video>
<script type="text/javascript">
document.getElementById('myVideo').addEventListener('ended', myHandler, false);
function myHandler(e) {
if (!e) { e = window.event; }
alert("Video Finished");
}
</script>
/*** UPDATE - FOR SOMEONE WHO ARE LOOKING FOR THE SAME HERE IS THE CODE ********/
<!DOCTYPE html>
<html>
<head>
<style>
#overlayContactForm {
visibility: hidden;
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:100%;
text-align:center;
z-index: 1000;
}
#overlayContactForm div {
width: 428px;
margin: 65px;
background-color: #fff;
border: 1px solid #000;
padding: 15px;
text-align: center;
height: 200px;
}
</style>
</head>
<body>
<div id="player"></div>
<script src="http://www.youtube.com/player_api"></script>
<div align="center">
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'VhvUEhxL1DQ',
playerVars: {rel: 0},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
event.target.playVideo();
}
// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
el = document.getElementById("overlayContactForm");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" :
"visible";
}
}
</script>
</div>
<div id="overlayContactForm">
<div>
<h1> Text Header Info </h1>
<form class="form-inline">
<input type="email" class="form-control" id="exampleInputEmail3"
placeholder="Email Address">
<button type="submit" class="btn btn-default">Sign in</button>
</form>
<p> Testing email opt-in - Video/Form </p>
</div>
</div>
</body>
</html>
Handle the javascript video end event as:
var signupForm; // reference to the sign-up form
signupForm.style.display = ''; // form initially hidden
// on video end
document.getElementById('myVideo').onended = function(e) {
signupForm.style.display = 'block';
};
EDIT:
Assuming that signupForm is a modal dialog, you can change the even handlers like this
var button; // reference to the button
document.getElementById('myVideo').onended = function(e) {
button.click();
};
button.onclick = function(e) {
signupForm.style.display = 'block';
}
So the modal will now show up both when button is clicked or the video has ended.

Categories