2017-05-01 20 views
2

AudioBuffer를 다운로드 할 수있는 wav 파일로 변환하려고합니다. 나는 모든 소리가 mediaRecorder을 던졌다가는 기록하고이 작업을 수행, 첫 번째 :AudioBuffer를 wav 파일로 변환하는 방법?

App.model.mediaRecorder.ondataavailable = function(evt) { 
    // push each chunk (blobs) in an array 
    //console.log(evt.data) 
    App.model.chunks.push(evt.data); 
}; 

App.model.mediaRecorder.onstop = function(evt) { 
    // Make blob out of our blobs, and open it. 
    var blob = new Blob(App.model.chunks, { 'type' : 'audio/wav; codecs=opus' }); 
    createDownloadLink(blob); 

}; 

나는 모양을 포함하는 청크 테이블을 만든 다음이 덩어리로 새로운 물방울을 만들 나는이 방법을 시도했다.

function createDownloadLink(blob) { 

    var url = URL.createObjectURL(blob); 
    var li = document.createElement('li'); 
    var au = document.createElement('audio'); 
    li.className = "recordedElement"; 
    var hf = document.createElement('a'); 
    li.style.textDecoration ="none"; 
    au.controls = true; 
    au.src = url; 
    hf.href = url; 
    hf.download = 'myrecording' + App.model.countRecordings + ".wav"; 
    hf.innerHTML = hf.download; 
    li.appendChild(au); 
    li.appendChild(hf); 
    recordingslist.appendChild(li); 

}

오디오 노드가 생성되고 난 그렇게 모든 것을 보인다 녹음 된 사운드를들을 수 있습니다 : 그런 다음 함수에서 "createDownloadLink()는"나는 오디오 노드와 다운로드 링크를 생성 작업. 그러나 파일을 다운로드 할 때 어떤 플레이어도이 파일을 읽을 수 없습니다. WAV로 인코딩되지 않았기 때문에 그것이 이해할 수 없기 때문이라고 생각합니다.

두 번째 방법은 "createDownloadLink()"기능을 제외하고는 위와 같습니다. 여기

