1. 録音する
以下のように作った関数 startRecording を呼ぶと
変数 audioData に録音した音声データが取得できます。
var localMediaStream = null;
var localScriptProcessor = null;
audioData = []; // 録音データ
var onAudioProcess = function(e) {
var input = e.inputBuffer.getChannelData(0);
var bufferData = new Float32Array(bufferSize);
for (var i = 0; i < bufferSize; i++) {
bufferData[i] = input[i];
}
audioData.push(bufferData);
};
var startRecording = function() {
navigator.getUserMedia(
{ audio: true },
function(stream) {
localMediaStream = stream;
var scriptProcessor = audioContext.createScriptProcessor(bufferSize, 1, 1);
localScriptProcessor = scriptProcessor;
var mediastreamsource = audioContext.createMediaStreamSource(stream);
mediastreamsource.connect(scriptProcessor);
scriptProcessor.onaudioprocess = onAudioProcess;
scriptProcessor.connect(audioContext.destination);
},
function(e) {
console.log(e);
}
);
};
2. WAVファイルに変換する
以下のように作った関数 exportWAV に 1 で作成した audioData を引数にわたして呼び出すと
WAVファイルを作成して、その url を返却してくれます。
var exportWAV = function(audioData) {
var encodeWAV = function(samples, sampleRate) {
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
var writeString = function(view, offset, string) {
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
};
var floatTo16BitPCM = function(output, offset, input) {
for (var i = 0; i < input.length; i++, offset += 2){
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
};
writeString(view, 0, 'RIFF'); // RIFFヘッダ
view.setUint32(4, 32 + samples.length * 2, true); // これ以降のファイルサイズ
writeString(view, 8, 'WAVE'); // WAVEヘッダ
writeString(view, 12, 'fmt '); // fmtチャンク
view.setUint32(16, 16, true); // fmtチャンクのバイト数
view.setUint16(20, 1, true); // フォーマットID
view.setUint16(22, 1, true); // チャンネル数
view.setUint32(24, sampleRate, true); // サンプリングレート
view.setUint32(28, sampleRate * 2, true); // データ速度
view.setUint16(32, 2, true); // ブロックサイズ
view.setUint16(34, 16, true); // サンプルあたりのビット数
writeString(view, 36, 'data'); // dataチャンク
view.setUint32(40, samples.length * 2, true); // 波形データのバイト数
floatTo16BitPCM(view, 44, samples); // 波形データ
return view;
};
var mergeBuffers = function(audioData) {
var sampleLength = 0;
for (var i = 0; i < audioData.length; i++) {
sampleLength += audioData[i].length;
}
var samples = new Float32Array(sampleLength);
var sampleIdx = 0;
for (var i = 0; i < audioData.length; i++) {
for (var j = 0; j < audioData[i].length; j++) {
samples[sampleIdx] = audioData[i][j];
sampleIdx++;
}
}
return samples;
};
var dataview = encodeWAV(mergeBuffers(audioData), audioContext.sampleRate);
var audioBlob = new Blob([dataview], { type: 'audio/wav' });
var myURL = window.URL || window.webkitURL;
var url = myURL.createObjectURL(audioBlob);
return url;
};
参考サイト