I am trying to send chunks of a live recording through a socket using expo-file-system in react native. The problem is that when I send chunks of the audio while it's still recording, the data turns out to be corrupted somehow, and when I decode it in my server I can't even play that audio. But if I wait for the recording to be stopped and then start to send the data the audio turns out ok.
This is the function:
export async function uploadChunksToServer(recordingInstance, chunkSize, delayBetweenChunks) {
let info = await FileSystem.getInfoAsync(recordingInstance.getURI());
let uri = info.uri;
let currentPosition = 0;
let current_file_size = info.size;
let prev_pos = 0;
await sleep(delayBetweenChunks);
do{
try{
let info = await FileSystem.getInfoAsync(recordingInstance.getURI());
current_file_size = info.size;
if (currentPosition + chunkSize >= current_file_size && currentPosition === prev_pos && prev_pos !== 0){
console.log('blocked')
continue;
}
else{
const fileChunk = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
})
currentPosition += chunkSize;
socket.emit('audioData', fileChunk);
}
prev_pos = currentPosition;
}
catch (e) {
console.log(e);
}
if (recordingInstance._isDoneRecording && current_file_size - currentPosition < chunkSize){
const fileChunk = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
position: currentPosition,
length: current_file_size - currentPosition
})
currentPosition += current_file_size - currentPosition;
socket.emit('recording', fileChunk);
break
}
} while(currentPosition < current_file_size)
console.log("final report >> ", currentPosition, current_file_size)
console.log('exiting')
const fileChunk = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
})
socket.emit('done_recording', fileChunk);
}
Here I sent the same audio twice and saved it in two files, once while recording and once after the recording stopped. I compared them using Beyond Compare and noticed differences even at the start of the data inside the files. Any info would be appreciated. Thanks!
const recordingInstance = new Audio.Recording();
await recordingInstance.prepareToRecordAsync({
android:{
extension: '.wav',
linearPCMIsBigEndian:true,
},
ios:{
extension: '.wav',
linearPCMIsBigEndian:false,
},
});
Set the linearPCMIsBigEndian:false
, and extension: '.wav'
and it works.
IMPORTANT: The chunk length needs to be a multiple of 24!