返回部落格

為什麼影片畫質會在播放中途改變:自適應位元率串流解析

自適應位元率串流(ABR)是挑選你的連線能維持的畫質等級的邏輯。白話文說明 YouTube、Netflix 和 Twitch 如何決定接下來要送什麼給你。

By

你看 YouTube 影片看到一半,畫面突然從銳利變模糊。幾秒後又爬了回來。你沒碰任何控制項。角落的 Wi-Fi 圖示看起來沒事。剛才發生了什麼?

你目睹了一個自適應位元率串流演算法在你面前工作。每個現代串流播放器背後,都有一個安靜的迴圈在測量你的網路、把數字與服務提供的預先編碼畫質變體選單比對,並在數學說要切換時悄悄切換。當你的連線抖動,播放器切到較小變體以避免播放停頓。當連線恢復,它又爬回來。多數時候你不會察覺。你會察覺的時候,是切換大到看得見的時候。

自適應位元率串流(ABR)是現代播放器於同一段影片預先編碼的不同畫質變體間切換的技術——為每個片段挑你的連線能維持的最高變體——讓播放在混亂的真實網路中持續流動。

本指南將走過畫質在播放中途切換時實際發生了什麼:服務如何為同一標題編碼多個變體、播放器如何測量頻寬並決定下一步要抓什麼、演算法為什麼有像 BOLA 和 MPC 這樣的名字、你在真實世界中在哪裡遇到 ABR,以及若你想儲存一段以這種方式播放的影片時這意味著什麼。

