當(dāng)前位置:首頁>職場>快手怎么錄制電腦游戲教程(一人單刷雨課堂需要多少工作量)
發(fā)布時(shí)間:2024-01-24閱讀(22)
機(jī)器之心發(fā)布
機(jī)器之心編輯部
昨天,清華自動(dòng)化大一學(xué)生的 C 大作業(yè)霸占了知乎榜首,該作業(yè)要求學(xué)生寫一個(gè)類似于「雨課堂」的網(wǎng)絡(luò)教學(xué)軟件(雷課堂),可以共享屏幕、語音直播、在線答題……其實(shí)現(xiàn)難度、工作量似乎都超出了大一學(xué)生的能力范圍,連清華特獎(jiǎng)得主、阿里 P6 也表示無法單獨(dú)完成。離提交 deadline 只剩五六周,這個(gè)作業(yè)真能寫完嗎?

在昨天的討論區(qū),我們看到大部分評(píng)論都是對(duì)于這一作業(yè)的吐槽。不過也有人提醒大家,為什么不試一試呢?畢竟,作業(yè)還是要交的。

作為雨課堂的技術(shù)支持方,快手的音視頻工程師范威給出了自己的專業(yè)回答。范威有著十多年的工作經(jīng)驗(yàn),在春節(jié)后深度參與了雨課堂和快手項(xiàng)目的聯(lián)合開發(fā),為雨課堂提供了音視頻底層技術(shù)支持。
根據(jù)范威的介紹,總共需要 2 周開發(fā)時(shí)間,就能擁有一個(gè)雷課堂。當(dāng)然,前提是「這些知識(shí)你都學(xué)過」,還要有「豐富的踩坑經(jīng)驗(yàn)」。
小伙伴們是不是心動(dòng)了?下面來看具體分析。
一個(gè)人單擼一個(gè)雷課堂需要多少工作量?
雨課堂是清華大學(xué)研發(fā)的一款在線教育 APP,可以支持老師在線授課、分享 PPT,學(xué)生與老師進(jìn)行語音互動(dòng)。從音視頻角度來看,這種在線授課的形式其實(shí)就是一個(gè)標(biāo)準(zhǔn)的視頻會(huì)議場景。
要說如何從頭開始擼一個(gè)視頻會(huì)議軟件,需要分前端和后端來說。這里前端指的是終端,后端指的是媒體服務(wù)器。前端的主要功能是負(fù)責(zé)音視頻通信,后端的主要功能是負(fù)責(zé)媒體流的轉(zhuǎn)發(fā)。
先說說前端。前端模塊包括音視頻采集、前處理、編解碼、收發(fā)包等功能模塊。目前開源的視頻會(huì)議項(xiàng)目以 webrtc 最為流行,其代碼里有 80w 行之多。要想單手從頭擼一個(gè)視頻會(huì)議終端,雖說不需要 80w 行代碼那么多,但是還是有其難度的。
采集模塊
首先是平臺(tái)的支持。iOS、Android、Windows、Mac、Linux,不同平臺(tái)提供的音視頻技術(shù)都不盡相同。音視頻的采集和前處理,需要根據(jù)不同的平臺(tái)和機(jī)型進(jìn)行適配,有些算法可以采用平臺(tái)的能力,而有些算法需要通過軟件進(jìn)行處理。
先來說一下采集和前處理模塊。視頻通過調(diào)用系統(tǒng) API 完成攝像頭數(shù)據(jù)的采集,這里不詳細(xì)說,感興趣的同學(xué)可以自行查閱官方文檔。視頻前處理包括各種美顏濾鏡算法,由于教育場景下這個(gè)功能不是剛需故而跳過。
這里說一下音頻前處理。在實(shí)時(shí)語音通話時(shí),從麥克風(fēng)直接采集到的音頻是包含自己說話的聲音以及對(duì)方說話的聲音的。這是因?yàn)楸镜氐膿P(yáng)聲器播放出對(duì)方的聲音也會(huì)被麥克風(fēng)采集進(jìn)去。如果不加任何處理就發(fā)送出去的話,對(duì)方會(huì)從揚(yáng)聲器里聽到自己說話,這種情況稱為聲學(xué)回聲(Echo)。為了得到一個(gè)比較自然的通話效果,需要對(duì)麥克風(fēng)采集的音頻數(shù)據(jù)進(jìn)行處理,消除掉對(duì)方說話的部分,只保留本地的聲音。這個(gè)過程叫做回聲消除(AEC,Acoustic Echo Cancellation)。AEC 算法最常用的方式是采用自適應(yīng)濾波器來產(chǎn)生一個(gè)模擬回聲,然后再從麥克風(fēng)采集信號(hào)中將這個(gè)模擬回聲抵消掉,達(dá)到消除回聲的目的。

