Masalah pemirsa pertama, atau kesulitan mengkonversi aliran video WebRTC ke HLS


George menutup laptopnya dan mengusap mata merahnya yang kurang tidur. "Pelanggan terus mengeluh tentang pembekuan aliran; paket perbaikan baru tidak membantu sama sekali! Apa yang harus saya lakukan dengan HLS (yang disensor) ini?" katanya.


Browser tidak hanya hypertext, tetapi juga streamer


Browser memiliki pemain untuk waktu yang lama, tetapi ceritanya berbeda dengan video encoder dan streaming. Sekarang, di hampir semua peramban versi terbaru, kita dapat menemukan modul untuk pengodean, streaming, 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, dan VP9, ​​dan kirimkan ke jaringan melalui protokol SRTP; yaitu, berfungsi sebagai encoder video streamer perangkat lunak. Akibatnya, kami melihat browser yang memiliki sesuatu yang mirip dengan ffmpeg atau gstreamer, kompres video dengan baik, stream pada RTP, dan memainkan stream video.


WebRTC memberi kami kebebasan untuk menerapkan berbagai kasus streaming dalam JavaScript:


  • streaming dari browser ke server untuk merekam dan distribusi selanjutnya
  • mendistribusikan aliran peer-to-peer
  • putar aliran pengguna lain dan kirim sendiri (obrolan video)
  • mengonversi protokol lain oleh server, misalnya RTMP, RTSP, dll., dan memutarnya di browser sebagai WebRTC

Skrip kontrol aliran yang disempurnakan mungkin terlihat seperti ini:


//Launching broadcast from browser to server session.createStream({name:”mystream”}).publish(); //Playing broadcast by the browser session.createStream({name:”mystream”}).play(); 

HLS berfungsi di mana WebRTC tidak berfungsi


WebRTC berjalan di versi browser terbaru, namun, ada dua faktor berikut: 1) Tidak semua pengguna memperbarui browser mereka secara tepat waktu dan mungkin menggunakan versi lama Chrome selama tiga tahun. 2) Pembaruan dan peramban baru, WebView, serta klien lain dan pengirim pesan instan yang membantu pengguna menjelajahi Internet dirilis hampir seminggu sekali. Tidak perlu dikatakan, tidak semua dari mereka memiliki dukungan WebRTC, dan jika mereka melakukannya, itu dapat dibatasi. Lihat bagaimana keadaannya sekarang:



Perangkat favorit semua orang oleh Apple bisa membuat sakit kepala. Mereka mulai mendukung WebRTC hanya baru-baru ini dan kadang-kadang, perilaku mereka dibandingkan dengan browser webkit mungkin tampak mengejutkan. Di mana WebRTC tidak berfungsi atau tidak bekerja dengan baik, HLS berfungsi dengan baik. Dalam hal ini, kompatibilitas diperlukan, dan sesuatu seperti konverter yang memungkinkan kita untuk mengkonversi WebRTC ke HLS dan memutarnya di hampir semua perangkat.


HLS pada awalnya tidak disusun untuk aliran waktu-nyata. Memang, bagaimana kita bisa melakukan streaming video real-time melalui HTTP? Tugas HLS adalah memotong video menjadi potongan-potongan dan mengirimkannya ke pemutar dengan lancar, tanpa terburu-buru, dengan mengunduhnya satu per satu. Seorang pemain HLS mengharapkan aliran video yang terbentuk dengan lembut dan halus. Di sini kita memiliki konflik, karena WebRTC, sebaliknya, dapat kehilangan paket karena persyaratan waktu nyata dan latensi rendah dan memiliki FPS / GOP mengambang dan laju bit variabel - menjadi kebalikan dari HLS dalam hal prediktabilitas dan keteraturan aliran.


Pendekatan yang jelas - Depacketization WebRTC (SRTP) dan konversi berikutnya ke HLS mungkin tidak berfungsi di pemutar HLS Apple asli atau bekerja dengan pembekuan, yang merupakan bentuk yang tidak cocok untuk produksi. Pemain asli berarti pemain yang digunakan di Apple iOS Safari, Mac OS Safari, dan Apple TV.


