直播是一個龐大而復雜的業務形態,一個優秀的直播系統涉及眾多團隊的共同協作,有非常完整的直播鏈路。
那么,直播鏈路中都有哪些角色?這些角色要解決的是哪些問題?要優化某個環節時需要哪些角色的配合?這些角色優化鏈路的手段有哪些?……
想要厘清這些問題,對直播全鏈路接觸比較少的同學無疑要花費大量的時間才能完成。本文將從直播拉流切入,力求幫助有興趣的同學簡單明了而全面地理解整個直播鏈路。
為什么直播拉流是“最后一公里”
從整個直播鏈路來看,直播拉流作為直播內容觸達觀眾的最后一個環節,從客觀現實上來說,就是直播鏈路的“最后一公里”。
直播拉流作為整個直播鏈路的“最后一公里”,鏈路上任何一個前置環節出現問題,都會在拉流過程中體現出來。通過分析、理解拉流過程中產生的各類問題,會是理解直播鏈路最有效的方式之一。
作為直播內容消費的關鍵環節,如何優化這“最后一公里”上的各類體驗,是每個直播從業人員不斷探索的問題,從直播拉流理解怎么做好直播無疑是一個好的選擇。
從直播業務理解直播鏈路

上圖所示是從業務層面看到的一次直播觀播過程,也是對直播拉流的一個高度簡化。麻雀雖小,但五臟俱全,圖中顯式或隱式地涵蓋了整個直播鏈路幾乎所有關鍵角色和流程。
直播鏈路上的關鍵角色
客戶端
客戶端中囊括了直播鏈路中多個 SDK,包括直播中臺 SDK、直播推流 SDK,以及直播拉流 SDK。
直播中臺 SDK
直播中臺 SDK 封裝直播間內的所有業務邏輯,能夠串聯流調度與推拉流 SDK,給推拉流 SDK 提供日志上報、配置下發能力。
直播推流 SDK
直播推流 SDK 作為提供給中臺 SDK 的封裝層,提供采集、編碼、推流、連麥等能力,響應流調度下發的各種配置,例如推流分辨率、碼率、編碼方式等端上能力,完成推流過程中各類日志信息的采集并上報至中臺 SDK。
直播拉流 SDK
直播拉流 SDK 作為提供給中臺 SDK 的封裝層,提供直播拉流相關能力,同時封裝了超分、音量均衡等功能,響應流調度、settings 下發的配置,例如是否開啟硬解等端上能力,并完成拉流過程中各類日志信息的采集并上報至中臺 SDK。
CDN
CDN 全稱是 Content Delivery Network,即內容分發網絡。CDN 的核心任務是使內容傳輸的更快、更穩定。
整個直播系統中,源站提供了鑒權、轉碼、回調、禁播等能力。CDN 通過邊緣節點,在客戶端和源站之間增加一層緩存,請求過的數據會在邊緣節點緩存一段時間。
動態請求內容會直接回源拉取,CDN 優化整個傳輸鏈路,解決跨網訪問、傳輸擁塞等問題。
流調度
流調度主要處理與直播流管理相關的任務,內部封裝了多家 CDN 供應商,屏蔽了不同 CDN 的細節區別。滿足大規模的直播內容分發需求,同時保證了服務的高可用性。提供完整的解決方案,方便業務方快速接入直播業務。
關鍵流程
直播數據流
直播內容從生產到消費主要涉及到推流端、CDN%20(源站、邊緣節點)%20以及拉流端,如圖中實箭頭所示即為直播數據流方向,其中:
在推流端,推流%20SDK%20完成了主播的音視頻采集,添加美顏、濾鏡后,需要經過編碼、封裝,最終按照指定地址,向%20CDN%20邊緣節點推流;
收流邊緣節點在被動收到用戶的推流請求后,這個節點會主動地將這個流轉推(中繼)到上層節點,上層節點經過同樣的過程,最終將源流轉推到源站;
源站內部會進一步地將源流轉推至其他集群完成轉碼、錄制等任務;
在拉流端,拉流%20SDK%20會根據流地址向%20CDN%20邊緣節點拉流,此時根據這路流在該節點上的緩存命中情況,出現兩種結果:
如果命中緩存,則邊緣節點將直接返回緩存數據;
如果未命中緩存,邊緣節點將逐級進行回源,最終將流數據返回邊緣節點,最終返回播放器。
詞語釋義:
源流:推流端推出的那路流。
轉碼:當需要對源流的分辨率、碼率、編碼等參數進行修改時,就需要進行轉碼,例如媒體直播往往由專業設備或者三方推流器推出,碼率會非常高,直接拉源流會造成帶寬壓力過大,這時就需要轉碼。但轉碼任務本身也需要消耗資源,因此衍生出推流轉碼、拉流轉碼等不同轉碼策略。
回源:往往發生在拉流側,邊緣節點上未命中緩存時,就需要到源站找到所需要的流,該過程即為回源。在上圖中表示為虛箭頭。完成回源后,邊緣節點上會留下這路流的緩存。
流調度
在開播側,參與到整個流程的角色包括%20App、直播%20SDK、開播服務、房間服務以及流調度。各角色在開播中的工作如下:
主播在%20App%20發起開播請求;
開播服務收到開播請求后根據不同的場景,使用不同的發布點%20ID%20向流調度發起請求創建直播流;
流調度根據具體要使用的發布點生成對應的推流地址,在這個過程中完成調度,決定使用哪家%20CDN%20以及使用何種協議等;
開播服務將推流地址返回至%20App%20后,App%20開始推流、房間服務在推流成功后更新流狀態;
在看播側,參與到整個流程的角色包%20App、直播%20SDK、房間服務以及流調度,其中:
觀眾在%20App%20發起進房請求;
房間服務收到進房請求后,透傳請求中攜帶的用戶信息、向流調度請求拉流地址;
流調度收到請求后,根據用戶信息進行調度,決定下發的檔位信息、功能信息等,并返回至房間服務;
房間服務獲取到流信息后,完成檔位映射等邏輯,最終返回%20App;
App%20獲得流信息后透傳至直播%20SDK,并觸發播放。
流調度負責了與流管理相關的所有工作,包括流創建、流參數下發、流狀態管理、生成推拉流地址等,同時流調度在重;顒又幸财鹬e足輕重的作用。
了解流調度是如何進行調度的,最好的方式是從流調度返回的數據來理解。例如在拉流端,所有調度信息是封裝在%20stream_data%20中,隨房間服務接口返回,由中臺客戶端透傳給拉流%20SDK,主要包含了以下重要信息:
分辨率,除源流外,目前支持的檔位有UHD、HD、SD、LD、MD、AO、AUTO,其中
AO、MD%20僅在特殊情況下使用,例如后臺播放等不需要高碼率的情況
并以不同的標識符分別代表該檔位為%20H.265%20或%20H.264%20轉碼
主備,為滿足大型活動中的災備需求,下發流數據中會包含兩條線路–即主(Main)備(Backup)雙線,實際上進行了%20CDN%20調度
格式,在每個檔位的每條線路下,一般存在多種格式(format)供拉流使用,例如常規%20FLV、用于超低時延的%20RTM、以及時移直播%20TSL%20等
流調度參數,為直播拉流提供所需的各類參數,例如控制實際使用協議、格式等,在實現調度的同時,避免上層業務感知不必要的細節;此外可以根據具體的場景控制參數的生效范圍,實現從%20CDN%20維度到單路流維度的精準控制
流調度在直播日常業務中,除了要對線上的默認分辨率、碼率等進行控制之外,在重保活動中也起著舉足輕重的作用。
當預估帶寬很大時,往往需要多家%20CDN%20來共同分擔壓力,同時需要根據各家質量來調節占比;
為避免推流端故障往往需要一主一備兩路流的熱備方案(甚至還需要冷備),拉流端需要在其中一路發生故障時自行切換到另一路;
在帶寬壓力過大時,需要及時降低下發的默認清晰度以緩解帶寬壓力,同時在帶寬充足時提高默認清晰度以優化體驗。
詞語釋義
ABR:即自適應碼率,在直播間中作為%20AUTO%20分辨率檔位,但是%20stream_data%20中實際不會包含這樣一個檔位,原因在于%20ABR%20實際是將要使用的若干檔位拼裝成了一個%20MPD(Media%20Presentation%20Description)傳遞給播放器,播放器內部切檔時實際使用的是對應檔位的流地址。
日志與監控
端監控作為日志上報的起點,將客戶端產生的各類日志按照一定的規則(例如采樣率等),進行上報;根據不同的 log_type,上報的日志會被分流并寫入到 Kafka 的不同 topic 中;根據數據不同的消費場景及用途,日志會經歷一系列處理(例如在 Flink 任務中進行清洗等),并最終呈現到各類數據工具當中。
了解日志數據流對于定位日志相關的各類問題是非常有幫助的。例如在 Kibana 中找不到日志時,可以從日志是否上報(通過 Charles 抓取端監控 monitor 接口上報數據確認)、分流是否正確(通過檢查 log_type 確認,一般不會在該環節出現問題)、是否由于日志中存在非法字段而被清洗(通過檢查端監控中的原始日志確認)等。
從直播鏈路理解優化與問題
為什么拉不到流?
直播是一條完整的鏈路,鏈路上任何一個環節中斷都會導致拉流端出現拉流失敗的情況:
推流端-收流節點中斷:單路流所有檔位、所有觀眾將出現進房時拉不到流或直播間內卡頓;
收流節點-源站中斷:一般不會出現,故障源站上的所有流將出現異常;
轉碼異常:某一個或幾個轉碼檔位出現異常,源流正常,觀看轉碼檔位的觀眾報障;
源站-拉流節點中斷:從故障邊緣節點上拉流的全部觀眾將會異常;
拉流節點-拉流端中斷:單用戶拉流出現故障。
前述情況主要描述的鏈路上某個環節中斷導致的拉流失敗,有時拉流失敗其實是首幀耗時過長造成的,這種情況在拉流成功率指標波動分析時較為常見:首幀耗時增長導致了拉流成功率下降。
為什么首幀慢?
首幀分階段分析