單線 AEC 架構(gòu)
在實(shí)際項(xiàng)目中,還會(huì)對(duì)信號(hào)做一個(gè) NLP(非線性濾波)來消除殘余回聲,同時(shí)為了增強(qiáng)信噪比還會(huì)做聲學(xué)降噪和自動(dòng)增益,統(tǒng)稱為 3A(AEC/AGC/ANS)。目前幾乎所有的智能手機(jī)和 Mac 平臺(tái)都有硬件的 3A 算法模塊,其中蘋果的設(shè)備調(diào)校的比較好,而 Android 手機(jī)的 3A 效果良莠不齊,通常需要通過軟件自己實(shí)現(xiàn)。最快的實(shí)現(xiàn)方式是采用系統(tǒng)提供的 3A 算法,這里算 1 個(gè)人天。
編碼模塊
接下來是編解碼模塊。編解碼是將經(jīng)過前處理的音視頻原始數(shù)據(jù)進(jìn)行壓縮,以達(dá)到網(wǎng)絡(luò)傳輸?shù)哪康摹S捎诰W(wǎng)絡(luò)資源的限制,原始的音視頻數(shù)據(jù)量太大,不能直接在網(wǎng)絡(luò)上進(jìn)行傳播,必須先經(jīng)過壓縮。壓縮分為無損壓縮和有損壓縮。音視頻數(shù)據(jù)通常采用有損壓縮的方式,可以做到非常大的壓縮比。視頻編碼算法常用的有 H.264/H.265/VP8/VP9/AV1/AVS2 等等,音頻的壓縮算法有 AAC/Speex/Opus/G.711/G.729 等。現(xiàn)在通常采用的視頻壓縮算法是 H.264/H.265,而音頻算法則大都采用 Opus。
壓縮算法的細(xì)節(jié)非常繁雜,目前大多采用比較成熟的開源項(xiàng)目來實(shí)現(xiàn),比如 x264,x265,ffmpeg 以及 libopus。蘋果設(shè)備也提供了內(nèi)置的硬件視頻編解碼器 videotoolbox 可以支持 H.264/H.265 的實(shí)時(shí)編解碼,而 Android 則有 MediaCodec 提供相同的能力。在桌面平臺(tái)上,Intel 和 NVIDIA 的很多芯片提供了 qsv 和 nvenc 功能,用于實(shí)現(xiàn)桌面端的硬件視頻編解碼。有了編碼器之后,還需要對(duì)編碼參數(shù)進(jìn)行正確的配置,以適合實(shí)時(shí)通信的場景。主要影響音視頻通話體驗(yàn)的參數(shù)就是碼率,在其他參數(shù)不變的條件下,碼率越大音視頻質(zhì)量就越好,而使用的網(wǎng)絡(luò)帶寬也越大。
這里為了簡化實(shí)現(xiàn),使用系統(tǒng)提供的編解碼器實(shí)現(xiàn),算 1 個(gè)人天。
傳輸模塊
經(jīng)過編碼之后的音視頻數(shù)據(jù)已經(jīng)小了很多,可以進(jìn)行網(wǎng)絡(luò)傳輸了。Internet 網(wǎng)絡(luò)傳輸協(xié)議分為 TCP 和 UDP 兩種方式。TCP 協(xié)議是可靠傳輸,保證數(shù)據(jù)的完整性和有序性,但是缺點(diǎn)是在公網(wǎng)傳輸時(shí)速度比較慢,延時(shí)比較大。而 UDP 協(xié)議是不可靠協(xié)議,數(shù)據(jù)只管發(fā),不能保證一定能夠到達(dá)對(duì)方,但是優(yōu)點(diǎn)是發(fā)送速度快,延時(shí)低。因此在實(shí)時(shí)音視頻通信里,都會(huì)優(yōu)先使用 UDP 協(xié)議進(jìn)行數(shù)據(jù)發(fā)送。UDP 數(shù)據(jù)是以數(shù)據(jù)包為單位進(jìn)行發(fā)送的,每次發(fā)送一個(gè)包,最大包大小不能超過 64K 字節(jié)。但是由于 IP 層的分片路由限制,通常一個(gè) UDP 數(shù)據(jù)包的大小都會(huì)限制在一個(gè) MTU(Max Transmission Unit)以內(nèi)。以太網(wǎng)的 MTU 為 1500 字節(jié),因此每個(gè) UDP 包的大小大多都會(huì)限制在 1K 字節(jié)左右。而編碼后的視頻數(shù)據(jù)相對(duì)于這個(gè)大小還是太大了,需要對(duì)視頻數(shù)據(jù)進(jìn)行進(jìn)一步的分包才能進(jìn)行發(fā)送。
由于 UDP 協(xié)議的特性是不可靠傳輸,因此數(shù)據(jù)包達(dá)到的先后順序也沒有保證。為了讓對(duì)方收到的音視頻數(shù)據(jù)的先后順序跟發(fā)送端一致,需要在接收端對(duì) UDP 包進(jìn)行排序。在視頻會(huì)議上,通常會(huì)采用 RTP 協(xié)議對(duì)分包之后的數(shù)據(jù)包進(jìn)行一層封裝,每個(gè) RTP 包都包含一個(gè) RTP 頭,里面為每個(gè) RTP 包分配了一個(gè)序列號(hào)。這個(gè)序列號(hào)是有序遞增的,因此接收端可以通過收到的 RTP 包的序列號(hào)對(duì)數(shù)據(jù)包進(jìn)行排序,同時(shí)也可以知道哪些序號(hào)的數(shù)據(jù)包沒有收到,從而向發(fā)送端請(qǐng)求重發(fā)。
上面提到 UDP 在網(wǎng)絡(luò)傳輸過程中可能會(huì)丟包。由于音視頻編碼后的數(shù)據(jù)需要完整接收才能進(jìn)行正常解碼,因此采用 UDP 協(xié)議傳輸?shù)?RTP 包需要能夠處理丟包恢復(fù)。丟包恢復(fù)的方式有兩種,一種是 FEC(前向糾錯(cuò)),一種是 ARQ(自動(dòng)重傳),通常項(xiàng)目上這兩個(gè)方法會(huì)同時(shí)采用。
FEC 是對(duì)一組 RTP 包進(jìn)行冗余編碼,產(chǎn)生出一些冗余包,冗余包包含了這一組 RTP 包的信息,在丟包的時(shí)候可以利用冗余包里的數(shù)據(jù),恢復(fù)出這一組 RTP 包數(shù)據(jù)。常用的 FEC 算法包括 RS、卷積碼、噴泉碼等。FEC 的好處是不會(huì)引入額外的延時(shí),冗余包和數(shù)據(jù)包一起發(fā)送給對(duì)端,對(duì)端通過接收到的數(shù)據(jù)包和冗余包嘗試恢復(fù),沒有額外的交互時(shí)間,但由于網(wǎng)絡(luò)丟包的隨機(jī)性,并不是每一個(gè) FEC 包都能夠被利用,這樣降低了整體的帶寬利用率
ARQ 則是精準(zhǔn)的請(qǐng)求丟失的 RTP 包,讓發(fā)送端重新發(fā)送。在 RTP 協(xié)議里,可以通過 NACK 來實(shí)現(xiàn)重傳請(qǐng)求,攜帶上請(qǐng)求重傳的 RTP 序列號(hào)。發(fā)送端接收到 NACK 請(qǐng)求后,會(huì)重新發(fā)送該序列號(hào)對(duì)應(yīng)的 RTP 包到對(duì)端。NACK 和重傳包的傳輸引入了額外的延時(shí),因此 ARQ 會(huì)導(dǎo)致音視頻通信的延時(shí)增加,但是帶寬利用率比較高。
對(duì)于差一些的網(wǎng)絡(luò),網(wǎng)絡(luò)的帶寬并沒有那么高,如果發(fā)送端編碼的音視頻數(shù)據(jù)超過了其發(fā)送的上行帶寬,就會(huì)導(dǎo)致網(wǎng)絡(luò)擁塞,產(chǎn)生丟包和卡頓。為了防止網(wǎng)絡(luò)擁塞的發(fā)生,發(fā)送端需要對(duì)自己的上行網(wǎng)絡(luò)帶寬進(jìn)行預(yù)測,并反饋給編碼器,調(diào)整編碼器的碼率不要超過帶寬上限。這個(gè)算法叫做帶寬估計(jì)。帶寬估計(jì)是實(shí)時(shí)音視頻通信非常重要的一個(gè)算法,其準(zhǔn)確性會(huì)很大程度上影響用戶體驗(yàn)。帶寬估計(jì)算法的策略有很多,webrtc 中采用的是 google 提出的 GCC(Google Congestion Control)算法。
整個(gè)傳輸模塊沒有現(xiàn)成的開源項(xiàng)目可用,要么自己擼要么參考 webrtc 的實(shí)現(xiàn),大概需要 3-5 天。