Oleh karena itu, jika Anda melihat pembekuan HLS pada pemain asli, mungkin ini masalahnya, 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 setelah daftar putar m3u8 dikembalikan. Penundaan 1 detik dapat menyebabkan pembekuan. Jika konfigurasi bitstream berubah dalam proses (yang cukup umum selama streaming WebRTC), juga akan ada pembekuan.


Melawan pembekuan di pemain asli


Dengan demikian, depacketisasi WebRTC dan paket HLS umumnya tidak berfungsi. 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 stream 4k
video VR memang ide yang buruk. Aliran berbobot seperti itu sangat mahal untuk ditranskrip dalam hal waktu CPU atau sumber daya GPU.



2) Menyesuaikan dan menyelaraskan aliran WebRTC saat bepergian agar sesuai dengan persyaratan HLS.


Ini adalah parser khusus yang menganalisis bitstream H.264 dan menyesuaikannya agar sesuai dengan fitur / bug pemain HLS asli Apple. Diakui, pemain non-asli seperti video.js dan hls.js lebih toleran terhadap stream
dengan bitrate dinamis dan FPS yang berjalan di WebRTC dan jangan memperlambat di mana implementasi referensi dari Apple HLS pada dasarnya menghasilkan pembekuan.



3) Menggunakan RTMP sebagai sumber aliran alih-alih WebRTC.


Terlepas dari kenyataan bahwa Flash player sudah usang, protokol RTMP aktif digunakan untuk streaming; ambil OBS Studio, misalnya. Kita harus mengakui bahwa encoders RTMP menghasilkan lebih banyak secara umum
stream daripada WebRTC dan karenanya praktis tidak menyebabkan pembekuan di HLS, mis. RTMP> Konversi HLS terlihat jauh lebih cocok dalam hal pembekuan, termasuk di pemain HLS asli. Karena itu, jika streaming
dilakukan dengan menggunakan 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 hanya WebRTC yang berfungsi dalam hal ini.



Ketiga metode yang dijelaskan di atas telah diuji dan berfungsi, sehingga Anda dapat memilih berdasarkan tugas.


WebRTC ke HLS di CDN


Ada beberapa hal yang tidak diinginkan yang akan Anda hadapi dalam sistem terdistribusi ketika ada beberapa server pengiriman aliran WebRTC antara sumber aliran WebRTC dan pemutar HLS, yaitu CDN , dalam kasus kami, berdasarkan pada server WCS. Ini terlihat seperti ini: Ada Origin - server yang menerima aliran WebRTC, dan ada Edge - server yang mendistribusikan aliran ini termasuk melalui 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 berskala 1000 kali.



Masalahnya sudah menjadi stabilo di atas; biasanya muncul di pemain asli: iOS Safari, Mac OS Safari, dan Apple TV. Maksud kami adalah pemain yang bekerja dengan indikasi langsung dari daftar putar url
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
tunda, mulailah mengirimkan segmen video HLS. Jika server tidak segera mulai mengirim segmen, pemain akan memutuskan bahwa ia telah ditipu dan berhenti bermain. Perilaku ini tipikal dari pemain HLS asli Apple, tetapi kami tidak bisa hanya memberi tahu pengguna "jangan gunakan iPhone Mac dan Apple TV untuk memutar stream HLS."


Jadi, ketika Anda mencoba memainkan aliran HLS di server Edge, server harus segera mulai mengembalikan segmen, tetapi bagaimana seharusnya melakukannya jika tidak memiliki aliran? Memang, ketika Anda mencoba memainkannya, di sana
tidak ada aliran di server ini. Logika CDN bekerja berdasarkan prinsip Lazy Loading - itu tidak akan memuat aliran ke server sampai seseorang meminta aliran ini di server ini. Ada masalah yang terhubung pertama kali
pengguna; orang pertama yang meminta aliran HLS dari server Edge dan memiliki kecerobohan untuk melakukan ini dari pemutar Apple default akan mendapatkan pembekuan karena itu akan membutuhkan waktu untuk memesan aliran ini
dari server Origin, dapatkan di Edge, dan mulai memotong HLS. Bahkan jika itu membutuhkan tiga detik, ini tidak akan membantu. Ini akan membeku.



