1 poin oleh GN⁺ 2025-12-24 | 1 komentar | Bagikan ke WhatsApp
  • Helix adalah platform AI yang menampilkan kepada pengguna layar tempat agen coding otonom berjalan di cloud, sehingga transmisi layar jarak jauh yang stabil menjadi hal yang krusial
  • Ketika streaming berbasis WebRTC gagal karena pemblokiran UDP dan batasan firewall di jaringan perusahaan, tim membangun pipeline H.264 berbasis WebSocket, tetapi latensi menjadi sangat parah di lingkungan Wi-Fi yang tidak stabil
  • Alih-alih struktur encoding·decoding yang kompleks, mereka menemukan bahwa pendekatan sederhana berupa mengirim screenshot JPEG secara berkala lewat HTTP jauh lebih stabil dan efisien
  • Pendekatan ini menggunakan bandwidth lebih sedikit, tidak memerlukan pemulihan frame yang rusak, dan secara otomatis menyesuaikan kualitas gambar serta frame rate sesuai kondisi jaringan
  • Pada akhirnya, Helix mengadopsi arsitektur hibrida yang memakai H.264 saat koneksi bagus dan beralih ke polling JPEG saat koneksi buruk, sehingga menghasilkan sistem streaming jarak jauh yang sederhana namun praktis

Masalah dan batasan streaming di Helix

  • Helix adalah platform yang harus membagikan layar agen AI untuk coding yang berjalan di sandbox cloud secara real-time
    • Pengguna menonton proses AI menulis kode layaknya remote desktop
  • Awalnya mereka memakai WebRTC, tetapi koneksi gagal karena UDP diblokir di jaringan perusahaan
    • Server TURN, STUN/ICE, dan port kustom semuanya diblokir oleh kebijakan firewall
  • Karena itu mereka langsung mengimplementasikan pipeline streaming H.264 berbasis WebSocket yang hanya memakai HTTPS (port 443)
    • Hardware encoding dengan GStreamer + VA-API, decoding di browser dengan WebCodecs
    • Mencapai 60fps, 40Mbps, dan latensi di bawah 100ms

Latensi jaringan dan penurunan performa

  • Di lingkungan jaringan yang tidak stabil seperti kedai kopi, muncul masalah video berhenti atau tertunda hingga puluhan detik
    • WebSocket berbasis TCP membuat frame tertunda secara berurutan saat terjadi packet loss, sehingga sifat real-time runtuh
    Iklan
  • Menurunkan bitrate tidak menyelesaikan latensi dan hanya menurunkan kualitas gambar
  • Mereka juga mencoba mengirim hanya keyframe, tetapi gagal karena protokol Moonlight memerlukan P-frame

Penemuan pendekatan screenshot JPEG

  • Saat debugging, mereka memanggil endpoint /screenshot?format=jpeg&quality=70 dan gambar yang tajam langsung dimuat
    • Satu JPEG berukuran 150KB tampil tanpa latensi
  • Dengan sekadar mengulang request HTTP untuk memperbarui screenshot, mereka bisa mendapatkan pembaruan layar yang mulus di kisaran 5fps
  • Pada akhirnya, mereka beralih dari pipeline video yang kompleks ke pendekatan request JPEG berkala (fetch loop)

Kelebihan pendekatan JPEG

  • Poin perbandingan utama terhadap H.264
    • Bandwidth: H.264 tetap di 40Mbps, JPEG bervariasi antara 100~500Kbps
    • Manajemen status: H.264 bergantung pada status, JPEG adalah frame independen sepenuhnya
    • Kemampuan pemulihan: H.264 perlu menunggu keyframe, JPEG langsung pulih di frame berikutnya
    • Kompleksitas: H.264 butuh pengembangan berbulan-bulan, JPEG cukup diimplementasikan dengan beberapa baris loop fetch()
  • Semakin buruk kualitas jaringan, pendekatan JPEG yang sederhana justru lebih stabil dan efisien
Iklan

Struktur perpindahan hibrida

  • Helix secara otomatis berpindah antara dua metode ini berdasarkan RTT (round-trip time)
    1. RTT < 150ms → streaming H.264
    2. RTT > 150ms → polling JPEG
    3. Saat koneksi pulih, pengguna dapat mengklik untuk beralih kembali
  • Event input (keyboard·mouse) tetap dikirim lewat WebSocket sehingga interaktivitas tetap terjaga
  • Server menghentikan pengiriman video dan beralih ke mode screenshot dengan pesan {"set_video_enabled": false}

Masalah ketidakstabilan perpindahan (oscillation) dan solusinya

  • Ketika trafik WebSocket berkurang setelah pengiriman dihentikan, latensi ikut turun dan menyebabkan loop tak berujung yang otomatis kembali ke mode video
  • Solusinya: setelah masuk ke mode screenshot, sistem tetap dipertahankan sampai pengguna mengklik
    • UI menampilkan pesan “video dijeda untuk menghemat bandwidth”