緩沖隊(duì)列
到這里,發(fā)送端模塊基本就介紹完了,下面說一些接收端要做的部分。接收端在接收到 RTP 數(shù)據(jù)包之后,首先根據(jù) RTP 的序列號(hào)進(jìn)行排序,如果有丟包,則通過 FEC 和 ARQ 進(jìn)行恢復(fù)和重傳。得到完整有序的 RTP 包之后,對(duì) RTP 包進(jìn)行重組,組合成編碼后的音視頻數(shù)據(jù)。由于網(wǎng)絡(luò)傳輸?shù)牟环€(wěn)定性,收到的數(shù)據(jù)并不是均勻的,有可能一會(huì)兒接收的快,一會(huì)兒接收的慢,造成數(shù)據(jù)接收的波動(dòng)。這種現(xiàn)象被稱為網(wǎng)絡(luò)抖動(dòng)(Jitter)。如果這時(shí)候直接進(jìn)行解碼播放,那么會(huì)導(dǎo)致視頻忽快忽慢,聲音出現(xiàn)變聲的現(xiàn)象。為了平滑這種網(wǎng)絡(luò)抖動(dòng),接收端需要有一個(gè)緩沖隊(duì)列,將接收到的音視頻數(shù)據(jù)放入到緩沖隊(duì)列中,然后再勻速的從隊(duì)列中取出,從而得到比較平滑的音視頻數(shù)據(jù)進(jìn)行播放。
從緩沖隊(duì)列取出的數(shù)據(jù)就可以進(jìn)行解碼了。解碼就是解壓縮的過程,將發(fā)送端壓縮的數(shù)據(jù)還原成原始的音視頻數(shù)據(jù),才能在本地進(jìn)行播放。一些編碼算法(例如 H.264/H.265/Opus)為了提高壓縮比,在壓縮時(shí)對(duì)于前后連續(xù)的兩幀音視頻數(shù)據(jù)做了參考,這樣就導(dǎo)致采用這類壓縮算法的編碼數(shù)據(jù)在解碼的時(shí)候存在參考關(guān)系的依賴,只有前一個(gè)數(shù)據(jù)被正確解碼,后一個(gè)數(shù)據(jù)才能也正確的解碼。但是由于網(wǎng)絡(luò)丟包,即使采用了 FEC 和 ARQ 等丟包恢復(fù)策略,仍然有部分音視頻數(shù)據(jù)無法完整的達(dá)到接收端。這時(shí)候如果強(qiáng)行解碼,那么視頻會(huì)出現(xiàn)花屏,而聲音會(huì)出現(xiàn)爆音。為了解決這個(gè)問題,對(duì)于不連續(xù)的視頻數(shù)據(jù),接收端需要向發(fā)送端請(qǐng)求編碼一個(gè)關(guān)鍵幀視頻數(shù)據(jù)。這個(gè)關(guān)鍵幀數(shù)據(jù)在解碼的時(shí)候不會(huì)參考其他視頻數(shù)據(jù)幀,同時(shí)可以被后續(xù)的編碼視頻幀參考,這樣可以解決后續(xù)視頻的參考關(guān)系問題。而音頻可以通過 PLC(Packet Loss Concealment)算法,根據(jù)波形產(chǎn)生出丟失的音頻數(shù)據(jù)。
這里可以參考 webrtc 的 neteq 隊(duì)列來實(shí)現(xiàn)(沒錯(cuò),只有 webrtc 開源,所以同學(xué)們沒有別的參考),大概需要 3 天
本地播放
最后就是本地播放解碼出的音視頻數(shù)據(jù)。在播放的時(shí)候,音視頻數(shù)據(jù)在網(wǎng)絡(luò)傳輸上并不一定是相同的速度,因此可能會(huì)產(chǎn)生音畫不同步的問題。這里還需要一個(gè)音視頻同步模塊,來控制音視頻播放的速度,保證聲音和視頻可以對(duì)齊。在對(duì)齊的時(shí)候,由于人耳對(duì)于音頻的快慢變化更加敏感,所以總是調(diào)整視頻的速度來對(duì)齊音頻。在每個(gè)音視頻數(shù)據(jù)中,都會(huì)帶一個(gè)時(shí)間戳(timestamp),這個(gè)時(shí)間戳是音頻和視頻數(shù)據(jù)采集時(shí)生成的,相同的時(shí)間戳的音視頻應(yīng)該同時(shí)播放才能保證音畫同步。因此在播放視頻幀的時(shí)候,需要對(duì)比當(dāng)前播放的音頻的時(shí)間戳,調(diào)整視頻播放的速度。
視頻在屏幕上播放的時(shí)候,其顯示的分辨率大小可能與實(shí)際編碼的分辨率大小不一致。視頻分辨率代表的是視頻像素點(diǎn)的個(gè)數(shù),分辨率越高越清晰。對(duì)于現(xiàn)在的手機(jī)和顯示器來說,大多支持 HDPI,通過更加密集的像素點(diǎn)得到更加清晰細(xì)膩的圖像。而攝像頭采集和編碼的視頻分辨率并不會(huì)特別高,那么在顯示的時(shí)候需要對(duì)視頻進(jìn)行放大。不同的視頻放大算法對(duì)于清晰的影響比較大,默認(rèn)的 linear 放大算法會(huì)導(dǎo)致圖像比較模糊,采用復(fù)雜的放大算法,比如 bicubic,lanzcos,spline 等,可以得到更加清晰的畫面,而一些特殊內(nèi)容采用特定的算法會(huì)得到更好的視覺效果(比如人臉部分采用 softcubic 可以達(dá)到美顏效果)。
這里不考慮實(shí)現(xiàn)效果的話,用最簡單的 opengl 渲染視頻,大概 2 天。

這樣,一個(gè)簡簡單單的實(shí)時(shí)音視頻通信的終端部分就開發(fā)完了,再配上一個(gè)炫酷拉風(fēng)的界面,就可以食用了。但是這里只能實(shí)現(xiàn)兩個(gè)人之間的通信,而在線授課的場景可是一個(gè)老師對(duì)一群學(xué)生。如何實(shí)現(xiàn)多人之間的實(shí)時(shí)通信呢?這就需要后端的媒體服務(wù)器作中轉(zhuǎn)來實(shí)現(xiàn)。
媒體后端
這里需要簡單介紹一下多人實(shí)時(shí)音視頻通信的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)。對(duì)于三人以上的實(shí)時(shí)通信,由于接收端同時(shí)會(huì)接收多個(gè)人傳過來的音視頻數(shù)據(jù),因此如果沒有服務(wù)器中轉(zhuǎn)的話,需要采用網(wǎng)狀拓?fù)浣Y(jié)構(gòu),每個(gè)終端的音視頻流都需要同時(shí)發(fā)送給其他所有終端,網(wǎng)絡(luò)帶寬成倍增加。為了解決這個(gè)問題,就需要采用星型拓?fù)浣Y(jié)構(gòu),所有的終端將自己的音視頻數(shù)據(jù)發(fā)送給中央服務(wù)器,再由服務(wù)器來做轉(zhuǎn)發(fā)。這個(gè)服務(wù)器就是視頻會(huì)議的后端,暨媒體服務(wù)器。
媒體服務(wù)器的實(shí)現(xiàn)方式有兩種。一種叫做 MCU 模式,一種叫 SFU 模式。
MCU 模式是服務(wù)器將所有人的音視頻數(shù)據(jù)在服務(wù)端進(jìn)行解碼,然后合成為一個(gè)新的音視頻流。這個(gè)視頻流是由所有人的視頻組合出來的,而音頻則是將所有人的音頻混合,之后重新進(jìn)行音視頻編碼,再發(fā)送給所有終端。這樣終端播放出來的音視頻流就是一個(gè)合并好的音視頻流。這種模式對(duì)于媒體服務(wù)器的性能消耗很大,因此一臺(tái)服務(wù)器并不能支持很多的終端。
SFU 模式則只是做 RTP 包的轉(zhuǎn)發(fā),并不做解碼和合流的工作。每個(gè)終端同時(shí)會(huì)接收到多個(gè)人的音視頻流,每一組音視頻流需要獨(dú)立進(jìn)行處理和解碼,然后在本地混合后播放出來。這種模式的 SFU 性能消耗比較低,能夠支持的并發(fā)很高。
如果不考慮高并發(fā)和架構(gòu)設(shè)計(jì),最簡單的實(shí)現(xiàn)大概 3 天。

