
Egor menutup tutup laptop dan menggosok mata merahnya karena kurang tidur. "Pelanggan terus mengeluh tentang pembekuan aliran, paket perbaikan baru tidak membantu sama sekali! Jadi apa yang harus dilakukan dengan HLS (disensor) ini?" Dia mengatakan ke dalam kekosongan penelitian.
Browser tidak hanya hypertext, tetapi juga streamer
Browser telah memperoleh pemain untuk waktu yang lama, tetapi dengan encoder video dan streaming ceritanya berbeda. Sekarang, di hampir semua peramban versi terbaru, Anda dapat menemukan modul untuk penyandian, pengaliran, pengodean dan pemutaran. Fungsi-fungsi ini tersedia melalui JavaScript API, dan implementasinya disebut Web Real Time Communications atau WebRTC. Pustaka yang dibangun dalam peramban ini dapat melakukan banyak hal: mengambil video dari kamera internal, virtual atau USB, kompres dengan codec H.264, VP8, VP9, ​​mengirimkannya ke jaringan melalui protokol SRTP, mis. berfungsi sebagai encoder streamer video perangkat lunak. Sebagai hasilnya, kami melihat browser yang memiliki sesuatu yang mirip dengan ffmpeg atau gstreamer di bawah kap, yang memampatkan video dengan baik, stream pada RTP dan memainkan stream video.
WebRTC memberi Anda kebebasan untuk menerapkan berbagai kasus streaming dalam JavaScript:
- streaming aliran dari browser ke server untuk merekam dan distribusi selanjutnya
- peer-to-peer
- putar aliran pengguna lain dan kirim sendiri (obrolan video)
- konversi protokol lain oleh server, misalnya RTMP, RTSP, dll., dan mainkan di browser sebagai WebRTC
Skrip kontrol aliran yang disempurnakan mungkin terlihat seperti ini:
HLS Bekerja Di Mana WebRTC Tidak Bekerja
WebRTC berfungsi di versi browser terbaru, namun ada dua faktor berikut: 1) Tidak semua pengguna memperbarui browser secara tepat waktu dan mungkin duduk di semacam Chrome selama tiga tahun. 2) Hampir seminggu sekali pembaruan dirilis dan browser baru, WebView, serta klien lain dan pengirim pesan instan yang dapat menjelajahi Internet. Tidak perlu dikatakan, tidak semua dari mereka memiliki dukungan WebRTC, dan jika ya, itu bisa sangat terpotong. Lihat bagaimana keadaannya sekarang:

Pisahkan sakit kepala - perangkat apel favorit semua orang. Mereka baru-baru ini menerima dukungan untuk WebRTC dan, kadang-kadang, mengejutkan dalam perilaku mereka dibandingkan dengan browser webkit Orthodox. Dan di mana WebRTC tidak berfungsi atau tidak bekerja dengan baik, HLS berfungsi dengan baik. Dalam hal ini, kompatibilitas diperlukan, dan sesuatu seperti konverter yang akan mengkonversi WebRTC ke HLS dan memutarnya di hampir semua perangkat.
Awalnya, HLS tidak dirancang untuk streaming real-time. Memang, apa yang bisa menjadi waktu video melalui HTTP? Tugas HLS adalah memotong video menjadi potongan-potongan dan mengirimkannya ke pemutar dengan lancar, tanpa terburu-buru, dengan mengunduh satu per satu. Pemain HLS mengharapkan aliran video yang terbentuk dengan lembut dan halus. Dan di sini konflik muncul, karena WebRTC, sebaliknya, dapat membiarkan dirinya kehilangan paket karena persyaratan waktu nyata dan latensi rendah dan memiliki FPS / GOP mengambang dan bit rate variabel - untuk menjadi kebalikan dari HLS dalam hal prediksi dan dimensi aliran.
Pendekatan yang jelas - depacketization WebRTC (SRTP) dan konversi berikutnya ke HLS, mungkin tidak berfungsi di pemutar HLS Apple asli atau bekerja dalam bentuk yang tidak sesuai untuk produksi dengan jalur. Pemain asli di sini berarti pemain yang digunakan di Apple iOS Safari, Mac OS Safari, Apple TV.
Oleh karena itu, jika Anda melihat heksing HLS pada pemain asli, mungkin ini dia, dan sumber alirannya adalah WebRTC atau aliran dinamis lain dengan markup yang tidak rata. Selain itu, dalam implementasi pemain Apple asli ada perilaku yang hanya bisa dipahami secara empiris. Misalnya, server harus mulai mengirim segmen HLS segera, segera setelah daftar putar m3u8 dikembalikan. Keterlambatan per detik mengancam dengan pembekuan. Jika konfigurasi bitstream telah berubah dalam proses (yang merupakan kejadian yang cukup umum dengan streaming WebRTC), juga akan ada dekorasi.
Bertarung melawan jalur pemain asli
Dengan demikian, depacketisasi dan paketisasi WebRTC langsung dan jujur ​​di HLS umumnya tidak bekerja. Di server video streaming Web Call Server (WCS) , kami memecahkan masalah dengan dua cara, dan kami menawarkan yang ketiga sebagai alternatif:
1) Transcoding.
Ini adalah cara paling andal untuk menyelaraskan aliran WebRTC ke persyaratan HLS, mengatur GOP, FPS yang diinginkan, dll. Namun, dalam beberapa kasus, transcoding bukanlah solusi yang baik, misalnya transcoding 4k stream video VR adalah ide yang begitu-begitu. Aliran berat seperti itu sangat mahal untuk ditranskrip dalam hal waktu CPU atau sumber daya GPU.