Masalah dukungan JPEG dan proses build

  • Tool screenshot untuk Wayland, grim, di paket bawaan Ubuntu menonaktifkan dukungan JPEG
    • Saat menjalankan grim -t jpeg, muncul error “jpeg support disabled”
  • Untuk mengatasinya, mereka membangun grim langsung dari source di Dockerfile dengan menyertakan libjpeg-turbo8-dev
Iklan

Arsitektur akhir

  • Koneksi bagus: H.264 60fps, hardware acceleration
  • Koneksi buruk: polling JPEG 2~10fps, sepenuhnya andal
  • Kualitas screenshot disesuaikan otomatis berdasarkan waktu transmisi
    • Jika melebihi 500ms, kualitas -10%; jika di bawah 300ms, +5%; minimum 2fps dipertahankan

Pelajaran utama

  1. Solusi sederhana bisa lebih baik daripada sistem yang kompleks — 3 bulan pengembangan H.264 kalah praktis dibanding 2 jam hacking JPEG
  2. Graceful degradation adalah inti dari pengalaman pengguna
  3. WebSocket optimal untuk pengiriman input, tetapi tidak wajib untuk pengiriman video
  4. Paket Ubuntu bisa saja kehilangan fitur — bila perlu, build sendiri
  5. Pengukuran wajib dilakukan sebelum optimasi — streaming kompleks bukan satu-satunya solusi

Rilis open source

  • Helix tersedia sebagai open source, dan implementasi intinya adalah sebagai berikut
    • api/cmd/screenshot-server/main.go — server screenshot
    • MoonlightStreamViewer.tsx — logika klien adaptif
    • websocket-stream.ts — kontrol perpindahan video
  • Helix sedang dikembangkan dengan tujuan membangun infrastruktur AI yang juga berfungsi di lingkungan nyata

