2012-07-16 6 views
8

Web Audio APIでオーディオファイルを一時停止/再開できないことがよくあります。
しかし今、私はexampleを見て、実際には一時停止して再開できるようにしました。私は彼らがどのようにそれをやったか把握しようとしました。多分source.looping = falseが鍵だと思ったが、そうではなかった。
今のところ私のオーディオは常に最初から再生されています。ウェブオーディオAPIが一時停止から再開

これは私の現在のコード

var context = new (window.AudioContext || window.webkitAudioContext)(); 

function AudioPlayer() { 
    this.source = context.createBufferSource(); 
    this.analyser = context.createAnalyser(); 
    this.stopped = true; 
} 

AudioPlayer.prototype.setBuffer = function(buffer) { 
    this.source.buffer = buffer; 
    this.source.looping = false; 
}; 

AudioPlayer.prototype.play = function() { 
    this.source.connect(this.analyser); 
    this.analyser.connect(context.destination); 

    this.source.noteOn(0); 
    this.stopped = false; 
}; 

AudioPlayer.prototype.stop = function() { 
    this.analyser.disconnect(); 
    this.source.disconnect(); 
    this.stopped = true; 
}; 

誰もが、それは仕事を取得するために、何をすべきかを知っていますか?

答えて

5

あなたの例のソースをチェックする任意の時間を費やすことなく、私は(https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#methodsandparams-AudioBufferSourceNode)あなたはAudioBufferSourceNodeのnoteGrainOnメソッドを使用するとよいでしょう

を言うと思いますちょうどあなたがいたバッファにどのくらいのトラックを保ちますnoteOffを呼び出してから、新しいAudioBufferSourceNodeでレジュームするときにそこからnoteGrainOnを実行します。

それは意味がありましたか?

EDIT: 更新されたAPI呼び出しについては、下記のコメントを参照してください。

+0

この例では、彼は 'noteGrainOn()'を使用していません(しかし、彼はどのようにしているのか分かりません)。しかし、とにかく、これは魅力のように働くので、私はこれを受け入れられた答えとみなします。ありがとうございました:) –

+1

noteGrainOn()は、noteOn()と同様に、仕様で名前が変更されました。両方とも、グレインオフセット引数の有無にかかわらずplay()になりました。しかし、これはまだサポートされて見たことがありません。 – LeeGee

+1

実際には 'start'(引数' start(howSoonRelativeToCurrentTime、fromSecondInBuffer、forDuration) ')の有無にかかわらず、Chrome Canaryで動作するようです –

15

オスカーの答えとaykeのコメントは非常に役に立ちますが、コード例がありませんでした。だから私は1つ書いた:http://jsfiddle.net/v3syS/2/私はそれが助けて欲しい。

var url = 'http://thelab.thingsinjars.com/web-audio-tutorial/hello.mp3'; 

var ctx = new webkitAudioContext(); 
var buffer; 
var sourceNode; 

var startedAt; 
var pausedAt; 
var paused; 

function load(url) { 
    var request = new XMLHttpRequest(); 
    request.open('GET', url, true); 
    request.responseType = 'arraybuffer'; 
    request.onload = function() { 
     ctx.decodeAudioData(request.response, onBufferLoad, onBufferError); 
    }; 
    request.send(); 
}; 

function play() { 
    sourceNode = ctx.createBufferSource(); 
    sourceNode.connect(ctx.destination); 
    sourceNode.buffer = buffer; 
    paused = false; 

    if (pausedAt) { 
     startedAt = Date.now() - pausedAt; 
     sourceNode.start(0, pausedAt/1000); 
    } 
    else { 
     startedAt = Date.now(); 
     sourceNode.start(0); 
    } 
}; 

function stop() { 
    sourceNode.stop(0); 
    pausedAt = Date.now() - startedAt; 
    paused = true; 
}; 

function onBufferLoad(b) { 
    buffer = b; 
    play(); 
}; 

function onBufferError(e) { 
    console.log('onBufferError', e); 
}; 

document.getElementById("toggle").onclick = function() { 
    if (paused) play(); 
    else stop(); 
}; 

load(url); 
0

WebAudio APIに組み込まれている一時停止機能がないため、私にとって大きな見苦しがあるようです。可能であれば、今後予定されているMediaElementSourceを使用してこれを行うことが可能になります。これにより、Web Audioに要素(一時停止をサポートする)を接続できます。今のところほとんどの回避策は、再生時間を記憶することに基づいているようです(imbriziの回答に記載されているように)。このような回避策では、サウンドをループするとき(実装ループが正常に実行されるかどうか)、サウンドの再生速度を動的に変更できるようにするとき(両方にタイミングに影響を及ぼす)という問題があります。あなたが使用できる別の、均等にハックっぽいと技術的には正しくないが、はるかに簡単な回避策は次のとおりです。

source.playbackRate = paused?0.0000001:1; 