以 HTTP-FLV 為例,從觸發播放器的 play 接口到最終完成首幀渲染,需要經歷以下這些過程:
DNS 解析: 決定了要從 CDN 的哪個邊緣節點拉流。這一過程在拉流 SDK 以及播放器內核中都會發生,后者往往是因為 SDK 層沒有解析到 IP 地址。DNS 解析耗時通常在 100ms 左右(localDNS,使用 HTTP-DNS 會進一步增加),因此 HTTP 場景下,我們可以采用 IP 直連的方式規避 DNS 耗時。
實現 IP 直連需要在拉流前獲取到 IP 地址,其關鍵在于 DNS 緩存(緩存之前的 DNS 解析結果,拉流 SDK 層的 DNS 策略)和 DNS 預解析(在 App 啟動之后一段時間,對可能用到的所有域名進行 DNS 解析并緩存結果,節點優選 SDK 的核心邏輯);
緩存的 DNS 結果會過期,尤其是 CDN 進行節點覆蓋調整時,緩存的 DNS 可能會導致調整不能及時生效,因此需要定期更新 DNS 結果;
用戶發生跨網時,由于運營商變化,也會導致此前緩存的 DNS 不可用,因此需要在網絡狀態發生變化時更新 DNS 結果。
TCP 建聯: 與邊緣節點建立 TCP 連接,這一過程的耗時主要是三次握手,耗時1-RTT。要優化建聯耗時,可以通過 TFO(TCP Fast Open,Wiki),或使用 UDP 協議(QUIC、KCP)。
TCP 首包: HTTP 響應完成,此時開始返回音視頻數據。如果此時邊緣節點上有這路流的緩存,那么將直接返回緩存數據;如果沒有命中緩存,TCP 首包返回之前將發生回源。要優化首包耗時,核心思路在于降低回源率,常見手段有增加邊緣節點緩存保持時間,對于大型活動提前進行預熱、以保證更多邊緣節點上有緩存。
視頻首包: 耗時主要發生在 avformat_find_stream_info 函數調用,播放器在播放前需要探測一定量的流數據,以確定流格式、編碼等流信息。由于目前在各個宿主中播放的格式相對固定,因此不需要探測過多的數據即可確定流信息。所以可以通過調節探測的數據量以優化視頻首包耗時。通過減小探測數據量,首包耗時下降 300ms 左右。
降低流數據探測的數據量也可能會帶來不良后果。當探測的數據量過少時,可能會導致讀取到的流信息不全,例如只探測到音頻數據、沒有探測到視頻數據(尤其是在音視頻數據交織不均勻的情況),最終出現有聲無畫或聲音正常、畫面卡住的問題。