2) Adaptasi dan penyelarasan aliran WebRTC dengan cepat di bawah persyaratan HLS.
Ini adalah parser khusus yang menganalisis bitstream H.264 dan memperbaikinya untuk fitur / bug pemain HLS Apple asli. Di sini kita harus mengakui bahwa pemain non-asli seperti video.js dan hls.js lebih toleran terhadap stream dengan bitrate dinamis dan FPS, yang merupakan WebRTC dan tidak melambat di mana implementasi referensi Apple HLS pada dasarnya jatuh ke dalam pembekuan abadi.

3) Gunakan RTMP sebagai sumber aliran alih-alih WebRTC.
Terlepas dari kenyataan bahwa flashdisk dihentikan, protokol RTMP secara aktif digunakan untuk streaming, mengambil OBS Studio yang sama. Dan saya harus mengakui bahwa encoders RTMP secara umum menghasilkan lebih banyak stream daripada WebRTC dan oleh karena itu praktis tidak menghasilkan jalur di HLS, mis. Mengkonversi RTMP> HLS dari sudut pandang jalur terlihat jauh lebih cocok, termasuk di pemain HLS asli. Karena itu, jika streaming dilakukan dari desktop dan OBS, maka lebih baik menggunakannya untuk konversi ke HLS. Jika sumbernya adalah browser Chrome, maka RTMP tidak dapat digunakan tanpa menginstal plugin, dan di sini hanya WebRTC.

Ketiga metode yang dijelaskan di atas diuji dan berfungsi, sehingga ada peluang untuk memilih berdasarkan kondisi tugas.
WebRTC ke HLS di CDN
Beberapa masalah dapat menunggu dalam sistem terdistribusi ketika beberapa server pengiriman aliran WebRTC terletak antara sumber aliran WebRTC dan pemain HLS, yaitu CDN , dalam kasus kami, berdasarkan pada server WCS. Ini terlihat seperti ini: ada Origin - server yang menerima aliran WebRTC, ada Edge - server yang mendistribusikan aliran ini termasuk HLS. Mungkin ada banyak server, yang memungkinkan penskalaan horizontal sistem. Misalnya, 1000 server HLS dapat dihubungkan ke satu server Origin, dalam hal ini kapasitas sistem diskalakan 1000 kali.

Masalahnya telah diidentifikasi sedikit lebih tinggi, dan masalah ini biasanya muncul pada pemain asli: iOS Safari, Mac OS Safari, Apple TV. Maksud kami adalah pemain yang bekerja dengan indikasi langsung dari url daftar putar dalam tag, misalnya, <video src="https://host/test.m3u8"/>
. Segera setelah pemain meminta daftar putar, dan tindakan ini sebenarnya adalah langkah pertama dalam memainkan aliran HLS, server harus segera, tanpa penundaan, mulai mengirimkan segmen video HLS. Jika server tidak segera mulai memberikan segmen, pemain memutuskan bahwa ia telah ditipu dan berhenti bermain. Sekali lagi, perilaku ini adalah tipikal dari pemain HLS asli Apple, tetapi kami tidak dapat memberi tahu pengguna - “tolong jangan gunakan iPhone Mac dan Apple TV untuk memutar stream HLS”, pengguna tidak akan mengerti.
Jadi, ketika Anda mencoba memainkan aliran HLS di server Edge, server harus segera mulai mengembalikan segmen, tetapi bagaimana ia akan melakukannya jika tidak memiliki aliran? Memang, ketika mencoba memainkan streaming di server ini hilang. Logika CDN bekerja berdasarkan prinsip Pemuatan Malas - kami tidak akan mengarahkan aliran ke server sampai seseorang meminta aliran ini di server ini. Ada masalah yang menghubungkan pertama - yang pertama yang meminta aliran HLS dari server Edge dan memiliki kecerobohan untuk melakukan ini dari pemain asli Apple akan menerima dekorasi karena alasan bahwa butuh waktu untuk memesan aliran ini dari server Origin, untuk mendapatkannya pada Edge dan lanjutkan dengan mengiris HLS. Bahkan jika itu membutuhkan tiga detik, pemain tidak akan menyimpannya. Dia akan pergi ke dekorasi.

