FFmpeg.wasm: Analisis Teknologi WebAssembly untuk Menjalankan FFmpeg di Browser

FFmpeg.wasm adalah versi alat pemrosesan audio dan video sumber terbuka terkenal FFmpeg yang dikompilasi ke WebAssembly melalui Emscripten. Teknologi ini memungkinkan browser untuk melakukan operasi kompleks seperti dekode video, transkode, dan penggabungan langsung di sisi klien tanpa bergantung pada server backend.
Tautan Proyek: github.com/ffmpegwasm/ffmpeg.wasm
Arsitektur Tradisional vs Arsitektur FFmpeg.wasm
Arsitektur Tradisional (Backend Transcoding):
Pengguna → Unggah Video → Server FFmpeg → Output → Pengguna Unduh
Masalah: Konsumsi sumber daya CPU server tinggi, biaya bandwidth mahal, masalah privasi
Arsitektur FFmpeg.wasm:
Pengguna → FFmpeg.wasm di Browser → Output Blob → Pengguna Unduh
Kelebihan: Nol biaya server, jaminan privasi, dapat digunakan secara offline
Inti Teknologi: Apa itu WebAssembly?
WebAssembly (Wasm) adalah format biner tingkat rendah yang dirancang agar kode dari bahasa yang dikompilasi (seperti C, C++, Rust) dapat dijalankan di browser dengan kecepatan mendekati aplikasi asli (native).
Kode sumber FFmpeg ditulis dalam bahasa C. Toolchain Emscripten dapat mengompilasi kode C tersebut menjadi modul biner .wasm, yang bekerja bersama kode perekat (glue code) JavaScript (ffmpeg-core.js) untuk dijalankan di lingkungan browser.
Dua Mode Operasi FFmpeg.wasm
Mode Single-threaded (Utas Tunggal)
import { FFmpeg } from '@ffmpeg/ffmpeg';
import { toBlobURL } from '@ffmpeg/util';
const ffmpeg = new FFmpeg();
await ffmpeg.load({
coreURL: await toBlobURL(
'https://unpkg.com/@ffmpeg/[email protected]/dist/esm/ffmpeg-core.js',
'text/javascript'
),
wasmURL: await toBlobURL(
'https://unpkg.com/@ffmpeg/[email protected]/dist/esm/ffmpeg-core.wasm',
'application/wasm'
),
});
- Tidak membutuhkan
SharedArrayBuffer - Tidak membutuhkan Header HTTP khusus (COOP/COEP)
- Semua operasi dilakukan dalam satu thread JS (Worker)
- Cocok untuk deploy di kebanyakan situs statis (Cloudflare Pages, GitHub Pages, dll.)
Mode Multi-threaded (Banyak Utas)
await ffmpeg.load({
coreURL: 'ffmpeg-core-mt.js', // core versi multi-threaded
wasmURL: 'ffmpeg-core-mt.wasm',
workerURL: 'ffmpeg-core-mt.worker.js',
});
- Menggunakan
SharedArrayBufferuntuk berbagi memori di antara beberapa Web Worker - Memerlukan server untuk mengatur Header HTTP berikut:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
- Peningkatan kecepatan yang signifikan (dapat memanfaatkan CPU multi-core)
- Namun pengaturannya lebih kompleks dan beberapa CDN tidak mendukungnya
Sistem File Virtual (Emscripten FS)
FFmpeg.wasm tidak memiliki akses langsung ke disk lokal. Ia menggunakan Virtual File System (VFS) dari Emscripten untuk mensimulasikan operasi disk:
// Menulis ArrayBuffer ke VFS virtual
await ffmpeg.writeFile('input.ts', new Uint8Array(buffer));
// Menjalankan perintah FFmpeg (beroperasi di VFS virtual)
await ffmpeg.exec(['-i', 'input.ts', '-c', 'copy', 'output.mp4']);
// Membaca output
const data = await ffmpeg.readFile('output.mp4');
// Membersihkan memori (Penting!)
await ffmpeg.deleteFile('input.ts');
await ffmpeg.deleteFile('output.mp4');
Kunci: Data dalam VFS berada di dalam JavaScript Heap. Data harus dihapus secara manual setelah selesai digunakan, jika tidak maka akan membebani memori browser sampai halaman ditutup.
Batasan Memori dan Praktik Terbaik
Ini adalah batasan bawaan terbesar dari FFmpeg.wasm:
| Item | Batasan |
|---|---|
| Batas Atas JS Heap | Sekitar 1-2 GB (Tergantung browser dan OS) |
| Model Memori Wasm | Alamat 32-bit, batas atas modul tunggal 4 GB |
| Memori Tersedia Riil | Biasanya 500 MB - 1.5 GB |
Skenario Penggunaan yang Disarankan
- ✅ Video di bawah 720p, durasi kurang dari 30 menit
- ✅ Fokus utama pada concat (penggabungan fragmen), bukan transcoding ulang
- ✅ Riset teknis dan pengujian tautan publik
- ❌ Video panjang 4K/1080p (Memori tidak cukup)
- ❌ Filter kompleks dan encoding ulang (Kecepatan terlalu lambat)
Praktik Terbaik Manajemen Memori
// 1. Unduh secara bertahap, hindari menampung semua ArrayBuffer sekaligus
const BATCH = 5;
for (let i = 0; i < segments.length; i += BATCH) {
const batch = await downloadBatch(segments.slice(i, i + BATCH));
// Segera tulis ke VFS, ArrayBuffer di sisi JS dapat didaur ulang
for (const [idx, buf] of batch.entries()) {
await ffmpeg.writeFile(`seg${i + idx}.ts`, new Uint8Array(buf));
}
}
// 2. Segera bersihkan VFS setelah operasi selesai
await ffmpeg.deleteFile('output.mp4');
Perbandingan dengan API Backend
| Aspek | FFmpeg.wasm | API Backend |
|---|---|---|
| Biaya Server | Nol | Tinggi (Padat CPU) |
| Privasi | 100% (Pemrosesan Lokal) | Harus mempercayai server |
| Kecepatan Proses | Lambat (Wasm Utas Tunggal) | Cepat (Multi-core + GPU) |
| Dukungan File Besar | Dibatasi memori browser | Hampir tanpa batas |
| Kompleksitas Deploy | Sangat simpel (Aset Statis) | Memerlukan pemeliharaan server |
| Skenario Terbaik | Konversi skala kecil, alat riset | Pemrosesan massal lingkungan produksi |
Implementasi Nyata: Cara Kerja Situs Ini
Alat Riset HLS di situs ini menggunakan kombinasi berikut:
- @ffmpeg/ffmpeg 0.12.x (Single-threaded, tidak butuh COOP/COEP)
- @ffmpeg/core 0.12.x (Wasm Core yang sesuai)
- Dimuat secara dinamis melalui unpkg CDN, pemuatan awal sekitar 15-30 detik (Modul Wasm sekitar 30MB)
- Menjalankan
ffmpeg -f concat -safe 0 -i concat.txt -c copy output.mp4untuk menyelesaikan penggabungan TS
Bacaan Lebih Lanjut
Ingin menguji tautan M3U8 Anda sekarang?
🚀 Uji Pemutar M3U8 Online Sekarang