視頻首幀解碼和視頻首幀渲染: 分別完成視頻首幀解碼和視頻首幀渲染,優化的主要方向是 decoder 及 render 實例的預初始化等。
快啟buffer
為了實現秒開,各家 CDN 都在邊緣節點上開啟了快啟 buffer 策略?靻 buffer 的核心邏輯是基于邊緣節點上的緩存(GopCache),調節緩存數據下發的具體數據范圍,同時保證視頻數據從關鍵幀開始下發?靻 buffer 也存在不同的策略,例如上限優先或下限優先,后者會要求對接的 CDN 廠商按照下限優先的原則下發緩存數據,比如下限 6s ,會先在緩存數據中定位最新 6s 的數據,然后向 6s 前的舊數據查找第一個關鍵幀下發(解碼器要從關鍵幀開始解碼,因此一定需要從關鍵幀開始下發)。

詞語釋義:
IP 直連: 即將 HTTP 地址中的 host 部分直接替換為對應的IP地址,并在 HTTP 請求的header中添加“Host”行,其值為原始的host,例如http://``x``.``x``.``x``.``x``/``app``/``stream`` .flv "Host: ``pull-host``.com\r\n"。前述方法最為規范,有的 CDN 也會支持在 host 前直接插入 IP 的方式實現 IP 直連,但該方法并不通用,因此并不建議使用前插 IP 的方法。
為什么會卡頓?
拉流發生卡頓的直接原因是播放器中的緩存耗盡,此時播放器卡住其實是在進行 Rebuffering 。
導致 buffer 耗盡的直接原因是播放器中 buffer 消費的速度高于 buffer 接收的速度:最為常見的例子就是當前拉流端的帶寬顯著低于視頻的碼率。同時,在帶寬充足的情況下,鏈路上前置環節的中斷也有可能導致拉流端卡頓。
因此為了對抗卡頓,一個最直接的方法就是在播放器中緩存更多數據,以期在緩存數據耗盡之前渡過網絡波動。最直接的做法就是增大播放器的最大緩存,使播放器能夠緩存足夠多的數據。
但直播場景的特殊性在于直播內容是實時產生的,在最大緩存允許的情況下,播放器中的緩存完全取決于當前鏈路上有多少緩存(還記得 GopCache 嗎)。
在播放器數據消費速度不變、帶寬充足的情況下,播放器在獲得了鏈路上所有的緩存后,buffer長度將不再變化,也就意味著播放器只能依賴這些緩存來對抗卡頓。在能獲得的緩存總量有限的情況下,進一步增強現有的緩存對抗卡頓能力的手段就是調整播放器消費數據的速度,例如在首幀之后判斷當前水位( buffer 長度)以決定是否起播(對應起播 buffer 策略),或在水位較低時降低播放速度(對應網絡自適應策略)。
在有限的帶寬條件下,如果能夠更有效的利用帶寬、采用更加高效的傳輸協議,也可以有效地對抗弱網條件下的卡頓問題。因此 KCP、QUIC、QUICU 等相較于 TCP 更加高效的協議被應用到了音視頻傳輸當中。除此之外,在特定的帶寬情況下選擇合適的碼率,也是降低卡頓的有效手段之一,因此ABR也在直播中得到了應用。
實際上“卡頓”在用戶反饋中涵蓋的情況很多,例如:App 本身的卡頓,或者 CDN 某些操作(數據積壓時丟棄視頻數據造成的視頻卡住、聲音正常,或者在數據積壓時主動使播放器報錯發生重試進而導致播放器出現鬼畜),甚至視頻本身幀率較低,都會導致用戶出現“卡頓”的感覺。為了更加貼近用戶對于卡頓的感受,我們增加了視頻渲染卡頓這一指標。
為什么有延遲?
為了對抗卡頓,我們需要在直播鏈路中增加緩存,但是緩存的引入必然導致延遲的增加。
例如在抖音上線低延遲 FLV 之前,端到端延遲在5~8s,而這些延遲的引入主要原因就在于 CDN 邊緣節點上的 GopCache --只有緩存到足夠的數據才會進行下發,在這個過程中便引入了時延(當然不管是推流端采集、服務端中間鏈路都會引入延遲,但是相對于緩存引入的延遲影響較小)。
在客戶端播放速度不變的情況下,延遲會一直保持下去,另外在發生卡頓(且未觸發重試)時延遲會不斷累積。
因此通過調節邊緣節點的 GopCache 大小可以直接影響到鏈路上的端到端延遲。與此同時,Gop 的大小也會影響到不同用戶之間的延遲差,在具體場景中就體現為兩個觀眾的延遲存在差異(比如內購會別人看到主持人說了“3、2、1,開搶”,你才看到“3”),兩名觀眾進入直播間的時間差即使很短,但是延遲差可能達到一個 Gop(以下圖為例,假設快啟 buffer 下限為 1.3s ,用戶分別在 1.2s 和 1.4s 進入直播間,延遲分別是多少?)。
為了更好地保證觀眾端的延遲體驗,我們在全面梳理了線上的延遲產生原因,實現了低延遲 FLV 方案,使得線上端到端延遲由 7s 左右下降至 3.5s 左右,并在抖音取得了顯著的 QoE 正向收益;與此同時,RTM 低延遲拉流方案也在穩步推進中。
如何判斷拉流異常問題的發生環節?
問題定位一般流程
如前文所述,直播是一個全鏈路的業務形態,尤其是拉流端處在整個鏈路的末端,各個環節的問題都會導致拉流端出現異常。因此如何根據現有信息及工具來定位問題的根源,便是解決問題的關鍵。定位問題一般要經歷以下過程:
對于各類問題,首先需要的是明確的case與信息,針對具體case,需要的信息有:
拉流端device_id或user_id
問題現象描述(至少提供roomID或者流名)
問題發生時間
最好提供錄屏
在Trace平臺,根據前述信息檢索相關日志,可以根據問題現象進一步查找對應的事件(對應event_key字段)
拉不到流?找到play_stop事件
根據first_frame_blocked字段判斷首幀卡在哪個階段
根據code字段判斷錯誤碼是什么(錯誤碼是0?還記得拉不到流的部分原因是首幀慢嗎?)
首幀慢?找到first_frame事件
根據前文中分階段耗時對應的字段,尋找存在顯著異常的階段
卡頓?找到stall事件
根據流名查詢對應時間點推流端的推流情況,是否推流端卡頓
根據拉流端在問題時間段前后的日志信息判斷是持續性卡頓、短時間波動還是流相關卡頓
如果找不到stall事件,只有render_stall,那么可能的原因就是發生了丟幀
例如花屏、綠屏之類的問題,在日志上一般沒有特別明顯的錯誤,此時可以通過查看流回放判斷源流是否有異常。如果源流回放沒有異常,且用戶播放轉碼流,且流已經結束的情況下,就需要運營同學持續關注相關反饋,盡可能保留現場(因為轉碼流不會進行錄制)。
問題范圍與定位方向
除了前述定位問題的一般過程,問題發生的范圍也是快速定位問題的有效依據。一般有以下判斷方法,根據問題(同一時間段)發生在不同用戶或場景判斷:
所有主播及觀眾 --> 這種情況非常少見,如果出現,一般意味著出現了整個系統級別的問題
單個主播的所有觀眾 --> 推流端本身或推流端到邊緣節點或源站引起,如果到邊緣節點日志正常,一般為源站問題
同一CDN下的多個主播的所有觀眾 --> 收流節點問題(收流節點相同)或源站問題(收流節點不同)
單個主播的部分觀眾(僅轉碼流觀眾或僅源流觀眾) --> 源站轉碼問題(默認分辨率的存在導致判斷易受影響,如果只有轉碼流播放,那么發生問題即使的是源流,最終反饋問題的也只有轉碼流觀眾)
單個主播的部分觀眾(某一地區) --> 分發CDN問題,一般是某一節點問題,層級因地區而異
單個主播的部分觀眾(CDN聚集) --> 分發CDN問題,這種情況一般出現在活動,有多家CDN參與分發
全量用戶(或有版本等特征)某一時間點后 --> 基本是放量引起的
某些版本一段時間出現激增并驟降 --> 一般是流相關的問題,在某些版本觸發了異常
問題定位的經驗是需要不斷積累的,不可能一蹴而就;除經驗外,還需要深入理解各個角色在整個鏈路中的作用,根據問題的表現推測根因,再基于推測進行佐證。
止損手段
推拉流 SDK 對于新功能都會添加各類開關,以保證功能上線后、出現異常時可以及時關閉進行止損。但是對于一些新問題或者一些歷史問題,如果沒有相應開關進行控制時,對于業務線會造成不同程度的影響。
這類問題一般會是流相關的,且在測試階段隱蔽性高(測試階段沒有辦法百分之百覆蓋到這些流問題,尤其是新問題)、突發性強(往往隨直播開播時發生、關播時結束)。這類問題在初步分析問題、確定問題可以通過調度等手段解決時,可以嘗試與轉碼、流調度配合完成這類問題的及時止損。隨后在新版本進行問題修復。
總結
在實際的直播相關業務開發過程中,還有許許多多有趣且值得深入挖掘的內容,這篇文章僅僅是對直播鏈路做了一個簡單的概覽,力求幫助沒有直播開發相關經驗的朋友對直播全鏈路有一個全局性的理解,相信各位朋友在理解了直播全鏈路之后,對于直播體驗優化或問題排查一定能夠更加得心應手。
文章內容僅供閱讀,不構成投資建議,請謹慎對待。投資者據此操作,風險自擔。
海報生成中...
海藝AI的模型系統在國際市場上廣受好評,目前站內累計模型數超過80萬個,涵蓋寫實、二次元、插畫、設計、攝影、風格化圖像等多類型應用場景,基本覆蓋所有主流創作風格。
IDC今日發布的《全球智能家居清潔機器人設備市場季度跟蹤報告,2025年第二季度》顯示,上半年全球智能家居清潔機器人市場出貨1,2萬臺,同比增長33%,顯示出品類強勁的市場需求。