Everything in my code works. It just doesn't switch to the next song/video after finishing the current one. I have tried adding an onended event handler (in the tag and in JavaScript) but failed. I also tried jQuery but it did't work. For some reasons it doesn't change songs at the end of the song. Instead, it will replay the same song over and over again.
<video id="vid" src="main/" playsinline autoplay loop>
<script>
var video = document.currentScript.parentElement;
video.volume = 0.1;
var lastSong = null;
var selection = null;
var playlist = ["main/songn.mp4", "main/songl.mp4", "/main/songt.mp4", "/main/songf.mp4"]; // List of Songs
var video = document.getElementById("vid");
video.autoplay=true;
video.addEventListener("ended", selectRandom);
function selectRandom(){
while(selection == lastSong){
selection = Math.floor(Math.random() * playlist.length);
}
lastSong = selection;
video.src = playlist[selection];
}
selectRandom();
video.play();
</script>
</video>
You just need to remove the loop parameter from the video tag if you want to trigger the end event (doc):
<video id="vid" src="main/" playsinline autoplay>
(Your code will handle the loop by loading a new song when one ended.)
BTW, keep var video = document.getElementById("vid"); to refer to your <video> tag, it's shorter and cleaner than the first declaration.
Related
I am trying to create an HTML video playlist and currently I am using vid.onended to detect when a video is done playing (based of the current video src) and then play the next video when the video ends. This works perfectly for the first video but for some reason it never plays the second video and jumps straight to the third video.
My code:
//add video playlist functionality to auto play next video based on id
var vid = document.getElementById("urlVideo");
vid.onended = function() {
var video0 = "http://techslides.com/demos/sample-videos/small.mp4";
var video1 = "https://media.w3.org/2010/05/sintel/trailer.mp4";
var video2 = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
if (vid.src = video0) {
vid.src = video1;
}
if (vid.src = video1) {
vid.src = video2;
}
};
<video id="urlVideo" width="100%" height="460" controls autoplay>
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
What am I doing wrong?
Edit:
Answer by Alen Toma works perfectly.
I Also managed to do it according to the current video source based on a comment by Quentin, For anyone else looking for how to do it explicitly with the current video source as the variable/condition, please see
https://jsfiddle.net/redlaw/qjb5h7e9/9/
I did make a small example below, it should help.
Have a look at this JSFiddle.
//add video playlist functionality to auto play next video based on id
var videoSrc = [
"https://media.w3.org/2010/05/sintel/trailer.mp4",
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
]
var vid = document.getElementById("urlVideo");
var index = 0;
vid.addEventListener("ended", function() {
var currentSrc = videoSrc[index];
index += 1;
if (index >= videoSrc.length)
index = 0; // Make Loop and jump to the first video
vid.src = currentSrc;
vid.play();
console.log(currentSrc)
}, true);
<video id="urlVideo" controls autoplay>
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>
you must use an event listener for your video player like this code:
var vid = document.getElementById("urlVideo");
vid.addEventListener("ended", function() { /* your code*/ }, true);
Is there any way to play a video in html5, stop and execute javascript at known points within the video?
Yes, try this. You have to use the currentTime property. Start with that and start your javascript functions from there. Is that what you're looking for?
var vid = document.getElementById("video");
//Add a timeupdate listener
video.addEventListener("timeupdate", function(){
//Check for video properties from within the function
if (this.currentTime == 5)
this.pause();
//cal javascript
}
}
Looking at the accepted answer over here it looks like it is possible.
To pause the video you just do this:
var mediaElement = document.getElementById("video"); // create a reference to your HTML5 video
mediaElement.pause(); // pauses the video
If you want to play the video, do this:
mediaElement.play(); // plays the video
To get the current time in the video, do this:
mediaElement.currentTime; // gets the current time
Here's an example linking them all up:
var mediaElement = document.getElementById("video");
if(mediaElement.currentTime == 35){
mediaElement.pause();
// do whatever else you would like
mediaElement.play();
}
The MDL documentation is here, there are plenty of other properties you might find helpful.
Hope this helps!
Yes, by doing like this you can.
Note that you have to look for a time using bigger than > bigger than (as the chance to match an exact millisecond is almost zero), and have a variable in one way or the other to know which ones is done.
window.addEventListener('load', function() {
var cur = document.querySelector('#cur'),
vid = document.querySelector('#vid')
})
var appDone = {"done7":false,"done4":false}
vid.addEventListener('timeupdate', function(e) {
if (e.target.currentTime > 7 && !appDone.done7) {
appDone.done7 = true;
e.target.pause();
//do something
cur.textContent += ", " + "done7 once";
e.target.play();
}
if (e.target.currentTime > 4 && !appDone.done4) {
appDone.done4 = true;
e.target.pause();
//do something
cur.textContent += ", " + "done4 once";
e.target.play();
}
})
<video id="vid" width="320" height="176" controls>
<source src="http://www.w3schools.com/tags/mov_bbb.mp4" type="video/mp4">
<source src="http://www.w3schools.com/tags/mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
<p id="cur"></p>
I'm trying to use a button to change the audio track to 1 of 2 being played in the browser, however, the method I found switches to the second track but doesn't change the audio played afterwards, it only restarts the second track. Here's my code:
function loadSong(){
var player=document.getElementById('player');
var source1=document.getElementById('player');
var source2=document.getElementById('player');
source1.src='/audio/mac+.mp3';
source2.src='/audio/mac-slowed.mp3';
player.load(); //just start buffering (preload)
player.play(); //start playing
}
HTML
<audio id="player" autoplay="autoplay" preload="auto" loop="loop">
<source id="source1" src="/audio/mac+.mp3" type="audio/mpeg">
<source id="source2" src="" type="audio/mpeg">
</audio>
<button onclick='loadSong()'>Switch the Music!</button>
Based on the information you provided in your original inquiry, this is most likely the best fit for you. Attached is a working JSFiddle for you review. You will need to update the src files with your own locally stored files.
HTML:
<audio id="source1" autoplay="autoplay" loop="loop" src='http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3'></audio>
<audio id="source2" loop="loop" src='http://www.stephaniequinn.com/Music/Pachelbel%20-%20Canon%20in%20D%20Major.mp3'></audio>
<button id="player">Switch the music to track # 2</button>
Javascript:
var player = document.getElementById('player');
var source1 = document.getElementById('source1');
var source2 = document.getElementById('source2');
player.onclick = function() {
curTrack = this.innerHTML.replace(/Switch the music to track # /, "");
if (curTrack == "1") {
nextTrack = "2";
source1.play();
source2.pause();
source2.currentTime = 0;
} else {
nextTrack = "1";
source2.play();
source1.pause();
source1.currentTime = 0;
}
this.innerHTML = "Switch the music to track # " + nextTrack;
}
You are overwriting the #player element look at your code you are saving the same selector to source1 and source 2 so change the selector of source one to source1 and source2
The following code is intended to play a series of short audio files in a sequence, as held in a javascript array named audio_sequence.
an .addEventListener('ended',function()) is used to trigger playback of each audio clip in the sequence.
This works as expected for the first 5 items in the array, playing each in turn, but then the audio elements start to play simultaneously and the sequence becomes jumbled.
I have tried several different approaches all yielding similar results.
Would very much appreciate any insights.
And example of the code running can be found here:
Play Sequence
Here's the javascript:
<script type="text/javascript">
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
}, true);
audioElement.play();
}
}
function playSequence(){
sequence_position = 0;
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
},true);
audioElement.play();
}
</script>
& the html is as follows:
<a onClick="javascript:playSequence();" href="#"><h2>Play Sequence</h2></a>
<audio hidden id="rooms" preload="auto">
<source src="/audio/rooms.mp3">
</audio>
<audio hidden id="food" preload="auto">
<source src="/audio/food.mp3" >
</audio>
<audio hidden id="bars" preload="auto">
<source src="/audio/bars.mp3">
</audio>
<audio hidden id="inveraray" preload="auto">
<source src="/audio/inveraray.mp3">
</audio>
<audio hidden id="arse" preload="auto">
<source src="/audio/arse.mp3">
</audio>
What is causing the problem is that you are attaching the same event listener several times to each element, as they are in a loop. In a non particularly elegant but effective workaround, you could remove the listener before attaching it again:
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
playSequence();
}
}
function playSequence(){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.removeEventListener('ended', prepareNextAudio);
audioElement.addEventListener('ended', prepareNextAudio, true);
audioElement.play();
}
function prepareNextAudio() {
sequence_position++;
play_next();
}
This code works and stops the playlist when each audio has been played for three times, which I guess is what you needed.
I am building a player logic that loads a movie, plays it to the end, reacts to the "ended" event and sets a new source, that has to be looped until the user interacts. Then, film2 gets played and "switches into loop" as well so i'm loading another src and setting options to loop for the loop.
I just couldn't get it to work.
Here is my code:
<video id="video_1" preload="auto" width="100%" height="100%">
<source src="video/dummy/dummy_film1.mp4" type='video/mp4'>
</video>
And here is my js:
function initialVideoFinished(){
_myPlayer.off('ended', initialVideoFinished);
console.log('video1 finished - video js READY');
console.log('myPlayer id == ' + _myPlayer);
_V_('video_1', {'loop' : 'true'});
_myPlayer.src('video/dummy/dummy_loop1.mp4');
_myPlayer.play();
ni_resize();
}
I tried a lot of variations. Loop in "" or without or _myPlayer.loop = true; V(...) oder just videojs(..) but the new video src never loops.
I also tried replacing the whole tag. This works, but then I lose my reference to the player object.
How can I do this?
You can use loop(true):
var myPlayer = videojs("my_video_1");
function initialVideoFinished(event) {
console.log("end");
myPlayer.off('ended', initialVideoFinished);
myPlayer.src("http://example.com/newsource.mp4");
myPlayer.loop(true);
myPlayer.play();
}
myPlayer.on('ended', initialVideoFinished);