第二部從索引清單的基本結構,講到巢狀清單、加密金鑰、IV 的規格退路、再到片段規格一致性的驗證,看起來是七個各自獨立的技術細節。但串起來看,其實都在示範同一件事:面對一個看起來複雜的協定,怎麼把它拆解成一連串可以各自驗證的小問題。
回顧這七天,每一天處理的都是「這一層可能不是你以為的樣子」:清單可能是巢狀的、IV 可能沒有明講、片段可能規格不一致。共通的處理模式是:先確認這一層實際的行為邊界(查規格、看真實資料),再針對每個邊界情況寫出對應的判斷邏輯,而不是假設「大部分情況」就是「所有情況」。
❌ 反例:憑印象寫出處理邏輯,沒有對照規格逐一確認
async def get_segments(url):
playlist = await fetch_and_parse(url)
return playlist.segments # 假設一定拿得到片段,沒考慮巢狀清單、沒考慮加密
✅ 正例:針對協定裡每一層已知的邊界情況,各自處理
async def get_segments(url):
playlist = await resolve_media_playlist(url) # 處理巢狀清單
cipher = await resolve_cipher(playlist) # 處理加密與 IV 退路
return playlist.segments, cipher
正例裡的每一個步驟,都對應第二部某一天處理過的邊界情況——這不是巧合,而是先把協定拆解成小問題,逐一確認每個小問題的答案,最後組合起來,會比想像整個協定的行為然後一次寫完更可靠。
第二部反覆強調一件事:技術細節要對照官方規格(RFC 8216)確認,不能只憑「看過幾份範例資料」的印象。範例資料只能告訴你「這幾份資料長什麼樣」,規格才能告訴你「所有合法的資料可能長什麼樣」——這中間的落差,就是 Day 11 那種「規格要求但沒實作」的缺口會潛伏很久才被發現的原因。
第三部開始:協定解析完,接下來是下載引擎的工程問題——為什麼要用非同步,線程池跟 asyncio 該怎麼選。