How to automatically play next song in HTML5 player - javascript

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.

Related

how can the audio going to play if the code given is correct on js

i am currently practicing my html and js skills and i have this code which is when i click the unlock button the audio will automatically play but the problem is even the unlock code is wrong the audio will still play this is my html on the button and on the audio
the audio tag:
<audio id="music" src="bgmusic.mp3" controls hidden loop></audio>
the button tag:
<button id="unlock" class="round pink" onclick="playAudio()">
Unlock
</button>
and here's my current js for the onlick event on the button
var x =
document.getElementById("music");
function playAudio() {
x.play();
}
that is my current syntax but what i want to happen is when the audio will only play if i enter the correct code
and here's the js function for the unlock code functionality:
var number = 0;
$('#unlock').on('click', function(event) {
event.preventDefault();
event.stopPropagation();
$('#textMachine').css('display', 'inline-block');
var code = '';
$.each($('.code'), function(i, v) {
code += $(v).val();
});
if(code == '30')
{
// success
var machine = $('#textMachine').slotMachine({
active: 0,
delay: 500,
randomize : function(activeElementIndex){
return 3;
}
});
machine.setRandomize(3);
machine.shuffle(5, function(){
answerCorrect();
});
} else {
if(number == 3) { number = 0; }
// fail
var machine = $('#textMachine').slotMachine({
active: 1,
delay: 500,
randomize : function(activeElementIndex){
return number;
}
});
machine.shuffle(5, function(){
number++;
});
}
});
var answerCorrect = function() {
$('.login-form').fadeOut();
$('.congratulation-text').fadeIn();
$('.success-area').css('display','block');
};
})();
well actually you can do this
function playSound () {
var audio = new Audio('audio_file.mp3');
audio.play();
}
and you can call it on your button or your function

Index of object and play next with youtube api

I am using the youtube api to search for youtube videos. The videos will then be displayed on #searchBar with the video id ex. NJNlqeMM8Ns as data-video. I get the video id by pressing on a img:
<img data-video = "{{videoid}}" src = "bilder/play.png" alt = "play" class = "knapp" width = "40" height = "40">
Which in my poorly understanding of javascript becomes (this).
When I search for videos I will get more than one result which means that I will get more than one img tag.
In this case I want to play the next song when the first one is finished. I tried to get the index when I pressed on my img tag:
$(".knapp").click(function(){
var index = $(".knapp").index(this);
alert(index);
});
However, when I alerted the index after the video was finshed I always got the value 0 back.
So I thought I could do something like this:
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED){
playNext();
}
}
$('#searchBar').on('click', '[data-video]', function(){
player.current_video = $(this).attr('data-video');
playVideo();
});
function playVideo(){
var video_id = player.current_video;
player.loadVideoById(video_id, 0, "large");
}
function playNext(){
var player.current_videon = **$(this + 1).attr('data-video');**
var next_id = player.current_videon;
player.loadVideoById(next_id, 0, "large");
}
But I'm not sure how to make it work, as you can see in the bold section, can I solve my problem like this or do I need another approach?
Edit:
With some research I found out that I need to set the value of the current video being played and also efter the video was done playing I add this number by 1.
However even if it did make the next video play, I was unable to chose which song I wanted anymore...
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED){
player.current_video++;
playVideo();
}
}
var player = document.querySelector('iframe');
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '40mSZPyqpag',
playerVars: {rel: 0},
events: {
'onStateChange': onPlayerStateChange
}
});
player.current_video = 0;
}
$('#searchBar').on('click', '[data-video]', function(){
player.current_video = $(this).index();
alert(player.current_video);
playVideo();
});
function playVideo(){
var video_id = $('[data-video]').eq(player.current_video).attr('data-video');
player.loadVideoById(video_id, 0, "large");
}
Here is a working PEN (click to RUN)
The solution is based on a global currentSongIndex index, without facilitating next()
var currentSongIndex = null;
$(".knapp").click(function () {
var index = $(this).attr('data-video');
playVideo(index);
});
function playVideo(index) {
console.log("Playing song INDEX: " + index);
currentSongIndex = index;
playNext();
}
function playNext() {
currentSongIndex++;
let nextSongIndex = $('img[data-video="' + currentSongIndex + '"]').attr('data-video');
console.log("Next song INDEX: " + nextSongIndex);
if(typeof nextSongIndex != "undefined") {
playVideo(nextSongIndex);
} else {
console.log('end of list... you can play from index 1 or whatever....');
}
}
I got a suggestion to get player.current_video by the closest li index, so I made an update to my data-video img tag.
<li class = liItem>
<img data-video = "{{videoid}}" src = "bilder/play.png" alt = "play" class = "knapp" width = "40" height = "40">
</li>
Then I changed the index on my click function in my edited example:
$('#searchBar').on('click', '[data-video]', function(){
player.current_video = $(this).closest('li').index();
playVideo();
});
With this new fuction I was able to chose and play the next song!
Shoutout to #cale_b for providing me with the .closest('li') suggestion.

HTMLMediaElement.duration returning NaN for audio file

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.

Multiple videos playing at once Jquery

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');
}
});
});

Start and stop with the same div (javascript-jquery)

I want to start and stop an animation when click on the same div.
$('div').click(function(){
//if is the first click -->do animation in loop
//if is the second click--->stop animation
});
How do u do it?
I had resolve only the animation start with loop:
var play = 0;
function myAnimateGreen(){
$('green').animate(
{left:'+250px'},
1000,
);
while(play==1) {myAnimateGreen();}
}
$('green').click(function(){
play = 1;
myAnimateGreen();}
});
But I can't resolve the stop!
You can use the :animated selector to detect if the animation is currently happening
$('div').click(function(){
if( !$(".green").is(':animated') ) {
//Do animation
} else {
//Stop animation
}
});
function animateGreen(el) {
var delay = 500,
time = 1000,
distance = 150;
el.animate({left:'+='+distance+'px'}, time, "linear");
el.data("anim_green", setTimeout(animateGreen, time+delay, el));
}
$('green').click(function() {
var self = $(this);
if (self.data("anim_green")) {
clearTimeout(self.data("anim_green"));
self.data("anim_green", false);
return;
}
animateGreen(self);
});
Should do it, just paste! Proof: http://jsbin.com/ajagij/3/edit

Categories

Resources