Trouble with HTML5 audio loop - javascript

I'm having trouble getting HTML5 audio to loop on my website: http://oclock.webs.com.
(It's an alarm which, when the alarm goes off, is supposed to loop a 1 second alarm sound over and over until you click OK on the alert box).
Simply including "loop" in the audio tag wasn't doing anything.
I found a helpful post on StackOverflow which lead me to this website: http://forestmist.org/2010/04/html5-audio-loops/
I knew Method 1 and 2 wouldn't work for me since they don't work on Firefox and are iffy on Chrome, and so Method 3 should have worked, unfortunately it didn't. Method 3 works when I'm on that website's page, but not when the code is included in my own page so I think there may be some conflicting code.
Relevant part of my webpage:
<audio id="audio1" preload>
<source src="media/alarm.ogg" type="audio/ogg" />
<source src="media/alarm.mp3" type="audio/mpeg" />
</audio>
<audio id="audio2" preload>
<source src="media/alarm.ogg" type="audio/ogg" />
<source src="media/alarm.mp3" type="audio/mpeg" />
</audio>
Relevant Javascript of the page:
if(timer==true && hours==hv && mins==mv && secs==sv){
document.getElementById("audio1").play();
alert("o'clock: Alarm ringing!");
document.getElementById("alarm").value="Set Alarm";
document.getElementById('audio1').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio2').play();
}, false);
document.getElementById('audio2').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio1').play();
}, false);
}
else{
document.getElementById("audio1").pause();
document.getElementById("audio2").pause();
document.getElementById("audio1").currentTime = 0;
document.getElementById("audio2").currentTime = 0;
}
Intention: Upon the computer's time matching that of the selected time on the page, the audio alarm will repeat (loop) until the user clicks OK on the alert box popup.
Problem: Currently it only plays through the audio once, it doesn't loop. Where did I mess up?

"ended event" or "loop" property dose not work on some browsers.
So I used window.setInterval() for looping audio playing.
For this method, you should know play time of Audio file in advanced.
function playAudioWithLoop (/**HTMLAudioElement*/audio, /**Number*/length)
{
function onEnd (){
audio.play();
}
/* length is msec */
if(length > 0) {
audio.__timer = window.setInterval(onEnd, length);
}
}
function stopAudioWithLoop (/**HTMLAudioElement*/audio)
{
if(audio.__timer) {
audio.__timer = window.clearInterval(audio.__timer);
}
}
======================================================================
***playAudioWithLoop(document.getElementById("audio1"), 12*1000);***
***stopAudioWithLoop(document.getElementById("audio1"));***

Related

Button when clicked changes audio track and mute every other audio

The goal is to make many buttons with different audio playing when clicked. Every time user is clicking on one button, it is toggling audio. If non-playing button for different audio is pressed, first audio stops and only after that 2nd one plays.
At this moment there are 2 buttons, everything almost working fine, except when 'B' audio has class 'playing' and you click on 1st audio button class won't remove from the 2nd one and they start to play simultaneously.
How is possible to make stop audio instead of pause when clicked on any of the button?
<script>
function play(chord) {
var audio = document.getElementById(chord);
var active = document.querySelector('.playing');
var everyAudio = document.querySelector('audio');
if(audio.classList.contains('playing')){
audio.pause();
}else {
everyAudio.pause();
everyAudio.classList.remove('playing');
audio.play();
}
audio.classList.toggle('playing');
}
</script>
<input type="button" value="C Major" onclick="play('C')">
<audio id="C">
<source src="Tveice_A_09.09.wav" type="audio/wav">
</audio>
<input type="button" value="B Major" onclick="play('B')">
<audio id="B">
<source src="Black_sand_cello1_raw.wav" type="audio/wav">
</audio>
Thank you for the answer on the first question. With your advice, toggling started to work:
var everyAudio = document.querySelectorAll('audio');
if(audio.classList.contains('playing')){
audio.pause();
}else{
for (var i = 0; i < everyAudio.length; i++){
everyAudio[i].classList.remove('playing');
everyAudio[i].pause();
}
audio.play();
}
Instead of using document.querySelector use document.querySelectorAll - the latter will return an array of elements, the prior will only return 1 element.
More info on document.querySelectorAll
The following may be the cause.
var everyAudio = document.querySelector('audio');
querySelector returns only one element.
Please use querySelectorAll to get the array.
Call pause for each of them.
First question was answered thanks to your advices to use document.querySelectorAll instead of document.querySelector, and then check whole array. Thank you!
For second question I've found solution by myself. Simply need to use audio currentTime audio parameter. So it looks like this in the end.
<script>
function play(chord) {
var audio = document.getElementById(chord);
var active = document.querySelector('.playing');
var everyAudio = document.querySelectorAll('audio');
if(audio.classList.contains('playing')){
audio.pause();
}else{
for (var i = 0; i < everyAudio.length; i++){
everyAudio[i].classList.remove('playing');
everyAudio[i].pause();
everyAudio[i].currentTime = 0;
}
audio.play();
}
audio.classList.toggle('playing');
}
</script>
<input type="button" value="C Major" onclick="play('C')">
<audio id="C">
<source src="Tveice_A_09.09.wav" type="audio/wav">
</audio>
<input type="button" value="B Major" onclick="play('B')">
<audio id="B">
<source src="Black_sand_cello1_raw.wav" type="audio/wav">
</audio>

