I'm trying to convert .webm to .mp4 on backend in node in a format that can be played on mobile safari.
The reason for doing this is that we are using getUserMedia() & getDisplayMedia to record the user's camera/screen and webm doesn't play on mobile ios safari.
Following the second part of this answer - https://stackoverflow.com/a/63463669
On frontend -
mediaStreamConstraints: {
video: { width: 1280, height: 720, frameRate: { min: 24, ideal: 30, max: 60 } },
audio: true,
...mediaStreamConstraints,
},
mediaRecorderOptions: {
videoBitsPerSecond: 4000000,
mimeType: 'video/webm;codecs=h264',
},
});
And on the backend
async uploadVideo(id: string, readableStream: stream.Readable, options: UploadBlobOptions) {
if (disableVideoEncoding) {
return this.uploadBlob(id, readableStream, options);
}
const buffer = await readableStreamToBuffer(readableStream);
const inputData = new Uint8Array(buffer);
const result = ffmpeg({
MEMFS: [{ name: 'input', data: inputData }],
print: () => {},
printErr: () => {},
arguments: [
...['-i', 'input'],
// Encode audio with AAC https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Audio_codecs#choosing_an_audio_codec
...['-c:a', 'aac'],
// Copy video
...['-c:v', 'copy'],
// Output
'output.mp4',
],
});
const out = result.MEMFS[0];
const outStream = new Duplex();
if (out) {
outStream.push(out.data);
outStream.push(null);
} else {
throw new Error('Could not find output file');
}
return this.uploadBlob(id, outStream, {
...options,
mimeType: 'video/mp4',
});
}
The output video works in chrome and is .mp4, but still doesn't play in safari. If anyone can solve I'm very grateful!!
This is a video generated with the code above:
And this is another video i uploaded a while back, which works in safari: https://tendon-user-files-public.s3.eu-west-1.amazonaws.com/tendon-production/bafybeihjwawyuvirf4ymwununm25skxvzedlsd33ztav3rbofekv7z6yzu.mp4