stream-chat-react
Version:
React components to create chat conversations or livestream style chat
34 lines (33 loc) • 1.9 kB
JavaScript
import { renderAudio, toAudioBuffer, } from '../../components/MediaRecorder/transcode/audioProcessing';
const ENCODING_BIT_RATE = 128; // kbps;
const COUNT_SAMPLES_PER_ENCODED_BLOCK = 1152;
const float32ArrayToInt16Array = (float32Arr) => {
const int16Arr = new Int16Array(float32Arr.length);
for (let i = 0; i < float32Arr.length; i++) {
const float32Value = float32Arr[i];
// Clamp the float value between -1 and 1
const clampedValue = Math.max(-1, Math.min(1, float32Value));
// Convert the float value to a signed 16-bit integer
int16Arr[i] = Math.round(clampedValue * 32767);
}
return int16Arr;
};
const splitDataByChannel = (audioBuffer) => Array.from({ length: audioBuffer.numberOfChannels }, (_, i) => audioBuffer.getChannelData(i)).map(float32ArrayToInt16Array);
export async function encodeToMp3(file, sampleRate) {
const lameJs = await import('@breezystack/lamejs');
const audioBuffer = await renderAudio(await toAudioBuffer(file), sampleRate);
const channelCount = audioBuffer.numberOfChannels;
const dataByChannel = splitDataByChannel(audioBuffer);
const mp3Encoder = new lameJs.Mp3Encoder(channelCount, sampleRate, ENCODING_BIT_RATE);
const dataBuffer = [];
let remaining = dataByChannel[0].length;
for (let i = 0; remaining >= COUNT_SAMPLES_PER_ENCODED_BLOCK; i += COUNT_SAMPLES_PER_ENCODED_BLOCK) {
const [leftChannelBlock, rightChannelBlock] = dataByChannel.map((channel) => channel.subarray(i, i + COUNT_SAMPLES_PER_ENCODED_BLOCK));
dataBuffer.push(new Int8Array(mp3Encoder.encodeBuffer(leftChannelBlock, rightChannelBlock)));
remaining -= COUNT_SAMPLES_PER_ENCODED_BLOCK;
}
const lastBlock = mp3Encoder.flush();
if (lastBlock.length)
dataBuffer.push(new Int8Array(lastBlock));
return new Blob(dataBuffer, { type: 'audio/mp3;sbu_type=voice' });
}