How to hide text before video ends with javascript

I have video and text that I am displaying when user clicks play button (4 seconds). So my code looks like this:
$('video').on('play', function (e) {
$('#showText').delay(4000).show(0);
});
What I am trying to achieve is hide this text (#showText) 5 seconds before the end of the video. I didn’t find any solution for this, so if anybody can help with this I’ll be more than thankful.
To make this work you can use the standard events associated with media elements. Specifically play and timeupdate. The former you've already covered. The latter fires as the playback progresses. You can use it to check the current position and determine if it's less than 5 seconds from the end, like this:
var $showText = $('#showText');
$('video').on({
play: function() {
$showText.delay(4000).show(0);
},
timeupdate: function(e) {
if ((this.duration - this.currentTime) < 5 && $showText.is(':visible'))
$showText.hide();
}
});
#showText {
display: none;
}
video {
height: 175px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="showText">Lorem ipsum</p>
<video autobuffer controls autoplay>
<source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
You can use video.js to get length of video then you can hide any element at any second before video is ending
var myPlayer = videojs('example_video_1'); //defining videojs
<video id="example_video_1" data-setup="{}" controls="">
<source src="my-source.mp4" type="video/mp4">
</video> //end defining videojs
$('#showText').delay(4000).show(0);
var lengthOfVideo = myPlayer.duration(); // length Of Video in seconds
$(#showText).oneTime(lengthOfVideo-5, function() { // 5 second before video ends
$("showText").hide();
});

Stop playing ( not pause ) HTML5 video on mouseout

Is there any way we can make a HTML5 video to completely stop a video on mouseout?
By stop I mean resetting the video state, just as refreshing the page. All I could get is having the video on pause on mouseout, but this is not what I want.
Thank you.
jsbin:
https://jsbin.com/fenixinuku/edit?html,css,js,output
HTML:
<video class="myvideo" src="http://vjs.zencdn.net/v/oceans.mp4" width="auto" height="auto" alt=""></video>
JS:
$(document).ready(function() {
$(".myvideo").on("mouseover", function(event) {
$(this).get(0).play();
}).on('mouseout', function(event) {
$(this).get(0).pause();
});
})
EDIT:
Thank you guys, based on your answers I made an alternative to this by displaying the video poster as the first frame ( Thank you Terence Eden for suggestion).
The only small issue is that the image poster is flickering on mouseout..Any better solution ?
HTML:
<video class="myvideo" src="http://vjs.zencdn.net/v/oceans.mp4" width="auto" height="auto" alt="" poster="https://www.w3schools.com/images/w3html5.gif"></video>
JS:
$(document).ready(function() {
$(".myvideo").on("mouseover", function(event) {
$(this).get(0).play();
}).on('mouseout', function(event) {
this.load();
});
})
demo 2 jsbin: https://jsbin.com/kivisutici/1/edit?html,css,js,output
Removing the video src property and adding it again should work. Try this inside the mouseout event:
var video = $(this).get(0);
var source = video.src;
video.src = "";
video.src = source;
You can do two things.
First, set the current time to 0.
$(this).get(0).currentTime = 0;
That returns the player position to 0 mins, 0 seconds - as though you had refreshed the page.
Secondly, you can set the poster for the video. By default this is the first frame of the video - but you can set it to any external JPG that you want.
You need to change you mouseout to this
.on('mouseout', function(event) {
$(this).get(0).currentTime = 0
$(this).get(0).pause();
});
Demo
Please try the following and let me know if it worked for you.
// Link here: https://www.w3schools.com/tags/av_prop_currenttime.asp
$(".myvideo"). mouseout(function() {
$(this).get(0).currentTime = 0;
});
or
$(".myvideo"). mouseout(function() {
$(this).currentTime = 0;
});
This is the sample code for stop video, using pause function on mouse-out in HTML5.
<script>
function testover(e)
{
//e.src="movie.mp4";
e.play();
}
function testout(ee)
{
ee.pause();
ee.currentTime =0;
//ee.src=null;
}
</script>
<video width="320" height="240" onmouseover="testover(this)" onmouseout="testout(this)" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
Please neglect if it is not useful.

Sequential playback of audio files overlap using .addEventListener ended

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.

Setting options dynamically for video.js

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

Categories