I've got two audio elements on a page:
<audio id="voice1" class="voice1 voice" controls>
<source src="1.mp3" type="audio/mpeg">
</audio>
<audio id="voice1" class="voice2 voice" controls>
<source src="2.mp3" type="audio/mpeg">
</audio>
I want to play the first one, pause for 5 seconds, play the second one, pause for a further 5 seconds then repeat the whole process a fixed number of times.
jQuery(document).ready(function(){
for (j = 0; j < 100; ++j) {
var audioArray = document.getElementsByClassName('voice');
var i = 0;
audioArray[i].play();
for (i = 0; i < audioArray.length - 1; ++i) {
audioArray[i].addEventListener('ended', function(e){
// pause here for 5 seconds
var currentSong = e.target;
var next = $(currentSong).nextAll('audio');
if (next.length) $(next[0]).trigger('play');
});
}
});
I have experimented with setInterval and setTimeout but I can't get this pause to work. I have considered just playing a quiet mp3 file for 5 seconds but this seems daft. Can anyone recommend a suitable approach?
Related
I am currently trying to play another audio if the current audio is finished but I am not getting any success results would be appreciated if any suggestions is given,here is the below code :-
document.addEventListener('DOMContentLoaded', () => {
ms();
});
function ms() {
var btns = document.getElementsByClassName("pas");
for (var j = 0; j < btns.length; j++) {
document.addEventListener('play', function(e) {
var songs = document.getElementsByClassName("pas");
for (var i = 0; i < songs.length; i++) {
if (songs[i] != e.target) {
songs[i].pause();
}
}
}, true);
}
}
<audio class="pas" controls loop autoplay>
<source src="https://www.mboxdrive.com/Drake_-_One_Dance_(Lyrics)_ft._Wizkid_&_Kyla(128k).m4a" type="audio/mp3">
Your browser dose not Support the audio Tag
</audio>
<audio class="pas" controls loop autoplay>
<source src="https://www.mboxdrive.com/Coobie_-_Miss_You_(Official_Lyric_Video)(256k).mp3" type="audio/mp3">
Your browser dose not Support the audio Tag
</audio>
The above js is to allow only one audio to be played once. Anyway possible way to add any function to play another audio if the first one is finished?
You can try code demo here https://jsfiddle.net/mt1koznd/2/
Use the timeupdate event, and the .duration and .currentTime properties. If you intend to switch players, you need to remove the loop attribute and remove the autoplay attribute on all but one or all players will play at the same time. The example will work for an unlimited amount of players and will loop back to the starting player if the current player is the last one.
Details are commented in example
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style></style>
</head>
<body>
<audio class="song" controls>
<source src="https://www.mboxdrive.com/Drake_-_One_Dance_(Lyrics)_ft._Wizkid_&_Kyla(128k).m4a" type="audio/mp3">
</audio>
<audio class="song" controls>
<source src="https://www.mboxdrive.com/Coobie_-_Miss_You_(Official_Lyric_Video)(256k).mp3" type="audio/mp3">
</audio>
<script>
// Collect all .song into a NodeList then convert it into a real array
const songs = [...document.querySelectorAll('.song')];
// Bind the timeupdate event to each .song
songs.forEach(song => song.ontimeupdate = nextSong);
// Event handler
function nextSong(e) {
// Get player's full duration in seconds
const end = this.duration;
// Get the current time spent playing in seconds
let now = this.currentTime;
// If the time playing reaches the duration...
if (end <= now) {
// Get the index position of player
const position = songs.indexOf(this);
// If the player is the last one start play on the first player
if (position === songs.length - 1) {
songs[0].play();
// Otherwise start ply on the next player
} else {
songs[position + 1].play();
}
}
}
</script>
</body>
</html>
I am adding multiple HTML5 videos onto a webpage.
The code I am replicating is from this recommended accessible approach. http://jspro.brothercake.com/audio-descriptions/ The video plays fine, and audio captions work, but when I add a new video to the same page the second video does not play the audio captions at all. Does anyone have suggestions on how I can fix this issue?
<video id="video" preload="auto" controls="controls"
width="640" height="360" poster="./media/HorribleHistories.jpg">
<source src="./media/HorribleHistories.mp4" type="video/mp4" />
<source src="./media/HorribleHistories.webm" type="video/webm" />
</video>
<audio id="audio" preload="auto">
<source src="./media/HorribleHistories.mp3" type="audio/mp3" />
<source src="./media/HorribleHistories.ogg" type="audio/ogg" />
</audio>
<script type="text/javascript">
(function()
{
//get references to the video and audio elements
var video = document.getElementById('video');
var audio = document.getElementById('audio');
//if media controllers are supported,
//create a controller instance for the video and audio
if(typeof(window.MediaController) === 'function')
{
var controller = new MediaController();
audio.controller = controller;
video.controller = controller;
}
//else create a null controller reference for comparison
else
{
controller = null;
}
//reduce the video volume slightly to emphasise the audio
audio.volume = 1;
video.volume = 0.8;
//when the video plays
video.addEventListener('play', function()
{
//if we have audio but no controller
//and the audio is paused, play that too
if(!controller && audio.paused)
{
audio.play();
}
}, false);
//when the video pauses
video.addEventListener('pause', function()
{
//if we have audio but no controller
//and the audio isn't paused, pause that too
if(!controller && !audio.paused)
{
audio.pause();
}
}, false);
//when the video ends
video.addEventListener('ended', function()
{
//if we have a controller, pause that
if(controller)
{
controller.pause();
}
//otherwise pause the video and audio separately
else
{
video.pause();
audio.pause();
}
}, false);
//when the video time is updated
video.addEventListener('timeupdate', function()
{
//if we have audio but no controller,
//and the audio has sufficiently loaded
if(!controller && audio.readyState >= 4)
{
//if the audio and video times are different,
//update the audio time to keep it in sync
if(Math.ceil(audio.currentTime) != Math.ceil(video.currentTime))
{
audio.currentTime = video.currentTime;
}
}
}, false);
})();
</script>
So your problem is to do with how you are grabbing the elements in the first place.
var video = document.getElementById('video');
var audio = document.getElementById('audio');
What you are doing is grabbing a single item on the page with the ID of "video" (same for "audio").
IDs have to be unique, so what you want to do is use classes instead.
<video class="video" preload="auto" controls="controls"
width="640" height="360" poster="./media/HorribleHistories.jpg">
See I changed the ID to a class.
Now any element with the class "video" can be used in our code.
However we do need to modify our code a bit as now we have multiple items to bind to.
please note the below is to give you an idea of how you loop items etc. You would need to rewrite your code to move each of the steps into functions etc. as your original code is not designed to work with multiple items
(function()
{
//get references to every single video and audio element
var videos = document.querySelectorAll('.video');
var audios = document.querySelectorAll('.audio');
// loop through all videos adding logic etc.
for(x = 0; x < videos.length; x++){
// grab a single video from our list to make our code neater
var video = videos[x];
if(typeof(window.MediaController) === 'function')
{
var controller = new MediaController();
video.controller = controller;
} else {
controller = null;
}
video.volume = 0.8;
//...etc.
}
})();
Quick Tip:
I would wrap your <video> and <audio> elements that are related in a <div> with a class (e.g. class="video-audio-wrapper").
This way you can change your CSS selector to something like:
var videoContainers = document.querySelectorAll('.video-audio-wrapper');
Then loop through them instead and check if they have a video and / or audio element
for(x = 0; x < videoContainers.length; x++){
var thisVideoContainer = videoContainers[x];
//query this container only - we can use `querySelector` as there should only be one video per container and that returns a single item / the first item it finds.
var video = thisVideoContainer.querySelector('video');
var audio = thisVideoContainer.querySelector('audio');
//now we can check if an element exists
if(video.length == 1){
//apply video logic
}
if(audio.length == 1){
//apply audio logic
}
// alternatively we can check both exist if we have to have both
if(video.length != 1 || audio.length != 1){
// we either have one or both missing.
// apply any logic for when a video / audio element is missing
//using "return" we can exit the function early, meaning all code after this point is not run.
return false;
}
///The beauty of this approach is you could then just use your original code!
}
Doing it this way you could recycle most of your code.
Thank you for your suggestions in changing the ID's into classes and adding the video wrapper <div> to the video container. That all makes sense in grouping each video on 1 page. I updated the the following code, but the audio captions won't play at all. The video plays and pauses fine, and the volume works. I am also not getting any syntax errors in the browser console. Here's what I got for my HTML and JS. I appreciate your help/feedback.
<div class="video-container-wrapper">
<div class="video-container">
<video class="video" preload="auto" controls="controls" width="640" height="360" poster="img/red-zone-thumb.png">
<source src="https://player.vimeo.com/external/395077086.hd.mp4?s=1514637c1ac308a950fafc00ad46c0a113c6e8be&profile_id=175" type="video/mp4">
<track kind="captions" label="English captions" src="captions/redzone-script.vtt" srclang="en" default="">
</video>
<audio class="audio" preload="auto">
<source src="captions/redzone-message.mp3" type="audio/mp3">
</audio>
</div>
</div>
Javascript:
var videoContainers = document.querySelectorAll('.video-container-wrapper');
for (x = 0; x < videoContainers.length; x++) {
var thisVideoContainer = videoContainers[x];
//query this container only - we can use `querySelector` as there should only be one video per container and that returns a single item / the first item it finds.
var video = thisVideoContainer.querySelector('video');
var audio = thisVideoContainer.querySelector('audio');
//now we can check if an element exists
if (video.length == 1) {
//apply video logic
//reduce the video volume slightly to emphasise the audio
video.volume = 0.8;
//when the video ends
video.addEventListener('ended', function () {
video.pause();
}, false);
}
if (audio.length == 1) {
//apply audio logic
audio.volume = 1;
//when the video plays
video.addEventListener('play', function () {
if (audio.paused) {
audio.play();
}
}, false);
// when the video ends
video.addEventListener('ended', function () {
audio.pause();
}, false);
//when the video time is updated
video.addEventListener('timeupdate', function () {
if (audio.readyState >= 4) {
//if the audio and video times are different,
//update the audio time to keep it in sync
if (Math.ceil(audio.currentTime) != Math.ceil(video.currentTime)) {
audio.currentTime = video.currentTime;
}
}
}, false);
}
}
I have a video in my html. I would like the video to pause at 5 seconds after playing so I used addEventListener. I also have 2 buttons that call either restart() or jump().
When I play my video, an EventListener is called on my video. It pauses at 5 seconds, but I can't get it to play after 5 seconds (I've tried removing the listener but then the video no longer pauses). When I call jump(), it'll take me to 10 seconds but continue to pause when I try to play it. When I call reset(), the video will play up to 5 seconds again, which makes sense since I have a Listener on it. How do I get it to play after 10 seconds for when I call jump()? At first I thought I would have to remove my Listener but I believe I'll need that still because I would like the video to pause at 15 seconds. Or maybe I need to call removeEventListener somewhere else?
js
var video = document.getElementById("myvid");
video.addEventListener("timeupdate", function(){
if(this.currentTime >= 5) {
this.pause();
}
});
function restart(){
video.currentTime = 0;
}
function jump(){
video.currentTime = 10;
if (video.currentTime >=15){
video.pause
}
}
html
<video id="myvid" width="320" height="240" controls>
<source src="video.mp4" type="video/mp4">
</video>
<button onclick="restart()">restart</button>
<button onclick="jump()">jump</button>
You must keep the pause time in a variable. Then you can use it in the jump function:
var video = document.getElementById( 'myvid' ),
pausedtime = 0;
video.addEventListener( 'timeupdate', function() {
if ( this.currentTime >= pausedtime + 5 ) {
this.pause();
pausedtime = this.currentTime
}
});
function restart(){
video.currentTime = 0;
pausedtime = 0;
video.play()
}
function jump(){
pausedtime += 5;
video.currentTime = pausedtime;
video.play()
}
<video id="myvid" width="320" height="240" controls>
<source src="http://iandevlin.com/html5/media-player/parrots.mp4.mp4" type="video/mp4">
<source src="http://iandevlin.com/html5/media-player/parrots.webm" type="video/webm">
</video>
<br>
<button type="button" onclick="restart()">Restart</button>
<button type="button" onclick="jump()">Jump</button>
how can using php play a sound each 1 or 2 min
when a user enter in the page the first sound play
after 1 min another sound will be played and the first will be stopped of
course all that will be auto play
html5 code:
<audio controls autoplay>
<source src="horse.mp3" type="audio/mpeg">
</audio>
Simply you can merge both sound with your timing and implemented just like this:
<audio controls="controls" onloadeddata="audioSoundFunction()">
<source src="horse.mp3" type="audio/mp3" />
</audio>
Javascript:
function audioSoundFunction() {
var audioSound = this;
setTimeout(function() {
audioSound.play();
}, 10000)
}
<audio id="selecterForAudio" controls autoplay>
<source src="horse.mp3" type="audio/mpeg">
</audio>
javascript/jquery
var myVar = setInterval(myTimer, 60000);
var audio = $("#selecterForAudio")[0];
var counter = 0;
var musicfiles = ["horse.mp3", "lard.mp3"];
function myTimer(){
//stopping the audio
audio.stop();
//setting new source of array of sources
$('#selecterForAudio').find('source').attr('src',musicfiles[counter]);
counter+1;
if(counter>COUNT(musicfiles)){
counter=0;
}
//play sound
audio.play();
}
something like this should fit your needs - it might need a little tweeking though
I have an engine song in autoplay and i want that when i click on my button the sound turn off "progressively" for get a fluid diminution of the volume and finish at 0.1 or 0.2 of the volume, someone have an idea ?
This is my actual code:
<audio autoplay>
<source src="../audio/2445.mp3">
</audio>
<button>turn off</button>
not sure if this is right way to do it, you could do something like:
<audio autoplay id='aud'>
<source src='http://upload.wikimedia.org/wikipedia/commons/5/5b/Ludwig_van_Beethoven_-_Symphonie_5_c-moll_-_1._Allegro_con_brio.ogg'>
</audio>
<button id='btn'>turn off</button>
JS:
var audio = document.getElementById('aud'), interval;
document.getElementById('btn').onclick = turnOff;
function turnOff(){
if(audio && !audio.paused){
interval = setInterval(function(){
console.log('audio volume: ', audio.volume);
if(!audio || audio.paused || audio.volume < 0.1){
clearInterval(interval);
}else{
audio.volume -= .05; // change this value as per your liking
}
}, 200); // change this value as per your liking
}
}
I guess a better way to do it might be with web-audio.
Fiddle Demo