I've a script that changes the play button on vimeo vids but it seems to activate all the videos on my site at the same time and not individually. I've added unique player_id=video player_id=video1, etc. You can see it live here (http://imdarrien.com/#modal2). Just click on a video and you can hear the audio play for all other videos I have.
https://jsfiddle.net/uxhxdcwp/5/
$(function () {
var iframe = document.getElementById('video');
var player = $f(iframe);
player.addEvent('ready', function () {
player.addEvent('finish', onFinish);
});
$('.playpause').click(function () {
player.api('paused', function (paused) {
if (!paused) {
player.api('pause');
$(".playpause").removeClass('pause');
} else {
player.api('play');
$(".playpause").addClass('pause');
}
});
});
function onFinish(id) {
$(".playpause").removeClass('pause');
}
});
Make sure you're only taking action on the relevant video with selectors!
$('.playpause').click(function () {
var el = $(this);
var player = $f( $(this).siblings('iframe')[0] );
player.api('paused', function (paused) {
if (!paused) {
player.api('pause');
el.removeClass('pause');
} else {
player.api('play');
el.addClass('pause');
}
});
});
Related
I would like to play through Vimeo videos in sequence with JavaScript with continuous playback and looping through items. The following code moves to the second video at the end of the first but the same functions are not called at the end of the second video. Only the end of the first video shows Called! in the Javascript console, not the end of the second.
The Vimeo Player SDK has player.getVideoId() but not player.setVideoId() so I used a hack to load the next video: setting the source of the iframe and starting the Vimeo player anew. I wonder if this is the problem and the listener for the end of the video is attached to the discarded player.
Another issue with this code is that it exits fullscreen to load the next video.
I attempted this CodePen that sets the Vimeo Player on any element instead of an iframe and was unable to change the played video.
What is a cleaner or effective way of changing videos with the Vimeo Player SDK?
The HTML is:
<div class="vimeo">
<div class="resp-iframe-container container-centered">
<iframe class="resp-iframe" scrolling="no" frameborder="no" src="https://player.vimeo.com/video/238301525" allowfullscreen="" data-ready="true"></iframe></div></div>
And the javascript is:
var l = ["238301525", "496371201", "238301525", "496371201", "..."];
window.current = 0;
var increment = function() {
window.current += 1;
if (window.current == l.length) {
window.current = 0;
}
};
var decrement = function() {
window.current -= 1;
if (window.current < 0) {
window.current = l.length - 1;
}
};
prevA.addEventListener("click", function() {
decrement();
loadPlayer();
});
nextA.addEventListener("click", function() {
increment();
console.log("here!");
loadPlayer();
console.log("there!");
});
var loadPlayer = function() {
console.log("Called!");
var iframe = document.querySelector('iframe');
iframe.src = "https://player.vimeo.com/video/" + l[window.current];
var player = new Vimeo.Player(iframe);
player.autoplay = true;
var treatEvent = function(data, eventLabel) {
// Custom code...
if ("end" == eventLabel) {
console.log("incrementing automatically");
increment();
loadPlayer();
}
};
var onPlay = function(data) {
treatEvent(data, "play");
}
var onPause = function(data) {
treatEvent(data, "pause");
}
var onSeeked = function(data) {
treatEvent(data, "seeked");
}
var onEnd = function(data) {
treatEvent(data, "end");
}
player.on('play', onPlay);
player.on('pause', onPause);
player.on('seeked', onSeeked);
player.on('ended', onEnd);
setTimeout(function() {
//console.log("Trying to play...");
player.play().then(function() {
// the video was played
console.log("success: video played");
}).catch(function(error) {
console.log("Error! " + error.name);
});
}, 1000);
}
loadPlayer();
It seems that the Vimeo Player keeps track of whether it was initialized, adding a tag data-vimeo-initialized="true" in the HTML element.
One solution is to use the Vimeo Player SDK function .loadVideo():
var song_iframe = document.querySelector("iframe#song_video");
var song_player = new Vimeo.Player(song_iframe);
var on_song_end = function(data) {
// Logic to get the new id.
song_player.loadVideo(newId).then(function() {
song_player.play();
});
};
song_player.on("ended", on_song_end);
I'm trying to play videos one after the other in the same Vimeo player, without success.
This is the code I'm working on. I can't find any example on how to do that.
I'm sure I'm wrong but I don't know how to go further...
var iframe = document.querySelector('iframe.main-player');
var player = new Vimeo.Player(iframe);
var video_ids = ['123456789', '987654321'];
video_ids.forEach(function(item, index) {
player.pause();
player.loadVideo(item);
player.on('loaded', function() {
player.play();
});
})
I'm not sure about this, because can't test it right now , but you can try something like this:
var iframe = document.querySelector('iframe.main-player');
var player = new Vimeo.Player(iframe);
var video_ids = ['123456789', '987654321'];
var index = 0;
var playNext = function(data){
player.pause();
if(index<=video_ids.length)
player.loadVideo(video_ids[index++])
}
player.pause();
player.loadVideo(video_ids[index++]);
player.on('loaded', function() {
player.play();
});
player.on('ended', playNext);
The idea is pretty simple by listen to the ended event then moving to the next item.
First of all, we just create a class to hold some information such as the list & current playing index:
import Player from "#vimeo/player";
class Playlist {
constructor(playlist) {
this.playlist = playlist;
this.currentIdx = 0;
}
init() {
this.player = new Player("app", {
id: this.currentItem,
width: 640
});
this.player.on("ended", this.onEnded.bind(this));
}
onEnded() {
if (this.currentIdx < this.playlist.length) {
this.currentIdx++;
const nextId = this.currentItem;
this.player.loadVideo(nextId);
// Check next item has loaded then play it automatically
// you might not receive any error in case of having to interact with document
this.player.on("loaded", () => {
this.player.play();
});
}
}
get currentItem() {
return this.playlist[this.currentIdx];
}
}
// Try to run 2 items
const pl = new Playlist([59777392, 28582484]);
pl.init();
NOTE: I also created a codesandbox link for you here https://codesandbox.io/s/focused-firefly-ej0fd?file=/src/index.js
I'm working on an online radio website and am trying to detect what state the audio player is currently in for the user.
The current setup I've got is often wrong in knowing this and if I'm on iOS and I pause from the lock screen player instead, it will still think it's playing because I never clicked the html pause button.
Finally how is it possible to detect when my stream has fully ended. I've tried: onstalled="", onwaiting="", onerror="", onended="". But none of them work 100% of the time. The closest one to work would be: onstalled="", but even that only had a 60% success rate or so (occasionally when I'm loading the site it would tell me it has ended).
HTML:
<audio autoplay="" id="player" title="" oncanplay="radioLoaded()">
<source src="...">
</audio>
Javascript:
function radioLoaded() {
if (player.paused) {
document.getElementById('radioplaypause').innerHTML = varRadioResume;
} else if (player.play) {
document.getElementById('radioplaypause').innerHTML = varRadioPause;
} else {
document.getElementById('radioplaypause').innerHTML = varRadioLoading;
}
window.player = document.getElementById('player');
document.getElementById('radioplaypause').onclick = function () {
if (player.paused) {
player.play();
this.innerHTML = varRadioPause;
} else {
player.pause();
this.innerHTML = varRadioResume;
}
}
};
function radioEnded() {
document.getElementById('radiolivetext').innerHTML = 'OFFLINE';
document.getElementById('radioplayer').style.display = 'none';
document.getElementById('radioinformation').style.display = 'none';
};
Try this, with some corrections/notes to the code in general:
function radioLoaded() {
// move this line to the top
window.player = document.getElementById('player'); // !!! <-- name too generic, possibility of global collisions
var playPauseButton = document.getElementById('radioplaypause');
if (player.paused) {
playPauseButton.innerHTML = varRadioResume;
} else if (player.play) {
playPauseButton.innerHTML = varRadioPause;
} else {
playPauseButton.innerHTML = varRadioLoading;
}
playPauseButton.onclick = function () {
if (player.paused) {
player.play();
this.innerHTML = varRadioPause;
} else {
player.pause();
this.innerHTML = varRadioResume;
}
};
player.onended = function () {
console.log('ended');
};
// other helpful events
player.onpause = function () {
console.log('paused...');
}
player.onplay = function () {
console.log('playing...');
}
player.onprogress = function (e) {
console.log(e.loaded + ' of ' + e.total + ' loaded');
}
};
I have the following JavaScript to play a sound when a button is clicked on the screen, however I'm only getting NaN for the duration.
$(document).ready(function() {
function play_sound() {
var audio = new Audio("assets/sound.ogg");
audio.play();
var duration = audio.duration;
console.log(duration);
}
$(document).on("click", ".box", function(e) {
play_sound();
});
});
In my research I found this answer which uses the "loadeddata" event, however I'm not sure how to incorporate that into my code. Should I use an <audio> element in my HTML?
Here's my shot at it:
$(document).ready(function() {
function play_sound() {
var audio = new Audio("assets/sound.ogg");
audio.addEventListener("loadedmetadata", function(_event) {
var duration = audio.duration;
console.log(duration);
});
audio.play();
}
$(document).on("click", ".box", function(e) {
play_sound();
});
});
http://jsfiddle.net/x2pe6hcf/1/
Added the eventListener and it works perfectly.
I have a html5 audio player and I cant seem to figure out how to make my script automatically play the next song on the playlist after the current song has ended. Currently the player plays a song then stops. It would also be ideal that the player auto play a song if the user hits the fast forward button as well.
Here is my JS code:
jQuery(document).ready(function() {
// inner variables
var song;
var tracker = $('.tracker');
var volume = $('.volume');
function initAudio(elem) {
var url = elem.attr('audiourl');
var title = elem.text();
var cover = elem.attr('cover');
var artist = elem.attr('artist');
$('.player .title').text(title);
$('.player .artist').text(artist);
$('.player .cover').css('background-image','url(' + cover+')');;
song = new Audio(url);
// timeupdate event listener
song.addEventListener('timeupdate',function (){
var curtime = parseInt(song.currentTime, 10);
tracker.slider('value', curtime);
});
$('.playlist li').removeClass('active');
elem.addClass('active');
playAudio();
}
function playAudio() {
song.play();
tracker.slider("option", "max", song.duration);
$('.play').addClass('hidden');
$('.pause').addClass('visible');
}
function stopAudio() {
song.pause();
$('.play').removeClass('hidden');
$('.pause').removeClass('visible');
}
// play click
$('.play').click(function (e) {
e.preventDefault();
playAudio();
});
// pause click
$('.pause').click(function (e) {
e.preventDefault();
stopAudio();
});
// forward click
$('.fwd').click(function (e) {
e.preventDefault();
stopAudio();
var next = $('.playlist li.active').next();
if (next.length == 0) {
next = $('.playlist li:first-child');
}
initAudio(next);
});
// rewind click
$('.rew').click(function (e) {
e.preventDefault();
stopAudio();
var prev = $('.playlist li.active').prev();
if (prev.length == 0) {
prev = $('.playlist li:last-child');
}
initAudio(prev);
});
// show playlist
$('.pl').click(function (e) {
e.preventDefault();
$('.playlist').fadeIn(300);
});
// playlist elements - click
$('.playlist li').click(function () {
stopAudio();
initAudio($(this));
});
// initialization - first element in playlist
initAudio($('.playlist li:first-child'));
// set volume
song.volume = 0.8;
// initialize the volume slider
volume.slider({
range: 'min',
min: 1,
max: 100,
value: 80,
start: function(event,ui) {},
slide: function(event, ui) {
song.volume = ui.value / 100;
},
stop: function(event,ui) {},
});
// empty tracker slider
tracker.slider({
range: 'min',
min: 0, max: 10,
start: function(event,ui) {},
slide: function(event, ui) {
song.currentTime = ui.value;
},
stop: function(event,ui) {}
});
});
I wanted to do the same thing, but I wasn't able to for a long while. After looking up several event-listeners, I finally managed to make it work :D
function playAudio() {
song.addEventListener('ended', function () {
var next = $('.playlist li.active').next();
if (next.length == 0) {
next = $('.playlist li:first-child');
}
initAudio(next);
song.addEventListener('loadedmetadata', function () {
playAudio();
});
}, false);
tracker.slider("option", "max", song.duration);
song.play();
$('.play').addClass('hidden');
$('.pause').addClass('visible');
}
Put this as your playAudio function. The first eventlistener loops the song to the next song in the playlist. And the second event listener is for the song.duration which happens to be null (weird) if I don't use this eventlistener.
If you want to make the audio play right after you click the playlist element or the forward/rewind button, then add this to your click playlist function and fwd/rewind function.
song.addEventListener('loadedmetadata', function() {playAudio(); });
Hope this helps!!!! (My first answer to a post :D)
I think the key to this is to listen for (or "bind", in jQuery parlance), the "ended" event on your audio playback tag. This will fire as soon as the media playback has finished. The example that Mystic Magic refers to leverages this, so search that page for "ended" in order to see this in action.