2017-02-20 15 views
1

私は<audio>要素を持っており、速度、開始/終了境界、ピッチを変更しています。ブラウザで聞いた音声を録音することが可能かどうかを確認したい。しかし私は、低音質のためにマイクで録音したくない。マイクを使わずに<audio>の出力を録音できますか?

私は同じエフェクトをサーバー側で実行できますが、基本的には2つの異なるテクノロジで同じ機能を複製するので、むしろそうしたいと思います。


「私が尋ねていることは不明」というフラグ投票に応じて、言い換えることにします。

私は<audio>要素をページ上で再生しています。私はいくつかのjavascriptで再生速度、音量などを操作しています。ブラウザには、と聞いているように、オーディオを記録します。これはマイクではありません。私はできるだけ近くに新しいオーディオファイルを作成したい。それが75%であれば、新しいファイルは75%のボリュームになります。

あなたがそれが不可能だと思うなら、そう言えばいいです。そしてもっと明確にしたいなら、それはいいですね。私は人々が説明を与えずにダウンボートやフラグを立てない方が好きです。

+2

おそらく 'captureStream()' APIを使うことができます:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/captureStream –

+0

はい、サポートされているブラウザでは、 'MediaElement.captureStream ()メソッドと[MediaRecorder API](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder)を参照してください。しかし、これらの技術はまだ活発に開発されており、現在の実装には依然としてバグがたくさんあることに注意してください。たとえば、あなたのケースでは、現在の安定したFFは、録音中に音量を変更すると元のメディアオーディオのレンダリングを停止します。 – Kaiido

+0

