Multi-Media Creator
無胥 Starknows
- 多媒體創作者
- 世界觀設定、小說創作、多媒體編劇
- 直播輔助工具、網頁應用、AI 應用服務
Multi-Media Creator
無胥 Starknows
上一回講解了「你推多久沒開台了」的開發思路, 這回就輪到衍生服務「你推最近開了多久」的解密了。
服務網址:https://recent-live.starknows.tw/
前一篇解釋過的東西會快速帶過,有興趣可以先讀:
兩個服務之間間隔了整整一年半 除了一直沒有什麼新的靈感之外 也是因為在這之間接了幾個滿花時間的劇本案 沒有什麼時間可以摸魚,也就沒有繼續推進這些 Side Project
大約是七月初 (2025) 的時候信箱突然來了通知 原來是有用戶反應沒辦法查詢含有中文的 ID 也讓我突然想起 YT 在去年 (2024) 就已經允許在頻道 ID 使用中文 而在 debug 的過程中也像是開啟了什麼開關,突然想來做些什麼
原先的備案有這些: - 正式發表開台通知的 Chome Extension - 透過 RSS 等方式做頻道數據分析 (類似 Playboard) - 某種圈內天災的防治手段
Extension 的部分我個人已經使用兩年多了 但一直沒什麼信心將它上架到商店 總覺得還差了一些什麼,卻又覺得還差得很遠 像是關閉提醒或提醒清單之類的
而天災防治 (委婉) 真的沒什麼想法 我甚至連這個天災是什麼都不敢講 或許將來可以做一個服務本地人的類棉花糖服務 至少有人想要提告的時候我可以提供數據協助吧?
雖然看到這裡也知道最後什麼也沒選中 但出發點確實是想從現有的技術做免錢的頻道分析 畢竟已經可以取得直播影片列表跟 RSS 資料了,應該行吧!
不,實際揭露在這兩個地方的資料太少 只靠這些材料很難找到一個真的吸引人或有趣的內容 後來回頭思考前一個服務的本質 決定還是要建立簡單又直接的內容
而且前一個服務對於企業勢及其粉絲沒太大樂趣 畢竟這類型的頻道應該都有開台次數的要求 查詢的結果就不太會有爆點
所以最後就覺得——啊不然反著做好了。 於是我就在公司的外訓課程途中訂下了這次服務的標題。
1. [前端] 取得帳號代碼、驗證帳號代碼,發送請求至雲端 2. [後端] 驗證帳號代碼、確認是否有快取資料 3. [後端] 對目標頻道之直播頁面發送請求 4. [後端] 取回 html 文件後進行文本分析 5. [後端] 取出直播列表之資料結構以及分頁 token 6. [後端] 透過 RSS 確認頻道資料快取、或取得頻道資料 7. [後端] 透過文本分析,確認 30 天內直播內容 8. [後端] 若資料疑似不足,發送請求取得下一頁資料 9. [後端] 將 30 內直播資料整理並快取 / 搭上頻道資料後回傳前端 10.[前端] 加總時間,並挑出最長的一場,顯示於畫面上
因為大多數跟前一個服務相似,這次寫得比較簡潔了, 但後面的字數肯定會讓人嚇一跳。
跟前一個服務幾乎一樣 唯一差別在會更早地確認快取資料是否存在 這部分是我針對兩個服務制定的快取策略不同 前一個服務「你推多久沒開台了?」只針對最後一場直播做計算 如果剛好在快取的期間開了新直播,且觀眾也有跟到這場直播 馬上就會察覺到資料過舊且呈現錯誤的情況; 而新的服務「你推最近開了多久?」是 30 天內所有直播時間總和 就算真的在快取期間開了新的台,也相對不容易被察覺漏算 除了極端狀況:整個月沒開、開得極少,且開完馬上就有人查詢 不過我的快取時長也沒有抓得很久,主要還是想儘可能減少伺服器端負擔
這邊其實也跟前一個服務有 95% 相同 但唯一不同之處:「取出分頁 token」這件事 含金量卻遠遠超出這個服務本身 有許多開源專案用過類似的技巧,不算什麼特別秘密 但只要掌握這點就能做出各式各樣的直播輔助功能
將 GET 請求加上分頁參數是很尋常的事情, 畢竟使用者不見得會認真看完所有網頁內容, 有時候只是過渡這個頁面,或只是想稍微了解大概, 如果這個時候卻要將完整的資料, 可能上百、甚至上千筆一起呈現在網頁上, 那先不論傳輸文字資料浪費的頻寬(儘管不多), 光是將巨量的內容渲染到瀏覽器上,就是一個很大的效能/記憶體浪費。
這個形式在網頁製作上叫做「無限滾動(Infinite Scrolling)」 YT 的所有影片列表頁面都用上了類似的機制 我們服務每次所請求的「/{頻道代碼}/streams」頁面也有實作 跟隨 Html 來的初始資料只會有 30 筆 (各處列表或有不同)
但問題來了, 我知道他是用無限滾動方式製作,也知道他會在滾動時打 API 拿新資料 但我究竟要怎麼打別人家的 API 去拿特定的資料?
這時候就要按下鍵盤上的 F12 叫出開發者工具 其中有一個叫 Network 的頁籤會列出所有的網路請求 無論是圖片、影片等資源網址,也會列出呼叫過的 API
簡而言之, 我解析了 YT 在取得下一筆資料時所呼叫的 API 確認了路徑還有所夾帶的資料結構(酬載、payload) 發現他使用到一條名稱與分頁相關的 token 而這個 token 肯定也在某個階段也來到了瀏覽器端 我在 Html 取出的資料發現了 continuationCommand 這個物件 接著,仿造請求的 UserAgent 說自己是瀏覽器、 仿造 Youtube 自訂的某個用戶資訊資料, 終於成功透過內部的 API 取得了分頁的資料。
順帶一提,我推測這個 token 本身應該是標記資料的斷點用的 假如完整的資料是 a b c d e f g 這樣的列表 我第一次請求取得了 a b c 這三筆資料,同時就會得到一個標記叫 stopAtC 這樣我下一次請求如果帶上這個 stopAtC 的標記, 服務端就知道我已經有了 a b c 的資料,下一次可以從 d 開始給起
在影片列表這種每次 API 固定給幾筆的情境中 這個標記結束在哪的 token 看起來滿無謂的 不過這個東西在聊天室當中就是非常重要的設計了 同樣的手段可以拿來模擬聊天室的 API 行為 也就是透過這個 token 一段一段擷取聊天室訊息 既不會漏掉、也不需要擔心重複 至於聊天室的部分,後續也會專門寫一篇文章介紹,敬請期待。
另外這邊有個比較要注意的地方是, 這類型非對外公開的 API 無法透過網頁前端(瀏覽器端)呼叫 因為瀏覽器會因為同源政策(Same Origin Policy)而拒絕這樣的行為 但就算用非瀏覽器的環境進行請求,也可能因為其他理由而被拒絕 總之這部分在 YT 目前的設計上是能夠繞過去的。
也就是透過 RSS 服務取得綠界跟山羌連結, 同前服務所述,略過不談
前面取出直播資料會花這麼大篇幅就是為了講解這兩點 如果只要確認最後一次直播的影片, 那麼只要一次 GET Html,30 筆資料綽綽有餘 畢竟不會有人一口氣開 30 間待機室......吧? 這部分也是人與人之間的信任,總之我沒有回去改舊服務。
但新服務的情況就不同了, 我相信肯定有不少人是全勤、甚至有人是一天二動以上的 30 筆資料恰巧就在一個很尷尬的長度 所以我才在這個服務上,花了不少時間加入分頁查詢的功能
而我為什麼會決定計算 30 天內直播時長總和呢? 因為在直播頁籤裡面,影片會顯示「幾天前」、「幾個月前」的文字 我只要跑一個迴圈,直到遇到第一筆擁有「個月前」這段字的資料就停止 所以我可以在完全不知道直播發生日期、結束日期的情況下完成影片分類 聽起來很好笑,但這樣就不用打 Search API 去確認一個月內的直播了 我又省下了 100 quota (笑)
期間遇到一個很好笑的 bug 因為判斷的是「個月前」這三個字, 所以遇到那種超過一年沒開台的,程式就停不下來(
只要改變判斷機制、加上前面的分頁功能, 其實我的服務是可以做到查詢一年內的開台時數的。 但這畢竟是公開給大家玩的東西 如果每個頻道都要計算到一年內的時數 可能一次的查詢,服務端就要打出將近 10 次 API 查詢 一來一回處理時間上可能就會拉得很長 也增加了因為呼叫頻率過高而被 YT 自動封鎖 IP 的可能性
所以有興趣的話可以自行撰寫相關程式查詢計算。
其實這部分也跟前個服務一樣 只是接收資料之後展示在畫面上 甚至還不需要建立計時器讓時間繼續跑
但也就是因為這個「跟前個服務一樣」 甚至能發現就連排版也 87% 相同 (因為我沒有設計能力,能沿用就沿用) 所以在製作前端頁面的時候就覺得渾身不舒服(
雖然我喜歡自己造輪子,但相同的東西不想再寫第二遍 所以我最後是製作了一個環境變數 只要修改變數,版面設計跟 API 路徑就會自動變更 雲端部署的部分也是透過環境變數讓兩個專案對應同一個 git 倉庫 雖然開發的時候要自己一直改環境變數, 至少許多繁雜的驗證、純函式就不用抄來抄去, 以免兩邊抄來抄去,最後功能不同步造成了後續維護麻煩。
為了寫這篇文章,我又改了文章編輯器的程式 現在除了標題跟小標,又多了章節標 後續還要再回去調整舊文章的字級設定 自建服務就是這麼自(麻)由(煩) 而且遲早有一天會越來越複雜, 甚至跟套件的文字編輯器一模一樣吧! 這就是為什麼大家說不要造輪子 因為繞了一大圈也可能只是取得同樣的結果 只能笑著說在過程中得到了回憶。
順便提一下之前文章發佈的時候有提到被 YT 封鎖的事情 也就是為什麼最後還是妥協了使用 Data API 的原因: 因為對 YT 來說還是有些不可觸犯的天條 我要抓影片清單甚至輪詢影片清單他可能都不覺得怎樣 不過我對影片 (/watch?v=OOOOOO) 打了 GET 請求後,他馬上就有反應了XD 雖然我只是要更詳細的影片資訊,不過他可能覺得我要偷影片本體 在本地端的 localhost 他或許還當作你在學術研究 但一放上雲端後,我的服務 IP 就瞬間被鎖了,呵呵。
跟 YT 周旋是件有趣的事情 學會蹭 API 之後又拓展了許多想像 其實目前我也私下在做些跟聊天室互動有關的東西 不過規模比目前任何服務都大上許多 也不曉得究竟什麼時候能夠真的推出就是了。