Currently, there isn't a built in browser API for compressing existing video or audio files on the client side. However, you can compress through a few workarounds:
1. Using the MediaRecorder API
This API is primarily for recording media streams, but you can specify codecs and bitrates to control the size and quality. It is mainly made for capturing in a compressed format than compressing existing files.
const options = { mimeType: 'video/webm; codecs=vp9', bitsPerSecond: 1000000 };
const mediaRecorder = new MediaRecorder(stream, options);
2. Manipulating video frames with Canvas API
You can draw video frames onto a canvas at a lower res and theb capture this as a new video stream. This method can reduce file size but is less efficient for high quality or long videos.
video.onplay = () => {
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth / 2;
canvas.height = video.videoHeight / 2;
const ctx = canvas.getContext('2d');
function drawFrame() {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
requestAnimationFrame(drawFrame);
}
drawFrame();
};
3. WebAssembly and JavaScript Libraries
For more heavy-duty compression, you can use libraries compiled to WebAssembly, like ffmpeg.js. These are more resource-intensive and may not be ideal for all scenarios.
- Example using FFmpeg.js:
import { FFmpeg } from '@ffmpeg/ffmpeg';
async function compressVideo(inputVideoPath, outputVideoPath) {
const ffmpeg = new FFmpeg();
await ffmpeg.load();
await ffmpeg.writeFile(inputVideoPath, await fetchFile(inputVideoPath));
await ffmpeg.exec(['-i', inputVideoPath, '-vcodec', 'libx264', '-crf', '28', outputVideoPath]);
const data = await ffmpeg.readFile(outputVideoPath);
}
compressVideo('input.mp4', 'compressed_output.mp4');
Ressources:
- https://github.com/ffmpegwasm/ffmpeg.wasm
- https://ffmpegwasm.netlify.app/docs/api/ffmpeg/classes/FFmpeg
- https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
- https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder