14

私はiOSメトロノームWebアプリに取り組んでいます。モバイルSafariは一度に1つのサウンドしか再生できないため、「オーディオスプライト」を作成しようとしています。ここでは、1つのオーディオトラックのさまざまなセグメントを使用してさまざまなサウンドを生成できます。1秒のクリップに2つの0.5秒のサウンドがあります。

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

JSFiddleでご覧ください。

ご覧のとおり、「timeupdate」イベント(jPlayerの例)を使用しようとしましたが、役に立ちませんでした。

オーディオスプライトに関するRemySharpの投稿を見たことがありますが、(A)それを機能させることができず、(B)ライブラリへの依存を避けたいと思います。

何か案は?


アップデート

私は今それを使用して動作してい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();
}

シーケンスと設定/クリア間隔にいくつかの問題がありますが、私の目的では、それは機能しているようです。

JSFiddle

PS誰かがこれを修正した場合、これはゲームとインターフェイスサウンドFXで使用できます。

4

2 に答える 2

22

ここにはいくつか問題があると思います。

まず、ユーザーがPlay1をクリックするたびにイベントリスナーを追加します。

また、私は思います

if (currentTime >= 0.5) { ...

する必要があります

if (audio.currentTime >= 0.5) { ...

これも機能します:

<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>
于 2011-05-18T02:17:43.893 に答える
0

オーディオオブジェクトのセグメントを再生するためのクリーンな関数が見つからなかったので、これが私が思いついたものです。また、ユーザーが短時間で複数のトリガーをクリックした場合に発生する次のエラーも解決します。

「キャッチされていない(約束された)DOMException:play()要求が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);
} 
于 2020-10-03T21:27:01.527 に答える