把這樣一個(gè)媒體服務(wù)器部署到網(wǎng)絡(luò)上,然后由它來轉(zhuǎn)發(fā)所有終端的音視頻數(shù)據(jù)包,這樣就可以實(shí)現(xiàn)多人之間的音視頻通信了。
總共需要 2 周開發(fā)時(shí)間,一個(gè)最最簡單的雷課堂就實(shí)現(xiàn)完成了。
當(dāng)然,這里只是為了完成作業(yè)從功能角度來實(shí)現(xiàn)。在實(shí)際項(xiàng)目中,需要考慮到性能和架構(gòu)優(yōu)化,增強(qiáng)穩(wěn)定性和音視頻質(zhì)量,服務(wù)端高并發(fā)和快速部署,各種算法參數(shù)調(diào)優(yōu)和策略優(yōu)化。沒有幾十人團(tuán)隊(duì)精細(xì)打磨 2-3 年,以及專業(yè)的音視頻質(zhì)量測試實(shí)驗(yàn)室,不可能做到業(yè)界頂尖水準(zhǔn)。
快手與雨課堂
為什么快手對(duì)于雨課堂這么熟悉?2 月 11 日,這家公司成為了清華大學(xué)慕課平臺(tái)「學(xué)堂在線」的獨(dú)家直播技術(shù)合作平臺(tái),致力于以直播技術(shù)驅(qū)動(dòng)優(yōu)質(zhì)教育課程更廣更快傳播。學(xué)堂在線旗下的雨課堂現(xiàn)在同時(shí)服務(wù)國內(nèi) 500 所高校線上授課,涵蓋國內(nèi) 90% 的 985 及 211 高校。
在疫情期間,全國大學(xué)有超過 100 萬堂課在雨課堂開課,近 4000 萬的大學(xué)生都在這里上課,其中在武漢地區(qū)開播 14000 次。快手的直播技術(shù)給這些線上的課程提供技術(shù)支持,讓老師和學(xué)生們?cè)诰€上開展教學(xué)時(shí)有良好的音視頻體驗(yàn)。

快手通過自身在直播平臺(tái)長期的技術(shù)積累,在推流工具、擁塞控制算法、智能 CDN 分發(fā)、質(zhì)量監(jiān)控、后端服務(wù)基礎(chǔ)架構(gòu)等全鏈路對(duì)雨課堂進(jìn)行了技術(shù)支持,確保了雨課堂大規(guī)模同時(shí)開課的穩(wěn)定性和流暢度。
歡迎分享轉(zhuǎn)載→http://m.avcorse.com/read-216786.html
Copyright ? 2024 有趣生活 All Rights Reserve吉ICP備19000289號(hào)-5 TXT地圖HTML地圖XML地圖