残念ながら、0は(実際に音を一時停止します)playbackRateに有効な値ではありません。しかし、多くの実用的な目的のために、0.000001のような非常に低い値が十分に近く、可聴出力を生成しません。

+0

クイックハックのための+10: – Sam

+0

これは、ブラウザが未使用のオーディオバッファをクリーンアップするのを防ぐので、素晴らしい考えではありません。 APIをそのまま使用するのはややこしいですが、パフォーマンスとメモリ効率の理由からそのように設計されています。 OPの質問のような小さなラッパーライブラリは、より良いアプローチです。 –

0

更新:これはChromeにのみ有効です。 Firefox(v29)はまだMediaElementAudioSourceNode.mediaElementプロパティを実装していません。すでにAudioContext参照して、メディアソースを持っていると仮定すると

(例えばAudioContext.createMediaElementSource()メソッドの呼び出しを介して)、あなたが例えば、あなたの元にMediaElement.play()MediaElement.pause()を呼び出すことができます

source.mediaElement.pause(); 
source.mediaElement.play(); 

ハックや回避策は必要ありません。 <audio>タグをソースとして使用している場合は、JavaScriptのオーディオ要素で直接ポーズを呼び出して再生を停止しないでください。現在のブラウザ(クロム43、Firefoxの40)において

9

'サスペンド' とAudioContextために利用可能な '再開' する方法今ある:実際

var audioCtx = new AudioContext(); 
susresBtn.onclick = function() { 
    if(audioCtx.state === 'running') { 
    audioCtx.suspend().then(function() { 
     susresBtn.textContent = 'Resume context'; 
    }); 
    } else if(audioCtx.state === 'suspended') { 
    audioCtx.resume().then(function() { 
     susresBtn.textContent = 'Suspend context'; 
    }); 
    } 
} 

https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/suspendから変形例コード)

3

ウェブ-audio APIは、あなたのために一時停止と再生タスクを実行できます。これは、オーディオコンテキスト(実行中または一時停止)の現在の状態を知っているので、あなたはこの簡単な方法でこれを行うことができます。

susresBtn.onclick = function() { 
 
    if(audioCtx.state === 'running') { 
 
    audioCtx.suspend() 
 
    } else if(audioCtx.state === 'suspended') { 
 
    audioCtx.resume() 
 
    } 
 
}

私はこれが役立つことを願って。

0

2017では、ctx.currentTimeを使用すると、ソング内のポイントをトラッキングするのに適しています。以下のコードでは、再生ボタン&の一時停止ボタンを切り替えるボタン(songStartPause)を使用しています。私は単純化のためにグローバル変数を使用しました。変数musicStartPointは、曲の何時になっているかを記録します。音楽APIは時間を秒単位で追跡します。しかし、これまであなたがいたために歌は、それが始まったときから終了時間を減算し、この時間の長さを追加するために0であなたの最初のmusicStartPoint(曲の先頭)

var ctx = new webkitAudioContext(); 
var buff, src; 
var musicLoaded = false; 
var musicStartPoint = 0; 
var songOnTime, songEndTime; 
var songOn = false; 

songStartPause.onclick = function() { 

    if(!songOn) { 
    if(!musicLoaded) { 
     loadAndPlay(); 
     musicLoaded = true; 
    } else { 
     play(); 
    } 

    songOn = true; 
    songStartPause.innerHTML = "||" //a fancy Pause symbol 

    } else { 
    songOn = false; 
    src.stop(); 
    setPausePoint(); 
    songStartPause.innerHTML = ">" //a fancy Play symbol 
    } 
} 

使用ctx.currentTimeを設定

最初の曲で。

function setPausePoint() { 
    songEndTime = ctx.currentTime; 
    musicStartPoint += (songEndTime - songOnTime); 
} 

機能をロード/再生します。

function loadAndPlay() { 
    var req = new XMLHttpRequest(); 
    req.open("GET", "//mymusic.com/unity.mp3") 
    req.responseType = "arraybuffer"; 
    req.onload = function() { 
    ctx.decodeAudioData(req.response, function(buffer) { 
     buff = buffer; 
     play(); 
    }) 
    } 
    req.send(); 
} 

function createBuffer() { 
     src = ctx.createBufferSource(); 
     src.buffer = buff; 
    } 


function connectNodes() { 
    src.connect(ctx.destination); 
} 

は最後に、再生機能は、指定musicStartPointに開始するように(と、すぐにそれを再生する)歌を伝え、またsongOnTime変数を設定します。

function play(){ 
    createBuffer() 
    connectNodes(); 
    songOnTime = ctx.currentTime; 
    src.start(0, musicStartPoint); 
} 

*追記:私はそれをクリック機能にsongOnTimeを設定するにはクリーナー見えるかもしれませんけど、私はそれがsrc.startにできるだけ近いタイムコードをつかむために理にかなって把握、ちょうど私達がつかむかのようにsrc.stopに可能な限り近い休止時間。

関連する問題