1 komentar

 
GN⁺ 2025-12-24
Komentar Hacker News
  • Saat jaringan buruk, penurunan performa JPEG itu bukan karena UDP, melainkan karena cara implementasi TCP
    JPEG tidak menyelesaikan masalah buffering atau kontrol kemacetan. Kemungkinan besar implementasinya dibuat dengan struktur yang meminimalkan pengiriman frame
    h.264 memiliki efisiensi encoding yang lebih tinggi daripada JPEG. Dengan ukuran yang sama, frame IDR h.264 bisa menghasilkan kualitas yang lebih baik
    Masalah mendasarnya adalah tidak adanya estimasi bandwidth. Bahkan di lingkungan TCP, bitrate bisa disesuaikan melalui probe bandwidth awal dan deteksi latensi transmisi
    Jika memungkinkan, lebih baik memakai WebRTC, dan untuk menghindari firewall, WebSocket adalah pilihan yang baik

    • Dalam kode polling yang muncul di artikel, permintaan berikutnya baru dikirim setelah unduhan JPEG sebelumnya selesai. Loop seperti ini tetap bisa dibuat tanpa UDP
    • Kemungkinan besar frame diserialkan sepenuhnya sehingga hanya diminta satu per satu, atau setiap kali membuka koneksi baru dengan permintaan GET baru
    • Hal yang menarik adalah, bahkan JPEG yang secara visual sama bisa diperkecil hingga sekitar 10~15% dari ukuran semula. Saat mengerjakan optimisasi performa web di akhir 2000-an, peningkatan efisiensi seperti ini terasa sangat memuaskan
  • Terlepas dari masalah format tulisan atau gaya LLM, banyak bagian dari isinya yang keliru
    10Mbps seharusnya cukup untuk layar statis. Masalahnya adalah pengaturan encoding yang salah atau kualitas encoder yang rendah
    Pendekatan “kirim keyframe saja” itu tidak efisien; sebagai gantinya, cukup atur interval keyframe yang pendek
    Pada akhirnya, masalahnya adalah struktur yang mendorong seluruh stream lewat satu koneksi TCP tunggal. Solusi seperti DASH untuk situasi seperti ini sudah ada

    • Saya tidak paham kenapa tulisan buatan AI bisa naik ke atas. Membaca tulisan yang dibuat tanpa kesungguhan rasanya hanya membuang waktu
    • Di Apple, DASH tidak didukung. HLS bisa menjadi alternatif, tetapi tanpa ffmpeg implementasinya sangat sulit
    • Justru tulisan ini hampir tidak terasa bergaya LLM. Kritik tanpa dasar tidak terlalu meyakinkan
    • Karena waktu dan biaya untuk mempelajari alat yang sudah ada itu besar, “menciptakan ulang dengan cara yang salah” pun dalam situasi tertentu bisa lebih efisien
  • Mungkin ada baiknya melihat cara yang sudah dipakai VNC sejak 1998
    Dengan tetap memakai model pull di sisi klien, framebuffer dibagi ke dalam unit tile, lalu hanya bagian yang berubah yang dikirim
    Pada layar coding yang statis, ini bisa sangat mengurangi bandwidth. Jika ditambah deteksi scroll, hasilnya akan lebih efisien lagi

    • Di antara berbagai usulan, ini tampaknya titik awal yang paling realistis. Menjadikan 40Mbps sebagai asumsi dasar terasa seperti pendekatan masalah yang salah sejak awal
    • Tulisan itu terasa masih belum matang. Saya penasaran apakah pendekatan seperti ini juga bisa dilakukan dengan open source
    • Saya sarankan melihat proyek neko terlebih dahulu. Dibanding VNC, proyek itu jauh lebih baik dalam menangani latensi koneksi dan backpressure
    • Meniru pendekatan VNC tampaknya percobaan pertama yang paling alami. Memakai solusi latensi rendah untuk game seperti Moonlight justru terasa kurang tepat
  • Saya pernah menangani video encoding sebelumnya, dan 40Mbps itu sudah setara kualitas Blu-ray
    Untuk streaming teks sederhana, itu berlebihan. Setelah berdiskusi dengan Claude, kesimpulannya adalah 30FPS, GOP 2 detik, dan rata-rata sekitar 1Mbps sudah cukup
    Bahkan dalam kasus terburuk, 1.2Mbps sudah cukup untuk menjaga kualitas yang stabil

  • Masalah inti tulisan ini adalah bandwidth minimum h.264 diatur terlalu tinggi
    H.264 jauh lebih efisien daripada JPEG. Seharusnya mulai dari 1Mbps lalu disesuaikan
    Menggunakan keyframe saja justru tidak efisien

    • Di tulisan itu disebutkan “saat diturunkan ke 10Mbps, muncul jeda 30 detik”, tetapi ini kemungkinan besar masalah pengaturan encoding
    • JPEG pun bisa mengurangi masalah tersendat jika buffering dipakai untuk membuat antrian pemutaran. Pemutar modern memantau kualitas jaringan secara real-time
  • Kalau saya, saya akan mengambil pendekatan yang sepenuhnya berbeda
    10Mbps itu berlebihan, dan video coding di YouTube pada 1080p saja ada yang hanya sekitar 0.6Mbps. Tetap cukup tajam
    Saya justru merasa lebih baik menurunkan ke 1fps atau menyesuaikan interval keyframe

    • Gaya bahasa dan alur logika tulisannya tercium bau LLM. Kodenya kemungkinan juga setingkat itu
    • 1fps mungkin tidak cukup. Diperlukan pengaturan agar semua frame menjadi keyframe
    • Tapi bagi sebagian orang, kualitas YouTube pun bisa terasa begitu mengganggu sampai sulit ditoleransi
  • Melakukan streaming video real-time ke browser memang benar-benar menyiksa
    Jika screenshot JPEG bekerja dengan baik, lebih baik biarkan saja begitu
    Stack seperti gstreamer atau Moonlight akan menjadi neraka untuk di-debug jika Anda tidak memahami backpressure dan propagasi error
    Kombinasi NVIDIA Video Codec SDK + WebSocket + MediaSource Extensions adalah alternatif yang realistis
    Tetapi jika tulisan itu memang hasil LLM, penulisnya tampaknya tidak akan punya niat untuk memahami struktur internal seperti ini

    • Saat sistem yang rumit seperti ini harus ditangani untuk tujuan tunggal, justru LLM bisa berguna
  • Dulu saya pernah memakai program yang mengambil screenshot setiap 5 detik, dan hard disk cepat penuh
    Setelah sadar bahwa sebagian besar gambar itu sama, saya mulai memikirkan algoritma yang hanya menyimpan bagian yang berubah
    Lalu saya sadar bahwa saya sedang menciptakan ulang kompresi video
    Satu baris ffmpeg menyelesaikan semuanya, dan menghemat 98% ruang penyimpanan

  • Men-streaming video LLM yang sedang mengetik pada 40Mbps itu bandwidth yang sangat berlebihan dan tidak normal

    • Apalagi menontonnya pada 60fps sebagai “adegan komputer sedang mengetik” juga terasa aneh. Pendekatan ini tampak benar-benar tidak memahami domain masalahnya
  • Satu-satunya cara mendapatkan jawaban bagus di HN adalah mengunggah tulisan yang salah
    Menurut saya, tulisan yang salah tapi menarik justru contoh keseimbangan sempurna untuk memancing diskusi