I am using Froogaloop.js to pause and play the vimeo video externally . Now I want to show a div after 20 second of video has been played. How to achieve this, I searched a lot and was not able to crack the code for it. This is what I have tried so far..
var iframe = document.getElementById('video');
// $f == Froogaloop
var player = $f(iframe);
// bind events
var playButton = document.getElementById("play-button");
playButton.addEventListener("click", function() {
player.api("play");
});
var pauseButton = document.getElementById("pause-button");
pauseButton.addEventListener("click", function() {
player.api("pause");
});
.button {
width: 48px;
height: 48px;
cursor: pointer;
}
.defs {
position: absolute;
top: -9999px;
left: -9999px;
}
iframe {
float: left;
width: 350px;
height: 200px;
}
.buttons {
padding: 1rem;
background: #f06d06;
float: left;
}
body {
padding: 1rem;
}
.show--div-20sec {
width: 100%;
background: red;
height: 80px;
float: left;
display: none;
}
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/froogaloop.js"></script>
<iframe src="https://player.vimeo.com/video/80312270?api=1" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen id="video"></iframe>
<!-----------Show this div when video has been played for 20 seconds----->
<div class="show--div-20sec">
Show me after 20 second of video play
</div>
<div class="buttons">
<button id="play-button">Play</button>
<button id="pause-button">Pause</button>
</div>
Help much appriciated.. Thanks in advance :)
Try this code
$(function() {
var iframe = $('#player1')[0];
var player = $f(iframe);
var status = $('.status');
var playButton = document.getElementById("play-button");
playButton.addEventListener("click", function() {
player.api("play");
});
var pauseButton = document.getElementById("pause-button");
pauseButton.addEventListener("click", function() {
player.api("pause");
});
setTimeout(function () {
player.addEvent('ready', function() {
player.addEvent('playProgress', onPlayProgress);
});
});
function onPlayProgress(data, id) {
var Time = data.seconds;
if (Time >= '20') {
$('.show--div-20sec').show();
}
}
});
DEMO
This is answer of your question i guess, you just need to modify the console.log part.
$(function() {
var iframe = $('#video')[0];
console.log()
var player = $f(iframe);
// When the player is ready, add listeners for pause, finish, and playProgress
player.addEvent('ready', function() {
status.text('ready');
player.addEvent('pause', onPause);
player.addEvent('finish', onFinish);
player.addEvent('playProgress', onPlayProgress);
});
// Call the API when a button is pressed
$('button').bind('click', function() {
player.api($(this).text().toLowerCase());
});
function onPause() {}
function onFinish() {}
function onPlayProgress(data) {
if (data.seconds >= 20) {
$('.show--div-20sec').css('display', 'block')
}
}
});
.button {
width: 48px;
height: 48px;
cursor: pointer;
}
.defs {
position: absolute;
top: -9999px;
left: -9999px;
}
iframe {
float: left;
width: 350px;
height: 200px;
}
.buttons {
padding: 1rem;
background: #f06d06;
float: left;
}
body {
padding: 1rem;
}
.show--div-20sec {
width: 100%;
background: red;
height: 80px;
float: left;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://f.vimeocdn.com/js/froogaloop2.min.js"></script>
<iframe src="//player.vimeo.com/video/80312270?api=1&player_id=video" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen id="video"></iframe>
<!-----------Show this div when video has been played for 20 seconds----->
<div class="show--div-20sec">
Show me after 20 second of video play
</div>
<div class="buttons">
<button id="play-button">Play</button>
<button id="pause-button">Pause</button>
</div>
Related
I am working on a static portfolio site and have styled some Javascript audio players.
The site is live here with the first audio player working almost exactly as desired (except the progress bar displays at the top of the div, I'd like it at the bottom). A photo is attached of the desired visual outcome.
I need five total audio players. How can I achieve this?
Current Javascript:
const audioPlayer = document.querySelector(".audio-player");
const audio = new Audio(
"https://jsomerset.uk/images/victory.mp3"
);
console.dir(audio);
audio.addEventListener(
"loadeddata",
() => {
audioPlayer.querySelector(".time .length").textContent = getTimeCodeFromNum(
audio.duration
);
audio.volume = .75;
},
false
);
const timeline = audioPlayer.querySelector(".timeline");
timeline.addEventListener("click", e => {
const timelineWidth = window.getComputedStyle(timeline).width;
const timeToSeek = e.offsetX / parseInt(timelineWidth) * audio.duration;
audio.currentTime = timeToSeek;
}, false);
setInterval(() => {
const progressBar = audioPlayer.querySelector(".progress");
progressBar.style.width = audio.currentTime / audio.duration * 100 + "%";
audioPlayer.querySelector(".time .current").textContent = getTimeCodeFromNum(
audio.currentTime
);
}, 500);
const playBtn = audioPlayer.querySelector(".controls .toggle-play");
playBtn.addEventListener(
"click",
() => {
if (audio.paused) {
playBtn.classList.remove("play");
playBtn.classList.add("pause");
audio.play();
} else {
playBtn.classList.remove("pause");
playBtn.classList.add("play");
audio.pause();
}
},
false
);
You code can't run properly, since you're selecting non existent elements.
Check you dev tools console for errors.
E.g. you're trying to display the current time in an element with the class time – but yout html does not contain such an element.
Besides, you haven't defined the method getTimeCodeFromNum().
See the cleaned up code – not usable blocks are commented out :
const audioPlayer = document
.querySelectorAll(".audio-player")
.forEach((audioPlayer) => {
const audio = new Audio(audioPlayer.dataset.src);
//console.dir(audio);
/*
audio.addEventListener(
"loadeddata",
() => {
audioPlayer.querySelector(
".time .length"
).textContent = getTimeCodeFromNum(audio.duration);
audio.volume = 0.75;
},
false
);
*/
const timeline = audioPlayer.querySelector(".timeline");
timeline.addEventListener(
"click",
(e) => {
const timelineWidth = window.getComputedStyle(timeline).width;
const timeToSeek =
(e.offsetX / parseInt(timelineWidth)) * audio.duration;
audio.currentTime = timeToSeek;
},
false
);
setInterval(() => {
const progressBar = audioPlayer.querySelector(".progress");
progressBar.style.width =
(audio.currentTime / audio.duration) * 100 + "%";
/*
audioPlayer.querySelector(
".time .current"
).textContent = getTimeCodeFromNum(audio.currentTime);
*/
}, 500);
const playBtn = audioPlayer.querySelector(".controls .toggle-play");
playBtn.addEventListener(
"click",
() => {
if (audio.paused) {
playBtn.classList.remove("play");
playBtn.classList.add("pause");
audio.play();
} else {
playBtn.classList.remove("pause");
playBtn.classList.add("play");
audio.pause();
}
},
false
);
/*
audioPlayer
.querySelector(".volume-button")
.addEventListener("click", () => {
const volumeEl = audioPlayer.querySelector(".volume-container .volume");
audio.muted = !audio.muted;
if (audio.muted) {
volumeEl.classList.remove("icono-volumeMedium");
volumeEl.classList.add("icono-volumeMute");
} else {
volumeEl.classList.add("icono-volumeMedium");
volumeEl.classList.remove("icono-volumeMute");
}
});
*/
});
body {
background: #000
}
.audio-player {
display: grid;
grid-template-rows: 6px auto;
overflow: hidden;
height: 200px;
width: 100vw;
color: #efefef;
}
.timeline {
background: none;
width: 100%;
position: relative;
cursor: pointer;
height: 5px;
}
.progress {
background: #efefef;
width: 0%;
height: 5px;
transition: 0.25s;
-webkit-transition: 0.25s;
}
.controls {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
}
.controls * {
display: flex;
justify-content: center;
align-items: center;
}
.play {
cursor: pointer;
position: relative;
left: 0;
height: 0;
width: 0;
border: 7px solid #0000;
border-left: 13px solid white;
}
.pause {
height: 15px;
width: 20px;
cursor: pointer;
position: absolute;
margin-left: 15px;
}
.pause:before {
position: absolute;
top: 0;
left: 0px;
background: white;
content: "";
height: 15px;
width: 3px;
}
.pause:after {
position: absolute;
top: 0;
right: 9px;
background: white;
content: "";
height: 15px;
width: 3px;
}
<div class="audio-player a-one font" data-src="https://jsomerset.uk/images/swain.mp3">
<div class="timeline">
<div class="progress" style="width: 0%;"></div>
</div>
<div class="name">Action</div>
<div class="controls">
<div class="play-container">
<div class="toggle-play play">
</div>
</div>
</div>
</div>
<div class="audio-player a-two font" data-src="https://jsomerset.uk/images/victory.mp3">
<div class="timeline">
<div class="progress"></div>
</div>
<div class="name">Victory Song</div>
<div class="controls">
<div class="play-container">
<div class="toggle-play play">
</div>
</div>
</div>
</div>
Use document.querySelectorAll, then loop over the selection. You can store the mp3 URL for each div inside a data-src attribute:
<div class="audio-player" data-src="https://jsomerset.uk/images/victory.mp3">...</div>
<div class="audio-player" data-src="https://jsomerset.uk/images/anotherFile.mp3">...</div>
<div class="audio-player" data-src="https://jsomerset.uk/images/etc.mp3">...</div>
document.querySelectorAll(".audio-player").forEach(audioPlayer => {
const audio = new Audio(audioPlayer.dataset.src);
// rest of your code
});
I made images and a video slideshow. 3 images and at the end 1 video. It is fine when I made it on a full-screen web page.
But when I made it to half of the screen the transition error showed up, the next image flashed at the bottom of the earlier image.
How can I fix my slideshow transition error?
Can anyone help me?
// Some variables
var timer;
var sWidth = '100%',
sHeight = '80%',
border = 10;
var slideshowSet = false;
var video;
var videoSet = false;
var slidePause = false;
var $el;
var $currentEl = $('.slideshow').find('li').eq(0);
// On document ready
$(function() {
// Set slideshow dimensions + border
setSlideDimensions(sWidth, sHeight, border);
// Show pause button
$('.slideshow').hover(
function() {
if (slideshowSet) {
$('.pause').stop().fadeIn(200);
}
},
function() {
if (slideshowSet) {
$('.pause').fadeOut(200);
}
}
);
// Pause button
$('.pause').click(function() {
if ($(this).text() == '| |') {
// Pause slideshow
slidePause = true;
$(this).text('►');
clearTimeout(timer);
if ($currentEl.find('video').size() == 1) {
video.pause();
}
} else {
// Play slideshow
$(this).text('| |');
if ($currentEl.find('video').size() == 1) {
video.play();
} else {
timer = setTimeout(slide, 2000);
}
}
});
});
// Window ready (all images loaded, but not videos!!)
$(window).ready(function() {
// Hide loader GIF
$('.loader').fadeOut(200);
// Show slideshow
$('.slideshow ul').fadeIn(200);
// Start slideshow
$el = $('.slideshow').find('li');
timer = setTimeout(slide, 2000);
slideshowSet = true;
});
// Function to slide
function slide() {
videoSet = false;
$el = $('.slideshow').find('li');
$el.eq(1).add($el.eq(0)).animate({
'left': '-=' + sWidth
}, {
queue: false,
duration: 300,
complete: function() {
$el.eq(0).animate({
'left': '100%'
}, 0);
$currentEl = $el.eq(1);
if ($(this).index() == 1) {
$('.slideshow ul').append($el.eq(0));
// We chek if it's a video
if ($(this).find('video').size() == 1) {
//If yes we set the variable
video = $(this).find('video')[0];
videoSets();
// If video can play
if (video.canPlayType) {
// Play video
video.play();
} else {
// Error message
alert('No html5');
}
} else {
// If not a video we set timeout to next slide
timer = setTimeout(slide, 2000);
}
}
}
});
}
// Function to set all video events
function videoSets() {
if (!videoSet) {
videoSet = true;
// Video ended
video.addEventListener("ended", function() {
timer = setTimeout(slide, 2000);
});
// Video Playing
video.addEventListener("playing", function() {
clearTimeout(timer);
if (slidePause) {
$('.pause').text('| |');
video.play();
slidePause = false;
}
});
}
}
// Function to set slideshow dimensions
function setSlideDimensions(w, h, b) {
$('.slideshow').css({
width: w,
'height': h,
'padding': b
});
$('.slideshow ul li img, .slideshow ul li video').css({
width: w,
'height': h
});
}
.slideshow {
position: relative;
margin: auto;
}
.slideshow ul {
width: 100%;
height: 100%;
position: relative;
list-style: none;
overflow: hidden;
display: none;
}
.slideshow ul li {
position: relative;
left: 100%;
}
.slideshow ul li:first-child {
left: 0%;
}
video {
background: #434343;
}
.loader {
width: 50px;
height: 50px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -25px;
margin-top: -25px;
}
.pause {
display: none;
width: 50px;
height: 50px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -25px;
margin-top: -25px;
border-radius: 50%;
background: rgba(0,0,0,.6);
z-index: 100;
line-height: 50px;
text-align: center;
font-size: 1.0em;
font-weight: bold;
color: white;
cursor: pointer;
}
.column {
float: left;
width: 50%;
padding: 5px;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<div class="row">
<div class="column">
<section class="slideshow">
<div class="pause">| |</div>
<img src="https://c.tenor.com/5o2p0tH5LFQAAAAi/hug.gif" width="50" class="loader" />
<ul>
<li><img src="https://natureconservancy-h.assetsadobe.com/is/image/content/dam/tnc/nature/en/photos/Zugpsitze_mountain.jpg?crop=0%2C176%2C3008%2C1654&wid=2000&hei=1100&scl=1.504" /></li>
<li><img src="https://mymodernmet.com/wp/wp-content/uploads/2021/04/Nature-Sounds-For-Well-Being-03.jpg" /></li>
<li><img src="https://img.freepik.com/free-photo/sunrise-jungle_1385-1689.jpg?w=1380&t=st=1664437209~exp=1664437809~hmac=2f34f36a7ab7d602cc4927fce5ad3063c5d945a169145d997b27e9f78f76f5ad" /></li>
<li><img src="https://img.freepik.com/free-photo/madakaripura-waterfall-is-tallest-waterfall-java_335224-388.jpg?w=1380&t=st=1664437263~exp=1664437863~hmac=5dfd42c39de69c5eebc5a8976d6ffc1ca733db1720a2b984a2d19b0cf5166c50" /></li>
<li><img src="https://img.freepik.com/premium-photo/natural-portraits-rice-fields-mountains-indonesian-rural-areas-with-sunrise-green-morning-dew-asia_80375-80.jpg?w=1380" /></li>
<li>
<video controls id="video1" preload>
<source src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4">
</video>
</li>
</ul>
</section>
</div>
<div class="column">
</div> </div>
</body>
</html>
I have markup that is added via JS that has an onclick action (it's a close button).
Essentially:
User clicks play button
A modal appears with the video and a close modal button (both which are added via JS)
As my close button (.modal--close) isn't on the page on load, I'm getting a Cannot set properties of null (setting 'onclick') (I think).
My thoughts are that the because the DOMContentLoaded event was already fired at this point, it is causing the error? But unsure how to resolve it.
Demo
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
if(document.querySelector(".open-video")){
document.querySelector(".open-video").onclick = function (e) {
e.preventDefault();
var modal = document.querySelector(".videoModal");
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
return false;
}
}
// close modal
document.querySelector(".modal--close").onclick = function (e) {
e.preventDefault();
console.log("test");
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before, .modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before, .modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe, .modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<a id="modal_close" class="modal__close"></a>
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>
Edit
Have also tried moving the event listener after the markup has been added:
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
let video_btn = document.querySelector(".open-video");
let close_btn = document.querySelector(".modal--close");
let modal = document.querySelector(".videoModal");
if(video_btn){
video_btn.addEventListener("click", function (e) {
e.preventDefault();
// get data
var triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
return false;
close_btn.addEventListener("click", function (e) {
e.preventDefault();
console.log("test");
});
});
}
}
With the above, the modal launches fine, but when I click .modal--close, nothing happens (no console.log and no console errors).
Edit 2
Have also tried moving the second event listener above the code snippet that adds the markup:
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
close_btn.addEventListener("click", function (e) {
e.preventDefault();
console.log("test");
});
modal.innerHTML = html;
return false;
With the above however, when I click the .open-video button, I get the error Cannot read properties of null (reading 'addEventListener')
if (document.readyState === "complete") {
ready();
} else {
document.addEventListener("DOMContentLoaded", ready);
}
function ready() {
var modal = document.querySelector(".videoModal");
var triggerURL;
if(document.querySelector(".open-video")){
document.querySelector(".open-video").onclick = function (e) {
e.preventDefault();
// get data
triggerURL = this.getAttribute("href");
var triggerID = this.getAttribute("data-modal");
// update modal attributes with trigger data
modal.setAttribute("data-video", triggerURL);
modal.setAttribute("id", triggerID);
var modalID = '#'+ triggerID;
modal.classList.add("modal--open");
return false;
}
}
// close modal
var html = '<div class="modal__wrapper"><iframe width="640" height="360" src="'+ triggerURL + '?rel=0&autoplay=1" frameborder="0" allowfullscreen></iframe></div><div class="modal__overlay"></div>';
modal.innerHTML = html;
if(document.querySelector(".modal--close")){
document.querySelector(".modal--close").onclick = function (e) {
e.preventDefault();
console.log("test");
}
}
}
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
overflow: hidden;
display: none;
padding: 70px 80px;
}
.modal--close {
position: fixed;
right: 50%;
top: 32px;
width: 16px;
height: 16px;
z-index: 999999;
pointer-events: auto !important;
}
.modal--close:hover:before, .modal--close:hover:after {
background-color: #F15A40;
}
.modal--close:before, .modal--close:after {
content: "";
position: absolute;
left: 15px;
height: 16px;
width: 2px;
background-color: #FFFFFF;
}
.modal--close:before {
transform: rotate(45deg);
}
.modal--close:after {
transform: rotate(-45deg);
}
.modal--open {
display: block;
}
.modal .modal__wrapper {
position: relative;
top: 50%;
transform: translateY(-50%);
max-height: 100%;
overflow: hidden;
z-index: 150;
}
.modal .modal__wrapper:before {
content: "";
display: block;
padding-top: 56.25%;
}
.modal .modal__wrapper iframe, .modal .modal__wrapper video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: none;
}
.modal .modal__overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000000;
}
<a class="button--play open-video" data-modal="video--1" href="https://www.youtube.com/embed/NpEaa2P7qZI">Click me</a>
<div class="videoModal modal modal__post--modal">
<a id="modal_close" class="modal__close"></a>
<div class="modal__wrapper"></div>
<div class="modal__overlay"></div>
</div>
Just wrap the code snippet that fires the issues with below function.
if(document.querySelector(".modal--close")){
}
I need multiple youtube player inside each .player div, But here only one player is loading with my code.
So can anyone please help me to find where is the problem?
$(document).ready(function(){
var iframeCount = $('.player');
iframeCount.each(function (index) {
$(this).attr('id', 'player-'+index);
});
var player, pId, playerText;
$('.start-video').on('click', function (index) {
onPlayerStateChange = function (event) {
if (event.data == YT.PlayerState.ENDED) {
event.target.destroy();
}
}
playerText = $(this).siblings('.player').text();
pId = $(this).siblings('.player').attr('id');
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
onYouTubeIframeAPIReady = function () {
player = new YT.Player(pId, {
height: '244',
width: '434',
videoId: playerText, // youtube video id
playerVars: {
'autoplay': 1,
'rel': 0,
'showinfo': 0
},
events: {
'onStateChange': onPlayerStateChange
}
});
}
$(this).parent().find('.start-video').fadeOut();
});
});
.y-video{
position: relative;
display: inline-block;
min-width: 434px;
min-height: 262px;
}
.y-video img{
position: absolute;
width: 434px;
height: 244px;
left: 0;
top: 0;
}
.play-icon{
display: inline-block;
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
top: 42%;
z-index: 1;
width: 40px;
font-size: 26px;
border: 3px solid #fff;
border-radius: 50%;
text-align: center;
color: #fff;
padding: 4px 0 4px 5px;
cursor: pointer;
background: rgba(0,0,0,.7);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="y-video">
<div class="player">gpzuVt_mkKs</div>
<span class="play-icon start-video">▷</span>
<img class="start-video" src="http://img.youtube.com/vi/gpzuVt_mkKs/0.jpg">
</div>
<div class="y-video">
<div class="player">Ep6U7vGjFw0</div>
<span class="play-icon start-video">▷</span>
<img class="start-video" src="http://img.youtube.com/vi/Ep6U7vGjFw0/0.jpg">
</div>
<div class="y-video">
<div class="player">6lt2JfJdGSY</div>
<span class="play-icon start-video">▷</span>
<img class="start-video" src="http://img.youtube.com/vi/6lt2JfJdGSY/0.jpg">
</div>
You need to separate the classes of each player (e.g. player1, player2 onwards), this will help your application separate each code/player.
Code snippet from a related SO post:
<div id="ytplayer1"></div>
<div id="ytplayer2"></div>
<script>
var player;
var player2;
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer1', {
height: '390',
width: '640',
videoId: 'hdy78ehsjdi'
});
player2 = new YT.Player('ytplayer2', {
height: '390',
width: '640',
videoId: '81hdjskilct'
});
}
</script>
There is also a Github code for playing multiple videos using Youtube API iFrame.
Hope this helps.
Used following reference to fix my issue: [http://jsfiddle.net/KtbYR/5/][1]
$(document).ready(function(){
var iframeCount = $('iframe');
iframeCount.each(function (index) {
$(this).attr('id', 'player-'+index);
});
});
function getFrameID(id) {
var elem = document.getElementById(id);
if (elem) {
if (/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
// else: Look for frame
var elems = elem.getElementsByTagName("iframe");
if (!elems.length) return null; //No iframe found, FAILURE
for (var i = 0; i < elems.length; i++) {
if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
}
elem = elems[i]; //The only, or the best iFrame
if (elem.id) return elem.id; //Existing ID, return it
// else: Create a new ID
do { //Keep postfixing `-frame` until the ID is unique
id += "-frame";
} while (document.getElementById(id));
elem.id = id;
return id;
}
// If no element, return null.
return null;
}
// Define YT_ready function.
var YT_ready = (function() {
var onReady_funcs = [],
api_isReady = false;
/* #param func function Function to execute on ready
* #param func Boolean If true, all qeued functions are executed
* #param b_before Boolean If true, the func will added to the first
position in the queue*/
return function(func, b_before) {
if (func === true) {
api_isReady = true;
for (var i = 0; i < onReady_funcs.length; i++) {
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if (typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before ? "unshift" : "push"](func);
}
}
})();
// This function will be called when the API is fully loaded
function onYouTubePlayerAPIReady() {
YT_ready(true)
}
var players = {};
//Define a player storage object, to enable later function calls,
// without having to create a new class instance again.
YT_ready(function() {
$(".thumb + iframe[id]").each(function() {
var identifier = this.id;
var frameID = getFrameID(identifier);
if (frameID) { //If the frame exists
players[frameID] = new YT.Player(frameID, {
events: {
"onReady": createYTEvent(frameID, identifier)
}
});
}
});
});
// Returns a function to enable multiple events
function createYTEvent(frameID, identifier) {
return function (event) {
var player = players[frameID]; // player object
var the_div = $('#'+identifier).parent();
the_div.children('.thumb').click(function() {
var $this = $(this);
$this.fadeOut().next().addClass('play');
setTimeout(function(){
$this.siblings('.thumb').hide();
},150);
if ($this.next().hasClass('play')) {
player.playVideo();
//player.destroy();
}
});
}
}
// Load YouTube Frame API
(function(){ //Closure, to not leak to the scope
var s = document.createElement("script");
s.src = "http://www.youtube.com/player_api"; /* Load Player API*/
var before = document.getElementsByTagName("script")[0];
before.parentNode.insertBefore(s, before);
})();
.y-video{
position: relative;
display: block;
width: 500px;
clear: left;
}
.play-icon{
display: inline-block;
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
top: 42%;
z-index: 1;
width: 40px;
font-size: 26px;
border: 2px solid #fff;
border-radius: 50%;
text-align: center;
color: rgba(255,255,255,0.4);
padding: 4px 0 4px 5px;
cursor: pointer;
background: rgba(0,0,0,.1);
-webkit-transition: 0.4s;
-moz-transition: 0.4s;
transition: 0.4s;
}
img.thumb{
position: absolute;
width: 100%;
height: auto;
max-height: 281px;
left: 0;
top: 0;
}
.y-video:hover .play-icon{
border-color: rgba(0,0,0,.1);
background: rgba(0,0,0,.6);
color: rgba(255,255,255,0.8);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="y-video">
<span class="thumb play-icon">▷</span>
<img class="thumb" src="http://img.youtube.com/vi/gpzuVt_mkKs/0.jpg">
<iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/gpzuVt_mkKs?enablejsapi=1&showinfo=0&rel=0">
</iframe>
</div>
<div class="y-video">
<span class="thumb play-icon">▷</span>
<img class="thumb" src="http://img.youtube.com/vi/Ep6U7vGjFw0/0.jpg">
<iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/Ep6U7vGjFw0?enablejsapi=1&showinfo=0&rel=0">
</iframe>
</div>
<div class="y-video">
<span class="thumb play-icon">▷</span>
<img class="thumb" src="http://img.youtube.com/vi/6lt2JfJdGSY/0.jpg">
<iframe width="500" height="281" frameborder="0" src="https://www.youtube.com/embed/6lt2JfJdGSY?enablejsapi=1&showinfo=0&rel=0">
</iframe>
</div>
My video player isn't working, it doesn't play when I click on the play button. I am testing it on chrome browser.
This is my code (I think the problem is in the JS part):
function dofirst() {
barSize = 500;
video = document.getElementById('video');
playbutton = document.getElementById('playbutton');
defaultBar = document.getElementById('defaultBar');
progressbar = document.getElementById('progressbar');
playbutton.addEventListener(click, PlayOrPause ,false);
defaultBar.addEventListener(click, clickedBar ,false);
}
function PlayOrPause() {
If( !video.paused && !video.ended){
video.pause();
playbutton.innerHTML = 'play';
window.clearInterval(updatebar);
} else {
video.play();
playbutton.innerHTML = 'pause';
updatebar = setInterval(update,500);
}
}
function update(){
if(!video.ended){
var size= parseInt(video.currentTime*barsize/video.duration);
progressbar.style.width = size +'px';
} else {
progressbar.style.width ='0px';
playbutton.innerHTML = 'play';
window.clearInterval(updatebar);
}
}
function clickedBar(e) {
If( !video.paused && !video.ended){
var mouseX = e.pageX-bar.offsetLeft;
var newtiem = mouseX*video.duration/barSize;
myMovie.currentTime = newtime;
progressbar.style.width = mouseX+'px';
}
}
window.addEventListener('load',dofirst,false);
body {
text-align: center;
}
#skin {
background: #5C6366;
width: 700px;
margin: 10px auto;
padding: 50px;
border: 2px black auto;
border-radius: 30px;
}
nav {
margin: 2px 0px;
}
#buttons {
float: left;
width: 70px;
height: 20px;
margin-left: 20px;/* 90px total 610 remaining*/
}
#defaultBar {
margin-top: 5px;
position: relative;
width: 500px;
float : left;
height: 5px;
background-color: black;
}
#progressbar {
position: absolute;
width: 0px;
height: 5px;
background-color: white;
}
<section id="skin" >
<video width=640px height=360px id="video" >
<source src="e:\dc\SampleVideo_1080x720_5mb.mp4" type="video/mp4"/>
</video>
<nav>
<div id="buttons">
<button type="button" id="playbutton">play</button>
</div>
<div id="defaultBar">
<div id="progressbar"></div>
</div>
<div style="clear:both" ></div>
</nav>
</section>
What is wrong? What do I need to fix to make it work?
There are two errors that make this not work:
JavaScript is a case sensitive language, and you are not using the right syntax for the keyword if (you wrote If in two different places):
if( !video.paused && !video.ended){
The same way that you are adding the event name between quotes in the addEventListener for the load event, you need to do the same for the click event:
playbutton.addEventListener("click", PlayOrPause ,false);
defaultBar.addEventListener("click", clickedBar ,false);
Once you fix those two things, it will work. Here is the code with the corrections:
function dofirst() {
barSize = 500;
video = document.getElementById('video');
playbutton = document.getElementById('playbutton');
defaultBar = document.getElementById('defaultBar');
progressbar = document.getElementById('progressbar');
playbutton.addEventListener("click", PlayOrPause ,false);
defaultBar.addEventListener("click", clickedBar ,false);
}
function PlayOrPause() {
if( !video.paused && !video.ended){
video.pause();
playbutton.innerHTML = 'play';
window.clearInterval(updatebar);
} else {
video.play();
playbutton.innerHTML = 'pause';
updatebar = setInterval(update,500);
}
}
function update(){
if(!video.ended){
var size= parseInt(video.currentTime*barsize/video.duration);
progressbar.style.width = size +'px';
} else {
progressbar.style.width ='0px';
playbutton.innerHTML = 'play';
window.clearInterval(updatebar);
}
}
function clickedBar(e) {
if( !video.paused && !video.ended){
var mouseX = e.pageX-bar.offsetLeft;
var newtiem = mouseX*video.duration/barSize;
myMovie.currentTime = newtime;
progressbar.style.width = mouseX+'px';
}
}
window.addEventListener('load',dofirst,false);
body {
text-align: center;
}
#skin {
background: #5C6366;
width: 700px;
margin: 10px auto;
padding: 50px;
border: 2px black auto;
border-radius: 30px;
}
nav {
margin: 2px 0px;
}
#buttons {
float: left;
width: 70px;
height: 20px;
margin-left: 20px;/* 90px total 610 remaining*/
}
#defaultBar {
margin-top: 5px;
position: relative;
width: 500px;
float : left;
height: 5px;
background-color: black;
}
#progressbar {
position: absolute;
width: 0px;
height: 5px;
background-color: white;
}
<section id="skin" >
<video width=640px height=360px id="video" >
<source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4"/>
</video>
<nav>
<div id="buttons">
<button type="button" id="playbutton">play</button>
</div>
<div id="defaultBar">
<div id="progressbar"></div>
</div>
<div style="clear:both" ></div>
</nav>
</section>
Note: I updated the video path to one that was actually available online to show that the video works after the changes specified above.