2016-07-14 12 views
1

Ich schrieb Testcode für die Aufnahme in der Webseite, und die exportierte WAV-Datei kann abgespielt werden, aber total falsch, nur ein paar bedeutungslosen Sound, und die Dauer in VLC ist nicht richtig. Bitte schauen Sie nach, ob der Code falsch ist.HTML5-Aufnahme funktioniert nicht

<html> 

<head></head> 

<body> 
    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> 
    <button id='start'>Start</button> 
    <button id='stop'>Stop</button> 
    <button id='export'>Export</button> 
    <script> 
    var isRecording = false; 
    var buf = []; 
    var totalLen = 0; 
    var channelNum = 1; 
    var sampleRate = 48000; 

    $('#start').click(function() 
    { 
    window.AudioContext = window.AudioContext || window.webkitAudioContext; 
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; 
    window.URL = window.URL || window.webkitURL; 

    var cxt = new AudioContext(); 
    isRecording = true; 

    navigator.getUserMedia({audio:true}, function(stream){ 
     var streamNode = cxt.createMediaStreamSource(stream); 
     var processNode = (cxt.createScriptProcessor || cxt.createJavaScriptNode).call(cxt, 1024 * 2, channelNum, channelNum); 
     processNode.onaudioprocess = function(e){ 
     if(!isRecording) return; 

     var f = e.inputBuffer; 
     var cdata = f.getChannelData(channelNum -1); 
     buf.push(cdata); 
     totalLen += cdata.length; 
     }; 
     streamNode.connect(processNode); 
     processNode.connect(cxt.destination); 

    }, function(){}); 
    }); 

    $('#stop').click(function(){ 
    isRecording = false; 
    }); 

    $('#export').click(function(){ 
    var oneBuf = new Float32Array(totalLen); 
    var offset = 0; 
    for(var i=0;i<buf.length;++i){ 
     oneBuf.set(buf[i], offset); 
     offset += buf[i].length; 
    } 

    var encodedBuf = encodeWAV(oneBuf); 
    var blob = new Blob([encodedBuf], {type:'audio/wav'}); 
    console.log(encodedBuf); 

    var url = URL.createObjectURL(blob); 
    var hf = document.createElement('a'); 
    hf.download = '1.wav'; 
    hf.innerHTML = hf.download; 
    hf.href = url; 
    $('body').append(hf); 
    }); 

    function encodeWAV(samples){ 
    var arr = new ArrayBuffer(44 + samples.length * 2); 
    var view = new DataView(arr); 

    /* RIFF identifier */ 
    writeString(view, 0, 'RIFF'); 
    /* RIFF chunk length */ 
    view.setUint32(4, 36 + samples.length * 2, true); 
    /* RIFF type */ 
    writeString(view, 8, 'WAVE'); 
    /* format chunk identifier */ 
    writeString(view, 12, 'fmt '); 
    /* format chunk length */ 
    view.setUint32(16, 16, true); 
    /* sample format (raw) */ 
    view.setUint16(20, 1, true); 
    /* channel count */ 
    view.setUint16(22, channelNum, true); 
    /* sample rate */ 
    view.setUint32(24, sampleRate, true); 
    /* byte rate (sample rate * block align) */ 
    view.setUint32(28, sampleRate * 4, true); 
    /* block align (channel count * bytes per sample) */ 
    view.setUint16(32, channelNum * 2, true); 
    /* bits per sample */ 
    view.setUint16(34, 16, true); 
    /* data chunk identifier */ 
    writeString(view, 36, 'data'); 
    /* data chunk length */ 
    view.setUint32(40, samples.length * 2, true); 

    floatTo16BitPCM(view, 44, samples); 
    console.log('my samplerate:%d', sampleRate); 
    return view; 
    } 

    function floatTo16BitPCM(view, offset, input) { 
     for (var i = 0; i < input.length; i++, offset += 2) { 
      var s = Math.max(-1, Math.min(1, input[i])); 
      view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); 
     } 
    } 

    function writeString(view, offset, string) { 
     for (var i = 0; i < string.length; i++) { 
      view.setUint8(offset + i, string.charCodeAt(i)); 
     } 
    } 

    </script> 
</body> 

</html> 

Antwort

1

Nach einigen Untersuchungen. Ich habe das Problem gefunden.

var cdata = f.getChannelData(channelNum -1); 
buf.push(cdata); 

Die variablen buf speichert Tondaten von Audiopuffer, sondern speichert nur die Puffer Referenz. Der Puffer wird kontinuierlich durch den Low-Level-Code aktualisiert. Als Konsequenz speichert buf speichert ein Array des gleichen Puffers. Deshalb ist der Sound von VLC bedeutungslos.

Nach dem nachstehend zu ändern, funktioniert der Code in Ordnung:

var cdata = f.getChannelData(channelNum -1); 
buf.push(cdata.slice()); 

aber immer noch nicht wissen, warum der Wert für die Dauer in VLC zur Zeit nicht korrekt ist.

Verwandte Themen