SOURCE

console 命令行工具 X clear

                    
>
console
function audioBufferToWav(buffer, opt) {
    opt = opt || {}

    var numChannels = buffer.numberOfChannels
    var sampleRate = buffer.sampleRate
    var format = opt.float32 ? 3 : 1
    var bitDepth = format === 3 ? 32 : 16

    var result
    if (numChannels === 2) {
        result = interleave(buffer.getChannelData(0), buffer.getChannelData(1))
    } else {
        result = buffer.getChannelData(0)
    }

    return encodeWAV(result, format, sampleRate, numChannels, bitDepth)
}

function encodeWAV(samples, format, sampleRate, numChannels, bitDepth) {
    var bytesPerSample = bitDepth / 8
    var blockAlign = numChannels * bytesPerSample

    var buffer = new ArrayBuffer(44 + samples.length * bytesPerSample)
    var view = new DataView(buffer)

    /* RIFF identifier */
    writeString(view, 0, 'RIFF')
    /* RIFF chunk length */
    view.setUint32(4, 36 + samples.length * bytesPerSample, 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, format, true)
    /* channel count */
    view.setUint16(22, numChannels, true)
    /* sample rate */
    view.setUint32(24, sampleRate, true)
    /* byte rate (sample rate * block align) */
    view.setUint32(28, sampleRate * blockAlign, true)
    /* block align (channel count * bytes per sample) */
    view.setUint16(32, blockAlign, true)
    /* bits per sample */
    view.setUint16(34, bitDepth, true)
    /* data chunk identifier */
    writeString(view, 36, 'data')
    /* data chunk length */
    view.setUint32(40, samples.length * bytesPerSample, true)
    if (format === 1) { // Raw PCM
        floatTo16BitPCM(view, 44, samples)
    } else {
        writeFloat32(view, 44, samples)
    }

    return buffer
}

function interleave(inputL, inputR) {
    var length = inputL.length + inputR.length
    var result = new Float32Array(length)

    var index = 0
    var inputIndex = 0

    while (index < length) {
        result[index++] = inputL[inputIndex]
        result[index++] = inputR[inputIndex]
        inputIndex++
    }
    return result
}

function writeFloat32(output, offset, input) {
    for (var i = 0; i < input.length; i++ , offset += 4) {
        output.setFloat32(offset, input[i], true)
    }
}

function floatTo16BitPCM(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)
    }
}

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


var numberOfChannels = 1 // 通道数
var sampleRate = 44100 // 采样率
var duration = 30 // 音频时长(可以从原视频去获取)

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

var offlineAudioContext = new OfflineAudioContext(numberOfChannels, sampleRate * duration, sampleRate);
var soundSource = offlineAudioContext.createBufferSource();

function imporFile() {


    var selectedFile = document.getElementById("files").files[0];//获取读取的File对象
    var name = selectedFile.name;//读取选中文件的文件名
    var size = selectedFile.size;//读取选中文件的大小
    console.log("文件名:" + name + "大小:" + size);


    var reader = new FileReader();//这里是核心!!!读取操作就是由它完成的。

    reader.readAsArrayBuffer(selectedFile); // video file

    reader.onload = function () {

        var videoFileAsBuffer = reader.result; // arraybuffer
        console.log('reading');

        audioContext.decodeAudioData(videoFileAsBuffer)
            .then(function (decodedAudioData) {

                myBuffer = decodedAudioData;
                soundSource.buffer = myBuffer;
                soundSource.connect(offlineAudioContext.destination);
                soundSource.start();

                offlineAudioContext.startRendering().then(function (renderedBuffer) {
                    var wav = audioBufferToWav(renderedBuffer)
                    var blob = new window.Blob([new DataView(wav)], {
                        type: 'audio/wav'
                    })

                    var url = window.URL.createObjectURL(blob)
                    // window.open(url)

                    document.getElementById('player').src = url
                    console.log('done')


                }).catch(function (err) {
                    console.log('Rendering failed: ' + err);
                });
            })
            .catch(function (ex) {
                console.log('ERR');
                console.log(ex);
            });
    };

}
<html>

<head></head>

<body>

	<div>
		<input type="file" id="files" onchange="imporFile();"/>
        <video controls id="player" ></video>
     </div>
    
</body>
</html>