Press ESC to close

206: Status Code Paling Licik di Dunia Video Browser

Salah satu bagian paling melelahkan dalam pengembangan NetMeter Web adalah menghitung bandwidth video di native player.

Jika chunked streaming HLS atau DASH masih bisa ditangkap lewat patch fetch/XHR dan worker, justru yang membuat kepala berdenyut adalah video klasik seperti (.mp4, .mkv, bahkan .3gp 😂) yang diputar melalui HTML5 player seperti Video.js, Fluid Player, dan teman-temannya.

Dan lagi-lagi, di situlah masalahnya dimulai. 😂

Mimpi Buruk Request Code 206

Pada contoh website yang memutar video .mp4 biasa, browser modern tidak pernah mengunduh file secara penuh.

Chrome akan melakukan range requests atau meminta sebagian file dalam potongan-potongan kecil.
Masalahnya disini, hampir semua response dari request media tersebut akan berstatus:

206 Partial Content

Secara teori, kita bisa saja membaca content-length dari setiap potongan request 206 itu lalu menghitungnya. Namun sayangnya, itu adalah kekeliruan besar.

Pada media streaming HTML5, ada alur tersembunyi yang tidak terlihat:

  • Browser melakukan buffering internal yang sangat agresif.
  • Player dapat meminta ulang potongan (chunk) berbeda tergantung seek.
  • Tidak semua segment muncul sebagai fetch/XHR dan sebagian besar di-handle langsung oleh mesin media Chrome, sehingga patch apapun akan buta terhadap hal ini.
Komparasi Flowchart antara Native Video Request vs HLS/Dash Streaming

Bahkan lebih buruknya lagi:

Request 206 untuk media tidak muncul di patcher fetch, tidak muncul di XHR, dan hanya sebagian yang tercatat di webRequest chrome api.

Inilah titik di mana saya mulai merasa: “Wah, ini bakal panjang lagi ceritanya” 😂.

By the way, saya pernah baca sumber artikel cukup menarik yang menceritakan alur yang cukup detail tentang bagaimana Chrome melakukan request terhadap media dengan 206, disini.

Eksperimen Penuh Frustasi

Selama beberapa hari, saya mencoba berbagai pendekatan dan ya…. semuanya gatot alias gagal total, meskipun sudah dibantu banyak pasukan AI. Inilah sedikit eksperimen dan cerita kegagalan saya:

1. Menghitung berdasarkan webRequest 206

Gagasan awalnya saya mengumpulkan semua potongan request dengan status-code 206 ber-tipe media, lalu menghitung totalnya saat onCompleted.

Masalahnya adalah:

  • Hasilnya tidak realtime. Karena request 206 saat player memainkan video itu bisa men-trigger onCompleted pada waktu yang tidak bisa kita kira-kira. Bisa 10 detik bisa juga 30 detik.
  • Jika tab ditutup mendadak, semua potongan yang sempat lewat API DevTools tidak pernah tercatat. Ini membuat perhitungan menjadi zonk dan nol. 😤
  • Banyak potongan request media men-trigger event onErrorOccured saat browser loading awal video HTML tersebut. Dan ini jelas tidak bisa kita hitung.

Status eksperimen: GAGAL.

2. PerformanceObserver

Sempat berharap pada PerformanceObserver, tapi ternyata pendekatan ini adalah pendekatan yang sangat random. Kadang muncul value, kadang nol. Beberapa data tidak bisa diakses karena CORS.

Sama sekali tidak bisa dijadikan landasan perhitungan bandwidth.

Status eksperimen: GAGAL.


Mengintip Dapur HTMLVideoElement

Setelah semua eksperimen diatas berakhir tanpa hasil, masih tersisa satu ide gila:

“Bagaimana jika kita tidak mengejar request-nya, tapi memantau proses decode video itu sendiri?”

Untungnya (Thanks to Chromium), Chrome menyediakan dua properti yang jarang dibahas tapi cukup sakti dan ciamik, karna dua properti ini hanya ada di Chromium based browser, yakni:

  • webkitVideoDecodedByteCount
  • webkitAudioDecodedByteCount

Dua properti di video ini saat kita listen menggunakan Chrome, angkanya terus bertambah setiap kali player memproses (decode) data.

Dengan kata lain:

Jika byte decode naik, berarti ada data yang benar-benar sudah diterima dari jaringan.

Dan meskipun ini bukanlah total download secara mentah (seperti yang terlihat di DevTools), tapi dua pahlawan itu pastinya sudah mewakili aliran data yang masuk secara realtime.

Dan dari sinilah patch baru NetMeter Web lahir.

Patch yang Melacak Setiap Video yang Diputar

Saya mencoba peruntungan dengan membuat sebuah loop kecil yang memonitor seluruh <video> di halaman:

  • Setiap detik, cek apakah ada video yang memuat file .mp4 atau tipe file video lain.
  • Jika ada, ambil byte decoded saat ini.
  • Lalu kita hitung delta dari detik sebelumnya.
  • Terakhir, kita hanya mengirim data jika video benar-benar melakukan buffering atau sedang diputar.

Untuk kalian yang penasaran, inti konsepnya kira-kira seperti ini:

const processVideo = (video) => {
  const decoded =
    video.webkitVideoDecodedByteCount +
    video.webkitAudioDecodedByteCount;

  const currentMB = decoded / (1024 * 1024);
  const delta = currentMB - lastReportedMB;

  if (delta > 0.1) {
    sendDataToListener(
      delta * 1024 * 1024 // ini adalah hasil delta yang bisa kita hitung
    );
  }

  lastReportedMB = currentMB;
};

Versi asli patch-nya tentu jauh lebih panjang (dengan validasi autoplay, loop, fluktuasi buffering, network state, dan sebagainya).

Tapi kurang lebih itulah rohnya.

Dengan pendekatan ini, NetMeter Web bisa menangkap bandwidth video klasik (.mp4, .mkv, .webm bahkan mungkin .3gp 😆) dengan akurasi:

≈ 90–95% mendekati total wire bandwidth Chrome

Apakah ini sempurna?
Belum. Karena Chrome punya banyak optimisasi internal yang tidak bisa kita lihat. Tapi untuk kasus yang sebelumnya mustahil, angka ini sudah sangat memuaskan.

Perlu diketahui, patch ini juga hanya aktif untuk direct video files, bukan HLS/DASH, karena format chunked modern tetap bisa dideteksi lewat patch fetch/XHR atau WASM worker seperti pada artikel sebelumnya.


Pelajaran Penting

Ini adalah salah satu perjalanan paling “membagongkan” selama mengembangkan NetMeter Web.
Request media dengan status-code 206 yang terlihat normal-normal saja dan aman, ternyata menyimpan hidden-gems.

Namun seperti biasa, kata-kata dari Pak Sopir hari ini adalah “Setiap masalah membuka pintu baru, setiap jalan buntu memaksa kita menemukan trik baru”.

Selamat bertugas!

Muhammad K Huda

A non exhausted blogger person within fullstack engineer (spicy food), open source religion, self-taught driver and maybe you know or don't like it. Simply says, Hello from Me!

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Cek untuk notifikasi e-mail jika komentar dibalas.

This site uses Akismet to reduce spam. Learn how your comment data is processed.