Guess how JS encoding the audio stream?lower

Next, when it comes to getting local audio streams as the first step, we all know that H5 has a new interface dedicated to dealing with audio streaming related methods. It is the prestigious AudioContext. As for what this object can do specifically, each viewer has his own Baidu.My main use here is the createMediaStreamSource method createScriptProcessor method, createMediaStreamDestination method.These three methods can ultimately get the audio stream pulled out by the local device we want, coded as follows:

let ac  =new AudioContext();
let source =;
let scriptNode =ac.createScriptProcessor(2048, 1, 1);
let dest =;

//When you want to trigger audio collection, execute the following two lines of code

scriptNode then has a method, onaudioprocess, to listen for audio stream sampling

scriptNode.onaudioprocess = (audioProcessingEvent) => {
        const { inputBuffer } = audioProcessingEvent;
        const inputData = inputBuffer.getChannelData(0);

Here we can getInputData.sampleRateThis is the sample rate of the audio stream. The default is 44000. Then we have basically finished the first step here, getting the sample rate of the audio stream and the audio stream.Everyone with insufficient knowledge will make up for their own mistakes in Baidu.

Next step, because the browser pulls out the audio stream with a high sampling rate, which puts pressure on the transmission. Next step is to compress the sampling rate by not requiring a high sampling rate and setting it to 8K as agreed upon with the background.

    function compress(sampleRate, data) {
        if (sampleRate < outSampleRate) return data;
        const compressRatio = Math.floor(sampleRate / outSampleRate);
        const compressLen = data.length / compressRatio;
        const result = new Float32Array(compressLen);
        let index = 0;
        let k = 0;
        while (index < compressLen) {
            result[index] = data[k];
            k += compressRatio;
            return result;

The above code is believed to be understandable, sampleRate is the 44000 audio sample rate we get, data is the inputData we got earlier, what this function method return s is the 8K sample rate we compressed

Next, the most important step is to encapsulate the FLV format, which is relatively simple, preceded by a flv with 9 bits in the head, and then a previouSize with 4 bits defaulting to 0 (the first is all 0 by default).Following are tag data, tag data atmosphere two parts tagheader, encapsulated some tag data information occupies 11 bits, tagData first bit is decoded data, the rest is audio data, and the last four bits are previouseSize, which is the size of data data.
These are the basic concepts, and the next step is to encapsulate the above code:

const payloadLen = data.length * 1;
const buffer = (tagCount == 0)? new ArrayBuffer(9 + 4 + 11 + 1 + payloadLen + 4): new ArrayBuffer(11 + 1 + payloadLen + 4); 
const output = new DataView(buffer);

setFlvHeader(output, payloadLen, tagCount);   //flv stream tagCount defaults to 0

That's the compressed code. With setFlvHeader, we can encapsulate our audio stream in flv fragments.

Next, an important step is to encapsulate the g711a encoding, code above:

    let offset = tagCount == 0 ? 25 : 12;
    for (let i = 0; i < data.length; i++, offset += 1) {
        const s = Math.max(-1, Math.min(1, data[i]));
        const int16 = s < 0 ? s * 0x8000 : s * 0x7FFF; 
        const alawUint8 = encodeALawSample(int16);
        output.setUint8(offset, alawUint8);

Because we encapsulate the format before encoding it, according to tagCount, we have a variable for offset to record the encoding location.We first convert the 32-bit floating point type to the 16-bit int type, then encode it using the encodeAlowSample method.
Finally, we get the g711a encoded audio stream encapsulated in flv format

Tags: Javascript encoding REST

Posted on Thu, 11 Jun 2020 22:39:02 -0400 by trent2800