Di sini kita memiliki dua solusi yang mungkin: satu baik-baik saja, dan yang lainnya kurang begitu. Seseorang dapat meninggalkan pendekatan Lazy Loading di CDN dan mengirim lalu lintas ke semua node, terlepas dari apakah ada pemirsa atau tidak. Sebuah solusi, mungkin cocok untuk mereka yang tidak terbatas pada sumber daya lalu lintas dan komputasi. Asal akan mengirim 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 aliran, skema seperti itu akan jelas
tidak efisien dalam hal sumber daya. Dan jika Anda ingat bahwa kami hanya menyelesaikan "masalah pengguna yang terhubung pertama dari browser asli," maka menjadi jelas bahwa itu tidak sepadan.



Pilihan kedua lebih elegan, tetapi juga hanya merupakan akhir-sekitar. Kami memberi pengguna pertama gambar video yang terhubung, tetapi ini masih bukan aliran yang ingin mereka lihat - ini adalah preloader. Karena kita harus memberi mereka sesuatu dan segera melakukannya, tetapi kami tidak memiliki aliran sumber (masih dipesan dan dikirim dari Asal), kami memutuskan untuk meminta klien untuk menunggu sedikit dan menunjukkan kepada mereka video dari
preloader dengan animasi bergerak. Pengguna menunggu beberapa detik sementara preloader berputar, dan ketika aliran sebenarnya akhirnya datang, pengguna mulai mendapatkan aliran nyata. Akibatnya, pengguna pertama akan melihat
preloader, dan mereka yang terhubung setelah itu akhirnya akan melihat aliran HLS biasa yang berasal dari CDN yang beroperasi berdasarkan prinsip Lazy Loading. Dengan demikian, masalah teknik telah terpecahkan.


Namun belum sepenuhnya terpecahkan


Tampaknya semuanya bekerja dengan baik. CDN berfungsi, aliran HLS dimuat dari server Edge, dan masalah pengguna terhubung pertama diselesaikan. Dan di sini ada perangkap lain - kita berikan
preloader dalam rasio aspek tetap 16: 9, sementara aliran format apa pun dapat memasukkan CDN: 16: 9, 4: 3, 2: 1 (video VR). Dan ini adalah masalah, karena jika Anda mengirim preloader dalam format 16: 9 ke pemain, dan aliran yang dipesan 4: 3, maka pemain asli akan sekali lagi menghadapi pembekuan.


Oleh karena itu, tugas baru muncul - Anda perlu tahu dengan rasio aspek apa aliran memasuki CDN dan memberikan rasio yang sama untuk preloader. Fitur aliran WebRTC adalah pelestarian rasio aspek saat
mengubah resolusi dan transcoding - jika browser memutuskan untuk menurunkan resolusi, itu menurunkannya dalam rasio yang sama. Jika server memutuskan untuk mentranskode aliran, itu mempertahankan rasio aspek dalam proporsi yang sama. Oleh karena itu, masuk akal bahwa jika kami 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
sumber aliran mungkin belum diketahui. Resolusi dilakukan oleh konfigurasi H.264 bitstream bersama dengan bingkai kunci. Oleh karena itu, server Edge dapat menerima informasi tentang streaming, tetapi tidak akan tahu tentang itu
resolusi dan rasio aspek, 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 pertama yang terhubung dengan penonton. . "



Ringkasan


Mengonversi WebRTC ke HLS umumnya menghasilkan pembekuan saat diputar di pemutar Apple bawaan. Masalahnya dipecahkan dengan menganalisis dan menyesuaikan bitstream H.264 dengan persyaratan HLS Apple, baik dengan ranscoding,
atau bermigrasi ke protokol RTMP dan pembuat enkode sebagai sumber aliran. Dalam jaringan terdistribusi dengan Lazy Loading of stream, ada masalah dengan viewer pertama yang terhubung, yang diselesaikan dengan menggunakan preloader dan menentukan resolusi pada sisi server Origin - titik masuk dari stream di CDN.



Server Panggilan Web - Server WebRTC


CDN untuk streaming WebRTC latensi rendah - CDN berbasis WCS


Memutar streaming video WebRTC dan RTMP melalui HLS - Fungsi server untuk mengonversi streaming dari berbagai sumber ke HLS

Source: https://habr.com/ru/post/id481668/


All Articles