I'm working on an iOS metronome web app. Since mobile Safari can only play one sound at a time , I'm attempting to create an 'audio sprite' - where I can use different segments of a single audio track to generate different sounds. I have a 1 second clip with 2 half-second sounds on it.
<audio id="sample" src="sounds.mp3"></audio>
<a href="javascript:play1();">Play1</a>
<a href="javascript:play2();">Play2</a>
<a href="javascript:pauseAudio();">Pause</a>
<script>
var audio = document.getElementById('click');
function play1(){
audio.currentTime = 0;
audio.play();
// This is the problem area
audio.addEventListener('timeupdate', function (){
if (currentTime >= 0.5) {
audio.pause();
}
}, false);
}
function play2(){
audio.currentTime = 0.5;
audio.play();
}
function pause(){
audio.pause();
}
</script>
See it on JSFiddle .
As you can see, I've attempted to use the 'timeupdate' event ( jPlayer example ) with no avail.
I've seen Remy Sharp's post on audio sprites , but (A) I wasn't able to get it to work for me, and (B) I would prefer to stay away from a library dependency.
Any ideas?
Update
I now have it working using setInterval
:
function play1(){
audio.currentTime = 0;
audio.play();
int = setInterval(function() {
if (audio.currentTime > 0.4) {
audio.pause();
clearInterval(int);
}
}, 10);
}
function play2(){
clearInterval(int);
audio.currentTime = 0.5;
audio.play();
}
There are some issues with sequence and setting/clearing intervals, but for my purpose - it seems to work.
PS If anyone has a fix for this, this could be used in Games and Interface Sound FX.
I think there are a couple of problems here.
Firstly, you're adding an event listener every time the user clicks Play 1.
Also I think
if (currentTime >= 0.5) { ...
should be
if (audio.currentTime >= 0.5) { ...
This also works:
<audio id="sample" src="http://dl.dropbox.com/u/222645/click1sec.mp3" controls preload></audio>
<a href="javascript:playSegment(0.0, 0.5);">Play1</a>
<a href="javascript:playSegment(0.5);">Play2</a>
<script>
var audio = document.getElementById('sample');
var segmentEnd;
audio.addEventListener('timeupdate', function (){
if (segmentEnd && audio.currentTime >= segmentEnd) {
audio.pause();
}
console.log(audio.currentTime);
}, false);
function playSegment(startTime, endTime){
segmentEnd = endTime;
audio.currentTime = startTime;
audio.play();
}
</script>
I didn't find a clean function to play segment of an audio object so this is what I come up with. It will also solves the the following error which will occur if the user click multiple triggers within short amount of time.
"Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()"
const audioObj_1 = new Audio('/some_audio_file.m4a');
playSegment(audioObj_1 , 1.11, 2.45); // this will play from 1.11 sec to 2.45 sec
function playSegment(audioObj, start, stop){
let audioObjNew = audioObj.cloneNode(true); //this is to prevent "play() request was interrupted" error.
audioObjNew.currentTime = start;
audioObjNew.play();
audioObjNew.int = setInterval(function() {
if (audioObjNew.currentTime > stop) {
audioObjNew.pause();
clearInterval(audioObjNew.int);
}
}, 10);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.