Di sini sekali lagi ada dua keputusan: satu adalah normal, yang lain tidak terlalu. Seseorang dapat meninggalkan pendekatan Pemuatan Malas di CDN dan mengirim lalu lintas ke semua node, terlepas dari apakah ada pemirsa di sana atau tidak. Sebuah solusi, mungkin cocok untuk mereka yang tidak terbatas pada sumber daya lalu lintas dan komputasi. Asal akan mengarahkan lalu lintas ke semua server Edge, sebagai akibatnya, semua server dan jaringan di antara mereka akan terus dimuat. Mungkin skema ini hanya cocok untuk beberapa solusi spesifik dengan sejumlah kecil arus masuk. Saat mereplikasi sejumlah besar utas, skema semacam itu jelas akan tidak efisien sumber daya. Dan jika Anda ingat bahwa kami hanya menyelesaikan "masalah koneksi pertama dari peramban asli", maka jelas bahwa itu tidak layak.

Pilihan kedua lebih elegan, tetapi juga solusinya. Kami memberi pengguna pertama gambar video yang terhubung, tetapi ini masih bukan aliran yang ingin dilihatnya - ini adalah preloader. Karena kita harus memberikan sesuatu sekarang dan melakukannya segera, tetapi kami tidak memiliki aliran sumber (masih dipesan dan dikirim dari Asal), kami memutuskan untuk meminta klien untuk menunggu sedikit dan menunjukkan kepadanya video preloader dengan animasi bergerak. Pengguna menunggu beberapa detik, preloader berputar, dan ketika aliran nyata tiba, pengguna mulai menunjukkan aliran nyata. Akibatnya, pengguna pertama melihat preloader, dan yang berikutnya yang terhubung pada akhirnya melihat aliran HLS normal yang berasal dari CDN, bekerja berdasarkan prinsip Lazy Loading. Masalah teknik diselesaikan.
Tetapi tidak sampai akhir
Tampaknya semuanya bekerja dengan baik. CDN berfungsi, aliran HLS diambil dari server Edge edge dan masalah koneksi pertama terpecahkan. Dan inilah jebakan lain - kami memberikan preloader dalam rasio aspek tetap 16: 9, dan CDN dapat menyertakan aliran format apa pun: 16: 9, 4: 3, 2: 1 (video VR). Dan ini adalah masalah, karena jika Anda memberi pemain preloader dalam format 16: 9, dan aliran yang dipesan akan dalam format 4: 3, maka pemain asli lagi menunggu dekorasi.
Oleh karena itu, tugas baru muncul - Anda perlu tahu dengan rasio aspek apa aliran memasuki CDN dan memberikan preloader dalam rasio yang sama. Fitur aliran WebRTC adalah pelestarian aspek rasio ketika mengubah resolusi dan selama transcoding - jika browser memutuskan untuk menurunkan resolusi, itu menurunkannya dalam rasio yang sama. Jika server memutuskan untuk mentranskode aliran, itu menjaga rasio aspek dalam proporsi yang sama. Oleh karena itu, masuk akal jika kita ingin menunjukkan preloader untuk HLS, kami menunjukkannya dalam rasio aspek yang sama di mana aliran masuk.

CDN berfungsi sebagai berikut: ketika lalu lintas memasuki server Origin, ia menginformasikan server lain di jaringan, termasuk server Edge, tentang aliran baru. Masalahnya adalah bahwa pada titik ini, resolusi aliran sumber mungkin belum diketahui. Resolusi dilakukan oleh konfigurasi H.264 bitstream bersama dengan bingkai kunci. Oleh karena itu, dapat terjadi bahwa server Edge menerima informasi bahwa ada aliran, tetapi tidak akan tahu tentang resolusi dan rasio aspeknya, yang tidak akan memungkinkannya untuk menghasilkan preloader dengan benar. Dalam hal ini, perlu memberi sinyal keberadaan aliran di CDN hanya jika ada bingkai kunci - ini dijamin untuk memberikan informasi ukuran server Edge dan memungkinkan preloader yang benar dihasilkan untuk mencegah "masalah penampil yang terhubung pertama".

Ringkasan
Konversi WebRTC ke HLS umumnya memberikan jalur ketika diputar di pemain Apple asli. Masalahnya diselesaikan dengan menganalisis dan menyesuaikan bitstream H.264 dengan persyaratan HLS Apple, baik transcoding, atau menggunakan migrasi ke protokol RTMP dan encoder sebagai sumber aliran. Dalam jaringan terdistribusi dengan lazy loading stream, ada masalah dengan viewer pertama yang terhubung, yang diselesaikan menggunakan preloader dan menentukan resolusi di sisi server Origin - titik masuk dari stream di CDN.
Referensi
Server Panggilan Web - Server WebRTC
Latensi Rendah WebRTC Streaming CDN - CDN Berbasis WCS
Putar stream video WebRTC dan RTMP melalui HLS - Fungsi server untuk mengonversi streaming dari berbagai sumber ke HLS