我們用 SMART——Specific(具體)、Measurable(可衡量)、Achievable(可達成)、Relevant(具關聯)、Time-bound(有時限)——把每個故事拆成五天,作為每次動手造輪子前的五個檢查問題。
本篇是故事四「從 ONVIF 攝影機截圖太難了,我們來搞 V4L2」的 Measurable 篇:什麼證據可以證明問題已經解決?
本篇定位:定義網路攝影機截圖的可驗收條件,而不是看到一張 JPEG 就宣布完成。
V4L2 提案暫時被按住之後,團隊回頭研究網路這一側。幾天後的站立會議,有人舉起筆電:「拿到了。」螢幕上是一張攝影機拍的畫面。
然後問題來了:這張圖是哪一台攝影機拍的?——測試那台,應該是。什麼時候拍的?——跑指令的時候吧。解析度為什麼是這個?——預設值,沒特別選。密碼錯了會怎樣?——沒試過。把攝影機的網路線拔掉呢?——應該會逾時,多久不確定。
追問來歷才知道,那張圖不是從攝影機口中問出來的:是在網路論壇上查到這個型號慣用的截圖網址,把帳密貼上去試出來的。那條網址是廠商的私有路徑,沒出現在任何標準宣告裡,設備從來沒有對外承認過它存在。圖是真的,但它能證明的只有一件事:某一次嘗試裡,某台設備曾經回了一張圖給某台筆電。
一張 JPEG 是一次觀察,不是一個驗收條件。這句話在按鈕與 LED 那個故事裡講過,換一個領域就會重新忘記一次——影像比 LED 更有說服力:畫面就在那裡,誰還會懷疑呢。
第一個問題是來歷。那條私有路徑是這個型號目前碰巧接受的東西,不是設備宣告的能力;換一台攝影機、升一版韌體或改一個設定,它就可能失效,而且失效時系統不會知道為什麼。ONVIF 之所以要走「問它支援哪些服務、有哪些媒體設定檔、再要一個 Snapshot URI」這一串,不是儀式,而是讓系統知道自己在向誰要、要的又是什麼——這正是「碰巧拿到」與「取得」的差別。
第二個問題是正常路徑之外的世界。截圖的價值恰恰發生在事件當下,也就是網路最不穩的時刻。認證失敗、設備離線、逾時、拿到快取舊畫面,這些不是邊角案例,是這個功能的主場;示範那天全部沒試過,等於只驗收了晴天。
第三個問題是可重現性。成功只存在於一位工程師的指令歷史裡,沒有文件,也沒有第二個人重做過——那不是團隊的能力,是個人的運氣。
Measurable 的產出,是把「拿到一張圖」展開成一張驗收表:
| 驗收項目 | 通過條件 |
|---|---|
| 能力來源明確 | 支援哪些服務、有哪些媒體設定檔,由設備自己回答,並留下回應紀錄 |
| 來源正確 | 能指定設備取圖,影像可對應到該設備,不靠碰巧試出來的網址 |
| 影像即時 | 依專案事先講定的判法,確認拿到的不是快取舊圖 |
| 規格明確 | 解析度出自選定的媒體設定檔,且取得影像後核對過實際尺寸 |
| 服務認證可辨識 | 服務呼叫的帳密錯誤時,回報得出是這一層沒過 |
| 取像認證可辨識 | 影像下載被拒時,回報得出是取像那一次請求沒過 |
| 離線可辨識 | 設備離線或逾時,在設定時間內回報,不無限等待 |
| 流程可重現 | 另一位工程師依文件能在另一台機器完整重做 |
認證得拆成兩層來驗。ONVIF 的服務呼叫有自己的認證,可能走 HTTP Digest,也可能走訊息層的 WS-UsernameToken,兩者同時出現時先驗 HTTP 那一層;但通過這一關,只代表你問得到 Snapshot URI。把影像抓下來是另一次獨立的 HTTP GET,必須再通過一次裝置的 HTTP 認證。服務呼叫成功不等於截圖下載會成功——帳號有查詢權限卻沒有取像權限,症狀就是「一路都對,最後一步被擋」。錯誤訊息因此至少要說得出卡在哪一層:是問不到網址,還是問到了卻拿不到影像。
「影像即時」那一列,是我們寫得最理想化的一項。原本的寫法是「影像時間與請求時間的差距在約定範圍內」,但多數設備回來的 JPEG 並不帶拍攝時間,沒東西可比對。可行的判法有兩種:拿 HTTP 回應的 Date 標頭當參考,至少知道設備何時送出;或在現場放一個持續變化、肉眼可辨的目標,請求前後各取一次做人工核對。兩種都不完美,這一列的通過條件必須在專案裡先講定,別留一句「要即時」給驗收當天吵。
逾時要有上限,而且要分段。連不上設備、認證卡住、拿到網址卻下載不完,是三種卡點,每段都該有自己的時限,時間到就帶著「卡在哪一段」放棄。
設備離線則要跟「暫時取不到」分開。一次逾時可能是網路抖動,連續失敗就是設備真的不在了;系統該說得出這個差別,而不是用同一種語氣一路重試。
共通的前提是留下證據:每次截圖的請求、回應與錯誤都要有紀錄。「畫面是黑的」與「根本沒拿到畫面」是兩種故障:前者去現場看鏡頭,後者查網路;紀錄裡分不出來,兩邊都會白跑。
還有一個功課是最小相容性驗證:至少在第二台不同來源的設備上跑過同一份流程,而且刻意挑條件不同的——不同廠牌、媒體設定檔數量不同、或只有串流沒有單張截圖介面。驗的重點不是「它也能成功」,而是失敗時能不能辨認出這台設備少了什麼能力,以及哪些步驟是標準保證的、哪些是這台設備碰巧提供的。
驗收表還有一個安靜的作用:讓後面的路線之爭有了量尺。不管走哪條路,都要過同一張表——包括「換一台設備還能不能用」那幾列。
成功不是工程師電腦上曾經出現過一張圖,而是系統知道自己向誰要、拿到什麼,以及失敗時發生了什麼。影像類的功能特別容易騙過驗收:一張看得見的畫面,會讓看不見的問題顯得多慮。把驗收寫成表,就是替它們保留席位。
表定好了,下一個問題是怎麼走到那裡。當初被我們判定太難的那套標準介面,重新給它一次公平的機會,能不能自己走完整張表?