古いブラウザのサポートが必要な場合は、MediaElementをWebAudio APIに渡すこともできます['createMediaElementSource'](https://developer.mozilla.org/en/US/docs/Web/API/AudioContext/createMediaElementSource)メソッドです。そこから、メディアの未加工PCMデータを取得して保存することができます(ただし、音量コントロールはwebAudioApi自体で行う必要があります)。 – Kaiido

答えて

3

サポートされているブラウザではMediaRecorder APIと一緒にMediaElement.captureStream()メソッドを使用できます。

しかし、これらのテクノロジはまだ開発中であり、現在の実装ではまだバグがたくさんあることに注意してください。
あなたのケースでは、現在の安定したFFは、録音中に音量を変更した場合、元のメディアオーディオのレンダリングを停止します...私はそれに関するバグレポートを検索する時間がありませんでしたが、とにかく、これはあなたが見つけられる多くのバグの一つです。古いブラウザの場合

// here we will save all the chunks of our record 
 
const chunks = []; 
 
// wait for the original media is ready 
 
audio.oncanplay = function() { 
 
    audio.volume = 0.5; // just for your example 
 
    // FF still does prefix this unstable method 
 
    var stream = audio.captureStream ? audio.captureStream() : audio.mozCaptureStream(); 
 
    // create a MediaRecorder from our stream 
 
    var rec = new MediaRecorder(stream); 
 
    // every time we've got a bit of data, store it 
 
    rec.ondataavailable = e => chunks.push(e.data); 
 
    // once everything is done 
 
    rec.onstop = e => { 
 
    audio.pause(); 
 
    // concatenate our chunks into one file 
 
    let final = new Blob(chunks); 
 
    let a = new Audio(URL.createObjectURL(final)); 
 
    a.controls = true; 
 
    document.body.append(a); 
 
    }; 
 
    rec.start(); 
 
    // record for 6 seconds 
 
    setTimeout(() => rec.stop(), 6000); 
 
    // for demo, change volume at half-time 
 
    setTimeout(() => audio.volume = 1, 3000); 
 
}; 
 

 
// FF will "taint" the stream, even if the media is served with correct CORS... 
 
fetch("https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3").then(resp => resp.blob()).then(b => audio.src = URL.createObjectURL(b));
<audio id="audio" autoplay controls></audio>

、あなたはAPIを通して、あなたのオーディオ要素メディアを渡すために、WebAudio APIのcreateMediaElementSourceメソッドを使用することができます。
そこから、生のPCMデータをarrayBuffersに抽出して保存することができます。

以下のデモでは、を大いに助けwavプロセスに保存するrecorder.jsライブラリを使用します。

audio.oncanplay = function(){ 
 
    var audioCtx = new AudioContext(); 
 
    var source = audioCtx.createMediaElementSource(audio); 
 
    var gainNode = audioCtx.createGain(); 
 

 
    gainNode.gain.value = 0.5; 
 

 
    source.connect(gainNode); 
 
    gainNode.connect(audioCtx.destination); 
 

 
    var rec = new Recorder(gainNode); 
 

 
    rec.record(); 
 
    setTimeout(function(){ 
 
    gainNode.gain.value = 1; 
 
    }, 3000); 
 
    setTimeout(function(){ 
 
    rec.stop() 
 
    audio.pause(); 
 
    rec.exportWAV(function(blob){ 
 
     var a = new Audio(URL.createObjectURL(blob)); 
 
     a.controls = true; 
 
     document.body.appendChild(a); 
 
     }); 
 
    }, 6000); 
 
    };
<script src="https://rawgit.com/mattdiamond/Recorderjs/master/dist/recorder.js"></script> 
 
<audio id="audio" crossOrigin="anonymous" controls src="https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3" autoplay></audio>

+1

が処理されます。しかし、私はあなたが実験的であるということを理解しているので、chrome://フラグに 'Experimental Web Platform Features'を有効にして' captureStream'を定義する必要がありました。 –

2

Kaiidoが彼の答えで述べているように、captureStream()はそれを行うための一つの方法です。ただし、まだChromeやFirefoxでは完全にサポートされていません。 MediaRecorderでは、録音中にトラックセットの変更も許可されず、captureStream()からのMediaStreamに(アプリケーションに依存する)MediaStreamが含まれている可能性があり、録音を途中で終了します。あなたはメディア要素から音声のみを記録するサポートされている方法が必要な場合は

は、あなたがそのMediaStreamAudioDestinationNode、およびパイプMediaRecorderにそのstream属性にMediaElementAudioSourceNode、パイプを使用することができます。WebAudioと録音の両方が同じようにどちらのアプローチは、適切なCORS設定せずに、クロスオリジンのオーディオソースで動作することを

const a = document.getElementsByTagName("audio")[0]; 
const ac = new AudioContext(); 
const source = ac.createMediaElementSource(a); 

// The media element source stops audio playout of the audio element. 
// Hook it up to speakers again. 
source.connect(ac.destination); 

// Hook up the audio element to a MediaStream. 
const dest = ac.createMediaStreamDestination(); 
source.connect(dest); 

// Record 10s of audio with MediaRecorder. 
const recorder = new MediaRecorder(dest.stream); 
recorder.start(); 
recorder.ondataavailable = ev => { 
    console.info("Finished recording. Got blob:", ev.data); 
    a.src = URL.createObjectURL(ev.data); 
    a.play(); 
}; 
setTimeout(() => recorder.stop(), 10 * 1000); 

注:ここでは

では、既存のオーディオ要素をページ上で使用することができます例ですアプリケーションにオーディオデータを検査する可能性を与えます。

+0

もう一度質問を読んで、異なる再生レートとピッチ設定で録音したいと思っています。 – pehrsons

+1

申し訳ありませんが、間違ったコメント。続行:MediaElementAudioSourceNodeはそれらを明示的には言及していないので(それらを転送することは仕様でサポートされています)、少なくともFirefoxはplaybackRateを正しく転送しません。私はそれがサポートされるまでは時間の問題だと言いたい。 https://bugzilla.mozilla.org/show_bug.cgi?id=966247を参照してください。 – pehrsons

関連する問題