重點摘要 {#key-takeaways}

  • ABR 是自適應串流播放器內部的位元率切換邏輯。 自適應串流是更廣的模式(HLS、DASH);ABR 是挑選下一個要抓哪個變體的特定演算法。
  • 服務以多個位元率預先編碼每個標題——「編碼階梯」如 1080p@5Mbps、720p@2.8Mbps480p@1.4Mbps、360p@800Kbps。manifest 將整個階梯暴露給播放器。
  • 切換發生在片段邊界,不是片段中途。 每 2 到 10 秒播放器可以挑不同變體。它無法在片段中途改變變體。
  • 頻寬估算比聽起來困難。 播放器使用最近幾次片段下載的吞吐量、緩衝區位準,或兩者並用——BOLA、MPC 和 dynamic 等演算法把這些訊號結合起來。
  • 冷啟動刻意保守。 沒有頻寬歷史時,播放器挑低變體讓播放快速起步;有真實測量後再爬。
  • 直播 ABR 是同樣模型加上更緊的緩衝區。 直播播放器以較小緩衝區跑,並接受較低變體,因為落後直播邊緣比掉一個畫質等級更糟。
  • 儲存 ABR 串流意味著刻意挑一個變體。 當播放器在播放中途切換時,磁碟上的位元組會是縫合起來的混合體——作為乾淨副本毫無用處。

簡單的解釋

想像你在塞車的路上開車。你不能永遠開 80——有時 50,有時龜速。你不會選一個速度然後堅守它;你不斷觀察前方的路並調整。ABR 就是你的影片播放器不斷檢查你網路的「速度」,並切換到連線現在能維持的畫質等級。

道路比喻成立得很好。串流服務已經以六種不同「速度」編碼了同一標題——畫質變體從小小的 360p 串流一路到龐大的 4K HDR。播放器手上有完整選單。每隔幾秒,它就問:我現在有多少頻寬?我的緩衝區有多滿?下一個我該拉哪個變體?

從觀眾的座位來看,這藏了不少工作。Wi-Fi 不穩時的順暢退回——播放器在緩衝區乾掉之前下一兩階,讓你看到的是短暫的畫質下降,而非旋轉的讀取圖示。頻寬恢復時的回復——播放器在接下來幾個片段內爬回來。「冷啟動」畫質有時前 10 秒感覺低得突兀——那是播放器在還不知道你的連線實際能做什麼之前的刻意保守。

重點不是找出最高畫質並堅持。重點是永不讓播放停頓。ABR 從根本上是一種可靠性技術,副作用是挑它能拿到的最佳畫質。整個設計假設網際網路很亂,而你和 CDN 之間的連線會出狀況——而那個假設正是讓串流在真實網路上得以運作的基礎。若想知道這在更大的串流管線中位於何處,姊妹文章從頭到尾介紹。

ABR 實際運作的方式

ABR 播放器在每個片段上跑緊湊迴圈:測量頻寬、估算可維持值、挑變體、抓取、解碼、重複。 每一步背後都有數十年的真實工程,但迴圈本身很小。

編碼階梯

在任何影片抵達 CDN 之前,服務以多個位元率-解析度組合預先編碼同一個標題。這組變體稱為編碼階梯,典型的網頁階梯看起來像這樣:

解析度位元率編碼器
1920x10805.0 MbpsH.264
1280x7202.8 MbpsH.264
854x4801.4 MbpsH.264
640x3600.8 MbpsH.264
426x2400.4 MbpsH.264

高級服務可能把階梯加倍——最頂端一個 4K HDR 變體、AV1 或 H.265 階梯與 H.264 並行給較新用戶端,加上獨立的純音訊版本。每個變體都是同一份來源內容,以不同畫質目標獨立編碼。不同的階梯也可以在不同變體中包含不同編碼器,讓較新裝置取得更有效率的編碼,而舊裝置取得 H.264 後備。

Manifest 將階梯暴露出來

播放器透過抓取 manifest——服務在播放開始時提供的小型文字檔——來了解階梯。兩個主流的 manifest 格式以不同語法描述同樣的階梯概念。在 HLS 中,主播放清單對每個變體使用一行 #EXT-X-STREAM-INF

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=854x480,CODECS="avc1.4d401e,mp4a.40.2"
480p/index.m3u8

在 DASH 中,同樣資訊存在於嵌套於 AdaptationSet 內的 Representation 元素中,帶有 bandwidthwidthheightcodecs 屬性。不同語法,相同工作——請見 HLS 主播放清單如何暴露變體DASH 如何透過 Representation 定義變體 取得並排細節。無論如何,播放器最終都會得到一份變體清單,每個都有宣告的頻寬和指向更詳細媒體播放清單或片段範本的 URL。

頻寬估算

播放器無法問網路它有多少容量。它得推斷。兩個訊號占主導:

  • 下載時間為基礎的估算測量最近幾個片段抵達了多少位元組以及花了多久。一個 6 MB 片段花了 2 秒,表示約 24 Mbps 吞吐量;滾動平均——通常是最近 3 到 5 次下載的調和平均——平滑掉單一噪聲樣本。
  • 緩衝區位準為基礎的估算觀察緩衝區。若緩衝區在成長,網路舒適地跑贏播放。若在縮減,網路就算原始吞吐量看起來還可以也在輸掉這場比賽——也許下一個片段正坐在某個慢的 CDN 佇列裡。

現代播放器同時使用兩者。純吞吐量估算對快速網路變化反應快,但對單一慢片段可能過度反應;純緩衝區估算穩定但反應慢。混合給播放器一個既快又穩的訊號。

切換演算法

一旦播放器有了頻寬估計,它得把那個翻譯成變體選擇。幾個有名的演算法主導這個領域:

  • 吞吐量為基礎(原始做法)——挑出符合你經安全邊際調整估計的最高頻寬變體。簡單、快速,對噪聲敏感。
  • BOLA(Buffer Occupancy-based Lyapunov Algorithm)——2016 年發表的緩衝區為基礎演算法,根據緩衝區有多滿來決策。緩衝區健康時,BOLA 維持當前變體;只在緩衝區下降時才下階。這避免了在不穩網路上不必要的畫質擺盪。
  • MPC(Model Predictive Control)——混合演算法,結合吞吐量估計、緩衝區位準和切換本身的成本函式,然後挑選在短期預測範圍內把預期卡頓加上可見畫質變化最小化的變體。
  • dash.js dynamic——開源 dash.js 播放器的預設,融合吞吐量與緩衝區訊號,並根據近期網路行為調整。

差異在不穩連線上才有意義。只看吞吐量的演算法觀察單一慢片段時可能恐慌並下兩階;BOLA 可能維持,因為緩衝區還好。工程口味各異;多數量產播放器提供經調校的 MPC 變體或 dynamic 混合。

切換發生在片段之間

播放器無法在片段中途更改變體。一旦它開始從 1080p 變體下載 segment042.ts,整個片段就鎖定了——即使網路突然變得很慢,切到 480p 最早只能在 segment043 發生。這就是為什麼片段長度是真正的調校參數:較短片段(2 秒)給播放器更多切換機會,並能更快反應網路變化,但意味著更多 HTTP 請求與額外負擔。較長片段(10 秒)更有效率但讓 ABR 變慢。

冷啟動 vs 穩態

你按下播放的那一刻,播放器沒有頻寬歷史。第一個變體選擇基本上是猜測。多數播放器猜得保守——它們挑最低或近最低變體,這樣播放快速起步而不冒立即卡頓的風險。前一兩個片段抵達後,播放器有真實下載時間並能爬升。這就是為什麼影片前幾秒常常看起來明顯比其他部分糟:這是 ABR 冷啟動依照設計運作。有些服務以先前工作階段頻寬或網路類型的提示起步,但保守冷啟動仍是預設。

直播 vs VOD ABR

直播以同樣的 ABR 迴圈運作,只有一個關鍵差異:緩衝區不能無限成長。VOD 播放器可以舒服地緩衝 30 到 60 秒。直播播放器緩衝大約 5 到 15 秒——超過那個就是越落越遠地落後直播邊緣。較小的緩衝區迫使 ABR 更快反應並更輕易接受較低變體,因為吸收一個壞片段的餘裕較少。低延遲 HLS 和 DASH 透過 chunk-based 傳輸把這推得更遠,給播放器更薄的緩衝區工作。

這些每一個決策都是播放器在你按下播放時會替你做的事。若你想帶走一個乾淨檔案,你會得自己做一些這些決策——而那正是 VidMost 介入的地方,它解析 manifest 並一次挑對變體,而不是不斷切換。

你在真實世界中看到 ABR 的地方

2026 年每個主要串流服務都跑 ABR;差異在調校上,而非要不要做。

  • YouTube 把 ABR 顯示得最明顯。畫質選單提供「Auto」加上一份具體變體清單。Auto 是 YouTube 的混合演算法在跑的 ABR;手動挑特定變體會把播放器固定在那個變體並停用安全網。瀏覽器開發者工具的 Network 面板顯示來自演算法當時所挑變體的片段請求。
  • Netflix 跑業界研究最深入的 ABR 堆疊之一,搭配內容感知編碼。Netflix 不使用一體適用的階梯,而是為每個標題依其內容調校階梯——低動作的劇情片與快動作的動作片有不同的階梯設定,因為編碼器在感知品質相同時需要的位元更少。結果是每個標題最佳化的階梯。
  • Twitch、Bigo Live 和其他直播平台跑激進的低緩衝 ABR 以維持低延遲。播放器接受較小緩衝區和更快的變體下降,因為直播聊天情境中的 30 秒緩衝代表你比動作慢 30 秒。串流者和觀眾雙方都會注意到。
  • 行動 vs 桌面行為不同。行動播放器通常起步較低並爬得較慢,因為 Wi-Fi 與行動網路不如有線連線可預測。桌面與 TV 播放器假設穩定連線並爬得較快。
  • Apple TV 與智慧電視通常最積極往上爬。它們假設穩定的 Wi-Fi 或有線乙太網路,不費心防禦。這就是為什麼 Netflix 在電視上常常比同一標題在筆電上看起來更銳利——演算法起步較高且爬得較快。
  • VR 與 360 度串流把 ABR 推向新方向。360 度影片比平面影片有多得多的像素,但你在任何時刻只看一個小視口。基於 tile 的 ABR 把全景拆成 tile,並以高畫質串流你正在看的 tile,其餘保持低畫質——和經典 ABR 不同的問題,但同樣是編碼多變體並挑選的哲學。

在消費型服務之外,託管影片供應商——Cloudflare Stream、Mux、Bitmovin、JW Player、Vimeo——預設提供啟用 ABR 的播放器。若一個網站嵌入了來自這些服務之一的影片,ABR 就在運作,即使沒人提到。

如果你想儲存影片,這意味著什麼

這裡 ABR 製造了一個會讓人吃驚的問題。當你以「Auto」觀看串流時,瀏覽器的 network 面板顯示混合下載——有些片段來自 1080p 變體、有些來自 720p 變體,也許在 Wi-Fi 眨眼時短暫繞道到 480p。你觀看時實際打到磁碟的位元組,是多個變體縫合起來的混合體。儲存「你看的內容」是不可能的,因為你看的不是一個單一的東西。

要拿到乾淨、一致畫質的副本,你得刻意挑一個變體,並只抓取該變體的片段。那意味著解析 manifest、辨識可用的最高頻寬變體,並完全繞過 ABR 迴圈——永不要求它切換,只從頂端那一階下載每個片段。瀏覽器擴充功能和「右鍵儲存」做不到這個。它們要嘛存 manifest 文字檔(沒食材的食譜),要嘛擷取播放器當時恰好抓到的片段,也就是你不要的那個混合爛攤子。

VidMost 直接處理這個。它讀取 manifest、挑選服務提供的最高頻寬變體,並從那一個變體下載一致畫質的片段——所以你最後拿到的是該標題完整的 1080p(或可用時的 4K)版本,而不是你 Wi-Fi 閃爍那一刻的 480p 切片。對於 DRM 保護內容,編碼階梯仍然存在;金鑰只是被一個授權伺服器把關。VidMost 內建的 Widevine L3 支援會在 L3 播放可行之處生效——不過實際上限由服務和 DRM 等級決定,而像 Netflix 或 Disney+ 這類高級平台不管 ABR 階梯提供什麼,通常將 L3 串流上限設在 480p–720p。

常見的陷阱與誤解

關於 ABR 的一些誤解反覆出現在論壇討論串中。值得釐清。

  • 「頻寬越高代表畫質越好。」 只在你的頻寬穩定時。一個尖刺式 100 Mbps 連線每分鐘掉到 1 Mbps 兩秒,對 ABR 而言比穩定 5 Mbps 線路更糟,因為演算法在反應噪聲而不是維持高變體。穩定性比尖峰速度更重要。
  • 「切換總是會造成卡頓。」 不是。現代播放器在片段邊界於變體間無形切換——你看到的是畫質變化,不是停頓。讀取圈只在緩衝區比下個片段抵達還早乾掉時出現,而那正是 ABR 想要避免的。
  • 「ABR 與自適應串流是一樣的。」 接近但不完全相同。自適應串流是更廣的模式——manifest、片段、HTTP 傳輸——由 HLS 與 DASH 體現。ABR 是自適應串流播放器內部具體的位元率切換邏輯。每個 HLS 或 DASH 播放器都跑 ABR 演算法;自適應串流是讓它可能的東西,ABR 是做選擇的東西。
  • 「我可以手動設定畫質為 1080p 來覆寫 ABR。」 你可以,但這會停用安全網。在不穩連線上,鎖定 1080p 代表每次網路無法維持位元率就重新緩衝。ABR 存在是因為網路不可靠;固定畫質不會修正網路,只會讓後果變得可見。
  • 「緩衝是浪費的頻寬。」 不是。30 秒的緩衝是讓你在 20 秒 Wi-Fi 中斷中持續觀看的東西。緩衝是演算法的安全邊際,健康串流與令人挫折的串流之間的差別,通常就在於緩衝是否深到能吸收一次短暫的網路問題。

結語

ABR 是那種運作時就消失的技術之一。你只在畫質切換大到看得見時注意到它,或者在緩衝區乾掉、讀取圈出現時。多數時候它默默地跑著——測量、決策、切換——在你的播放器抓取的每一對片段之間。

一旦你能在 manifest 中辨識出編碼階梯,以及播放器在每個片段上跑的「頻寬-決策-抓取」迴圈,許多串流行為就不再神秘。冷啟動的模糊是刻意保守的猜測。播放中途的畫質跳動是播放器在避免停頓。儲存「我看的那一份」副本之所以困難,是因為你看的東西本來就不是單一一份。

如果你寧可完全跳過協定層、一次儲存最高畫質的變體,VidMost 解析 manifest、挑選頂端那一階、乾淨地下載。

延伸閱讀

常見問題

什麼是自適應位元率串流?
自適應位元率串流(ABR)是現代影片播放器在你觀看時於同一影片預先編碼的不同畫質變體間切換所用的技術。伺服器以多個位元率代管該標題——例如 1080p 5 Mbps、720p 2.8 Mbps、480p 1.4 Mbps。播放器測量你的頻寬與緩衝區位準,並為每個新片段挑出你的連線能維持的最高變體。當網路改變,播放器在下一個片段邊界切換到不同變體,而不重新開始播放。
為什麼我的 YouTube 影片畫質一直在變?
當 YouTube 設為 Auto 時,有一個 ABR 演算法在跑。播放器下載短片段、測量它們抵達的速度,並挑選你的連線能跟上的最佳變體。若你的 Wi-Fi 短暫變慢,下一個片段從較低畫質變體抓取;連線恢復後,播放器爬回來。你看到的可見畫質跳動是播放器在避免緩衝區欠載。手動鎖定畫質為 1080p 會停用這個安全網,因此不穩的連線會以重新緩衝取而代之。
為什麼影片一開始模糊,後來變清晰?
在播放開始時,播放器沒有頻寬歷史。它挑一個保守的變體,這樣能快速起步而不立刻卡頓。前幾個片段抵達後,播放器測量到真實下載時間,意識到自己的頻寬比假設的多,並在下一個片段邊界切換到較高變體。一段影片的前 5 到 15 秒常常是整條串流最不好看的部分——這是 ABR 冷啟動,不是來源的問題。
可以停用自適應串流嗎?
某種程度上可以。多數播放器 UI——YouTube、Netflix 的開發者選項、Twitch——讓你把畫質固定在特定變體。那會告訴 ABR 邏輯不要再替你選擇。代價是真實的:若你在只能維持 720p 的連線上鎖定 1080p,每次緩衝區被抽乾就會看到重新緩衝。ABR 存在是因為底下的網路不可靠;關掉它不會讓網路變可靠,只會讓播放器更誠實地展現後果。
為什麼 Netflix 挑的畫質比我的網路能負荷的還低?
Netflix 的 ABR 故意保守。演算法權衡你測得的吞吐量、你的緩衝區位準和抖動的安全邊際;它也根據你的 DRM 安全等級設置最高位元率上限。在 Widevine L3 桌面瀏覽器上,無論你的連線多快,Netflix 都不會送超過 720p。Netflix 的內容感知編碼也為每個標題個別調校階梯——低動作的劇情片可能比動作片止步於較低位元率,因為編碼器不需要更多位元就能達到同樣的感知品質。
卡頓和 ABR 切換是一樣的嗎?
不是,但兩者相關。ABR 切換是看不見的——播放器在下一個片段邊界切換到不同變體,你繼續觀看,可能畫面銳利度不同。卡頓是當緩衝區在下一個片段抵達之前耗盡時你看到的事;播放停止,播放器等待。現代 ABR 正是設計來避免卡頓,方法是在緩衝區抽乾之前降到較小變體。當你真的看到讀取圈時,通常代表網路掉得比演算法能反應的還快。
為什麼前幾秒總是看起來很糟?
因為你按下播放的那一刻播放器沒有頻寬資料,所以它挑一個低變體以快速起步。另一個選擇——樂觀地挑 1080p、緩衝區填充時卡頓十秒——使用者體驗差得多。多數 ABR 演算法刻意以最低或近最低變體冷啟動,並在前幾個片段內爬升。有些服務使用先前工作階段資料或訊號強度提示來起得高一點,但保守的冷啟動仍是有充分理由的預設。
ABR 在直播上有用嗎?
有,但有更嚴格的限制。直播 ABR 跑在與 VOD 相同的編碼階梯、manifest、片段模型上,但緩衝區小得多——有時只有幾秒——因為堆積緩衝意味著落後直播邊緣。這迫使演算法更快反應,並在網路抖動時接受較低畫質。低延遲 HLS 和 DASH 變體使用部分片段與 chunk-based 傳輸,在不讓 ABR 決策變慢或變差的前提下保持薄緩衝。