function createDownloadLink(blob) { 


    var reader = new FileReader(); 
    reader.readAsArrayBuffer(blob); 
    App.model.sourceBuffer = App.model.audioCtx.createBufferSource(); 

    reader.onloadend = function() 
    { 
     App.model.recordBuffer = reader.result; 
     App.model.audioCtx.decodeAudioData(App.model.recordBuffer, function(decodedData) 
             { 
      App.model.sourceBuffer.buffer = decodedData; 

     }) 
    } 

+0

이의 mediaRecorder을 통과하지 마십시오. 대신 MediaStreamSource를 생성 할 audioContext를 사용하고 ScriptProcessorNode에 전달합니다. 여기에서이 processorNode에 전달 된 모든 데이터를 기록하고 올바른 wav 메타 데이터와 함께 연결합니다. [recorder.js] (https://github.com/mattdiamond/Recorderjs/blob/master/src/recorder.js)와 같은 라이브러리는 이러한 마지막 단계에 도움이됩니다. MediaStreamSource로 피드를 보내면됩니다. – Kaiido

답변

0

당신이의 변형을 사용할 수 ... 나는 기록 된 소리의 오디오 버퍼 얻을,하지만 난 WAV 파일로 변환하는 방법을 찾지 못했습니다? https://gist.github.com/asanoboy/3979747

어쩌면 이렇게 할 수 있을까요? 여기

var wav = createWavFromBuffer(convertBlock(decodedData), 44100); 
// Then call wav.getBuffer or wav.getWavInt16Array() for the WAV-RIFF formatted data 

다른 기능 :

class Wav { 
    constructor(opt_params) { 
     this._sampleRate = opt_params && opt_params.sampleRate ? opt_params.sampleRate : 44100; 
     this._channels = opt_params && opt_params.channels ? opt_params.channels : 2; 
     this._eof = true; 
     this._bufferNeedle = 0; 
     this._buffer; 
    } 
    setBuffer(buffer) { 
     this._buffer = this.getWavInt16Array(buffer); 
     this._bufferNeedle = 0; 
     this._internalBuffer = ''; 
     this._hasOutputHeader = false; 
     this._eof = false; 
    } 
    getBuffer(len) { 
     var rt; 
     if(this._bufferNeedle + len >= this._buffer.length){ 
      rt = new Int16Array(this._buffer.length - this._bufferNeedle); 
      this._eof = true; 
     } 
     else { 
      rt = new Int16Array(len); 
     } 
     for(var i=0; i<rt.length; i++){ 
      rt[i] = this._buffer[i+this._bufferNeedle]; 
     } 
     this._bufferNeedle += rt.length; 
     return rt.buffer; 
    } 
    eof() { 
     return this._eof; 
    } 
    getWavInt16Array(buffer) { 

     var intBuffer = new Int16Array(buffer.length + 23), tmp; 

     intBuffer[0] = 0x4952; // "RI" 
     intBuffer[1] = 0x4646; // "FF" 

     intBuffer[2] = (2*buffer.length + 15) & 0x0000ffff; // RIFF size 
     intBuffer[3] = ((2*buffer.length + 15) & 0xffff0000) >> 16; // RIFF size 

     intBuffer[4] = 0x4157; // "WA" 
     intBuffer[5] = 0x4556; // "VE" 

     intBuffer[6] = 0x6d66; // "fm" 
     intBuffer[7] = 0x2074; // "t " 

     intBuffer[8] = 0x0012; // fmt chunksize: 18 
     intBuffer[9] = 0x0000; // 

     intBuffer[10] = 0x0001; // format tag : 1 
     intBuffer[11] = this._channels; // channels: 2 

     intBuffer[12] = this._sampleRate & 0x0000ffff; // sample per sec 
     intBuffer[13] = (this._sampleRate & 0xffff0000) >> 16; // sample per sec 

     intBuffer[14] = (2*this._channels*this._sampleRate) & 0x0000ffff; // byte per sec 
     intBuffer[15] = ((2*this._channels*this._sampleRate) & 0xffff0000) >> 16; // byte per sec 

     intBuffer[16] = 0x0004; // block align 
     intBuffer[17] = 0x0010; // bit per sample 
     intBuffer[18] = 0x0000; // cb size 
     intBuffer[19] = 0x6164; // "da" 
     intBuffer[20] = 0x6174; // "ta" 
     intBuffer[21] = (2*buffer.length) & 0x0000ffff; // data size[byte] 
     intBuffer[22] = ((2*buffer.length) & 0xffff0000) >> 16; // data size[byte] 

     for (var i = 0; i < buffer.length; i++) { 
      tmp = buffer[i]; 
      if (tmp >= 1) { 
       intBuffer[i+23] = (1 << 15) - 1; 
      } 
      else if (tmp <= -1) { 
       intBuffer[i+23] = -(1 << 15); 
      } 
      else { 
       intBuffer[i+23] = Math.round(tmp * (1 << 15)); 
      } 
     } 

     return intBuffer; 
    } 
} 

// factory 
function createWavFromBuffer(buffer, sampleRate) { 
    var wav = new Wav({ 
     sampleRate: sampleRate, 
     channels: 1 
    }); 
    wav.setBuffer(buffer); 
    return wav; 
} 


// ArrayBuffer -> Float32Array 
var convertBlock = function(buffer) { 
    var incomingData = new Uint8Array(buffer); 
    var i, l = incomingData.length; 
    var outputData = new Float32Array(incomingData.length); 
    for (i = 0; i < l; i++) { 
     outputData[i] = (incomingData[i] - 128)/128.0; 
    } 
    return outputData; 
} 
+0

코드 스 니프 - 여기에서 가져온 것 : https://gist.github.com/revolunet/46d4187c3b6f28632a91421c1f2a9fad#file-create-wav-from-buffer-js-L45 – Erik