
音視頻后端物聯(lián)網(wǎng)計算機視覺【免費下載鏈接】scryptedScrypted is a high performance video integration and automation platform項目地址https://gitcode.com/gh_mirrors/sc/scrypted點擊查看免費下載本文以 Scrypted 倉庫中 Amcrest 插件的 AD410 門鈴真實事件抓包plugins/amcrest/ad410.md為核心素材逐事件解讀 Amcrest 門鈴在按鍵呼叫過程中推送的 multipart 事件流并結(jié)合插件源碼amcrest-api.ts、main.ts說明這些事件如何被解析、匹配最終驅(qū)動 Scrypted 的BinarySensor門鈴狀態(tài)與MotionSensor移動偵測接口幫助你在調(diào)試 Amcrest 門鈴、對接自定義事件或排查門鈴不觸發(fā)問題時具備完整的協(xié)議級認知。AD410 門鈴的真實事件流抓包plugins/amcrest/ad410.md 記錄了 Amcrest AD410 門鈴在一次完整按鍵呼叫訪客按下門鈴按鈕、無人接聽、隨后掛斷過程中通過 HTTP 長連接推送的原始事件流。這是理解整個 Amcrest 事件協(xié)議最直接的樣本event --myboundary Content-Type: text/plain Content-Length:41 Code_CallRemoveMask;actionStart;index0 event --myboundary Content-Type: text/plain Content-Length:36 CodeAlarmLocal;actionStart;index0 event --myboundary Content-Type: text/plain Content-Length:148 Code_DoTalkAction_;actionPulse;index0;data{ Action : Invite, CallID : 20220406135211095697192.168.10.20, CallSrcMask : 4 } event --myboundary Content-Type: text/plain Content-Length:68 CodeCallNoAnswered;actionStart;index0;data{ CallID : 4 } event --myboundary Content-Type: text/plain Content-Length:41 CodePhoneCallDetect;actionStart;index0 event --myboundary Content-Type: text/plain Content-Length:41 CodeVideoMotionInfo;actionState;index0 event --myboundary Content-Type: text/plain Content-Length:185 Code_DoTalkAction_;actionPulse;index0;data{ Action : Hangup, CallID : 20220406135211095697192.168.10.20, CallSrcMask : 4, HangupReason : HangupByPhone } event --myboundary Content-Type: text/plain Content-Length:35 CodeAlarmLocal;actionStop;index0 event --myboundary Content-Type: text/plain Content-Length:39 CodeCallNoAnswered;actionStop;index0 event --myboundary Content-Type: text/plain Content-Length:95 CodeVideoMotion;actionStop;index0;data{ Id : [ 0 ], RegionName : [ Region1 ] } event --myboundary Content-Type: text/plain Content-Length:40 CodePhoneCallDetect;actionStop;index0 event --myboundary Content-Type: text/plain Content-Length:40 Code_CallRemoveMask;actionStop;index0分幀格式multipart 邊界 頭 定長 body抓包中每一幀part的構(gòu)成非常清晰--myboundarymultipart 流的邊界行用于分隔相鄰兩個事件 part。抓包中邊界行前的event前綴是捕獲工具/控制臺打印的日志前綴不屬于流內(nèi)容本身Content-Type: text/plain該 part 的 MIME 類型聲明 body 是純文本Content-Length:N該 part body 的精確字節(jié)數(shù)例如Code_CallRemoveMask;actionStart;index0恰好是 41 字節(jié)空行頭與 body 的分隔bodyCode...;action...;index...;data{...}形式的事件負載其中data字段是可選的 JSON。這個分幀方式與 amcrest-api.ts 中的解析邏輯一一對應(yīng)插件從 HTTP 響應(yīng)的content-type頭中解析出 boundary源碼注釋明確指出 Amcrest 可能發(fā)送--myboundary或帶空格的-- myboundary兩種形式再對每個 part 讀取頭行、按Content-Length讀取定長 body。逐事件解讀一次完整門鈴呼叫的生命周期把 12 個事件按時間序展開就是一次 AD410 門鈴呼叫的完整狀態(tài)機順序事件語義1Code_CallRemoveMask;actionStart;index0呼叫開始解除掩碼門鈴內(nèi)部狀態(tài)插件忽略2CodeAlarmLocal;actionStart;index0本地報警/響鈴開始插件忽略3Code_DoTalkAction_;actionPulse;index0;data{Action:Invite,...}訪客按下門鈴按鈕發(fā)起雙向?qū)χv邀請關(guān)鍵事件4CodeCallNoAnswered;actionStart;index0;data{CallID:4}呼叫開始被標記為未應(yīng)答5CodePhoneCallDetect;actionStart;index0檢測到電話呼叫門鈴被按6CodeVideoMotionInfo;actionState;index0移動偵測狀態(tài)脈沖訪客靠近鏡頭觸發(fā)7Code_DoTalkAction_;actionPulse;index0;data{Action:Hangup,...,HangupReason:HangupByPhone}對講結(jié)束由電話側(cè)掛斷關(guān)鍵事件8CodeAlarmLocal;actionStop;index0本地報警停止9CodeCallNoAnswered;actionStop;index0未應(yīng)答狀態(tài)結(jié)束10CodeVideoMotion;actionStop;index0;data{Id:[0],RegionName:[Region1]}移動偵測區(qū)域停止RegionName指出觸發(fā)區(qū)域11CodePhoneCallDetect;actionStop;index0電話呼叫檢測結(jié)束12Code_CallRemoveMask;actionStop;index0呼叫結(jié)束掩碼恢復(fù)幾個值得注意的細節(jié)CallID的構(gòu)成20220406135211095697192.168.10.20遵循時間戳序號來源IP的格式Invite 與 Hangup 兩個脈沖攜帶相同CallID可用于配對一次完整呼叫CallSrcMask: 4表示呼叫來源掩碼。動作語義action取值為Start進入某狀態(tài)、Stop離開某狀態(tài)、Pulse瞬時脈沖常帶 JSONdata、State狀態(tài)上報。index0通道索引0 基。插件會把index 1與設(shè)備配置的通道號比較不匹配則丟棄見后文。對照AD110 的門鈴事件流倉庫中另有 AD110 抓包 可以對照閱讀。AD110 的呼叫事件序列更精簡NTPAdjustTime;actionPulseNTP 校時脈沖、_DoTalkAction_;actionPulseInvite、CallNoAnswered;actionStart、CallNoAnswered;actionStop、_DoTalkAction_;actionPulseHangup。兩者的對比揭示了 Amcrest 不同型號門鈴的事件協(xié)議差異AD410 會額外推送PhoneCallDetect、AlarmLocal、_CallRemoveMask、VideoMotion/VideoMotionInfo等事件形成完整的呼叫 移動偵測生命周期AD110 的抓包中則沒有這些條目或其固件版本未推送AD110 抓包中還混入了[HomeKit]: snapshot requested for reason: 1日志行——這是 Scrypted 控制臺輸出與原始事件流同一捕獲通道產(chǎn)生的混排結(jié)果并非 multipart 事件流的一部分閱讀此類抓包時需要區(qū)分關(guān)鍵的雙向?qū)χv事件_DoTalkAction_的 Invite/Hangup 脈沖、CallNoAnswered在兩個型號上完全一致這正是插件能夠用統(tǒng)一邏輯處理多種門鈴的基礎(chǔ)。源碼級解析listenEvents 如何消費事件流訂閱端點與邊界解析AmcrestCameraClient.listenEvents() 是整個事件鏈的入口它向設(shè)備發(fā)起一個 HTTP 長連接請求http://ip/cgi-bin/eventManager.cgi?actionattachcodes[All]codes[All]表示訂閱設(shè)備的全部事件碼。拿到可讀流后解析流程與上面抓包的分幀格式嚴格對應(yīng)逐行讀取邊界common/src/read-stream.ts 的readUntil/readLine按換行切分遇到終止邊界--myboundary--跳過讀頭readAmcrestMessage 持續(xù)讀取行直到空行。源碼注釋專門處理了一個 DahuaAmcrest 同源固件的畸形情況——header 與 body 之間缺少換行分隔Content-Length:39后緊跟 body 行此時把不含:的行unshift回流中返回避免誤判讀 bodycommon/src/rtsp-server.ts 的readBody按解析出的Content-Length精確讀取定長數(shù)據(jù)這保證了data{...}中跨多行的 JSON如抓包里 Invite 脈沖的 148 字節(jié)能被完整取出容錯兼容解析循環(huán)還處理了 Dahua 設(shè)備偶發(fā)在流中插入完整HTTP/1.1 200 OK響應(yīng)消息的 bugamcrest-api.ts#L271-L281將其整段跳過并記錄日志。事件碼表AmcrestEvent 枚舉與匹配AmcrestEvent 枚舉 定義了插件關(guān)心的全部事件碼匹配方式是子串包含data.indexOf(event) ! -1。對照 AD410 抓包可以精確看出哪些事件被消費、哪些被靜默忽略export enum AmcrestEvent { MotionStart CodeVideoMotion;actionStart, MotionStop CodeVideoMotion;actionStop, MotionInfo CodeVideoMotionInfo;actionState, AudioStart CodeAudioMutation;actionStart, AudioStop CodeAudioMutation;actionStop, TalkInvite Code_DoTalkAction_;actionInvite, TalkHangup Code_DoTalkAction_;actionHangup, TalkPulse Code_DoTalkAction_;actionPulse, AlarmIPCStart CodeAlarmIPC;actionStart, AlarmIPCStop CodeAlarmIPC;actionStop, PhoneCallDetectStart CodePhoneCallDetect;actionStart, PhoneCallDetectStop CodePhoneCallDetect;actionStop, DahuaTalkInvite CodeCallNoAnswered;actionStart, DahuaTalkHangup CodePassiveHungup;actionStart, DahuaCallDeny CodeHungupPhone;actionPulse, DahuaTalkPulse Code_CallNoAnswer_;actionPulse, FaceDetection CodeFaceDetection;actionStart, SmartMotionHuman CodeSmartMotionHuman;actionStart, SmartMotionVehicle CodeVehicle;actionStart, CrossLineDetection CodeCrossLineDetection;actionStart, CrossRegionDetection CodeCrossRegionDetection;actionStart, }以 AD410 抓包為參照被消費的PhoneCallDetect;actionStart/Stop、_DoTalkAction_;actionPulseInvite/Hangup 靠 payload 區(qū)分、CallNoAnswered;actionStart、VideoMotionInfo;actionState、VideoMotion;actionStop被忽略的_CallRemoveMask、AlarmLocal、CallNoAnswered;actionStop——它們不在枚舉中解析循環(huán)對它們不做任何狀態(tài)變更。這意味著事件協(xié)議中相當一部分內(nèi)部簿記事件對上層是透明的。每個事件 emit 時還會攜帶從 body 中解析出的index通道索引與dataJSON 負載解析器把 body 按;切分提取index與data兩個片段data會被JSON.parse成對象amcrest-api.ts#L297-L319。此外智能檢測事件SmartMotionHuman、Vehicle、FaceDetection、CrossLine/CrossRegionDetection會被進一步映射為person/car/face類別并額外 emitsmart事件供ObjectDetector接口輸出倉庫中 plugins/amcrest/dumps/amcrest-face-detected.json 與 plugins/amcrest/dumps/amcrest-human-detected.json 保留了這類事件的真實 JSON 樣本包含BoundingBox、ObjectType、Confidence等字段。事件流如何變成 Scrypted 的傳感器狀態(tài)門鈴按鍵 → BinarySensorAmcrestCamera.listenEvents() 訂閱事件流后把事件碼翻譯為設(shè)備狀態(tài)。處理 AD410 門鈴按鍵的關(guān)鍵分支main.ts#L260-L286else if (event AmcrestEvent.TalkInvite || event AmcrestEvent.PhoneCallDetectStart || event AmcrestEvent.AlarmIPCStart || event AmcrestEvent.DahuaTalkInvite) { ... this.binaryState true; } else if (event AmcrestEvent.TalkHangup || event AmcrestEvent.PhoneCallDetectStop || ... ) { this.binaryState false; } else if (event AmcrestEvent.TalkPulse doorbellType AMCREST_DOORBELL_TYPE) { if (payload.includes(Invite)) { this.binaryState true; } else if (payload.includes(Hangup)) { this.binaryState false; } }把 AD410 抓包代入這段邏輯binaryState的翻轉(zhuǎn)軌跡是_DoTalkAction_Invite 脈沖 →binaryState true訪客按下按鈕門鈴響CallNoAnswered;actionStart、PhoneCallDetect;actionStart→ 再次置true冗余確認_DoTalkAction_Hangup 脈沖HangupReason: HangupByPhone→binaryState falsePhoneCallDetect;actionStop→ 置false。值得注意的是TalkPulse分支對payload完整 body 字符串做includes(Invite)/includes(Hangup)判斷——這正是為什么 Invite/Hangup 兩個脈沖必須攜帶 JSONdata字段如果某固件的脈沖不帶data該分支不會翻轉(zhuǎn)狀態(tài)只能依賴PhoneCallDetect的 Start/Stop 兜底。而事件負載中的index會先經(jīng)過通道過濾main.ts#L231-L236index 1必須等于設(shè)備配置的Channel Number OverridertspChannel設(shè)置項多通道 NVR 場景下避免串通道。接口暴露上updateDevice() 在設(shè)備Doorbell Type設(shè)為Amcrest Doorbell時把設(shè)備類型置為Doorbell并追加BinarySensor與Intercom接口——這解釋了為什么 README 中門鈴配置的第一步是SelectTypeisDoorbell只有如此門鈴事件才會被映射到二進制傳感器而非僅日志。移動偵測20 秒超時而非 Stop 事件AD410 抓包中的VideoMotionInfo;actionState事件 6與VideoMotion;actionStop事件 10的處理體現(xiàn)了插件的防抖設(shè)計main.ts#L211-L253MotionStart/SmartMotionHuman/SmartMotionVehicle/CrossLine/RegionDetection→ 立即motionDetected true并重置一個20 秒的motionTimeoutMotionInfo即VideoMotionInfo;actionState脈沖→ 若尚未檢測到則補置true同樣重置 20 秒計時MotionStop→有意不立即清除狀態(tài)注釋寫明use resetMotionTimeout即依賴 20 秒無新事件后自動回落為false。這種事件置位 超時回落的模式避免了固件偶發(fā)漏推Start/Stop配對事件時傳感器卡死的問題——這也與抓包中VideoMotion;actionStop攜帶RegionName: [Region1]對應(yīng) Amcrest 配置界面第一號運動偵測區(qū)域相互印證即使 Stop 到達狀態(tài)清理仍統(tǒng)一由超時完成。監(jiān)聽器?;頻istenLoop 的重連與空閑超時事件長連接的健壯性由基類 RtspSmartCamera.listenLoop() 保證監(jiān)聽器創(chuàng)建失敗、連接close或error時自動銷毀并延時重建rtsp.ts#L183-L191連接后啟動 5 分鐘空閑看門狗期間沒有任何data事件即設(shè)備長時間無活動則銷毀監(jiān)聽并重建防止半死連接每個事件到達都會刷新空閑計時因此在門鈴頻繁觸發(fā)的場景下連接會持續(xù)?;?。listenEvents內(nèi)部還會stream.socket.setKeepAlive(true)維持 TCP ?;頰mcrest-api.ts#L250。調(diào)試時可在設(shè)備設(shè)置中開啟debug每個原始事件幀會打印到控制臺rtsp.ts#L211-L215——ad410.md 與 ad110.md 這兩份文檔本身就是這類調(diào)試輸出的歸檔樣本。實戰(zhàn)配置與 AD410 已知怪癖門鈴設(shè)備的基本配置按 Amcrest 插件 README 的門鈴配置要求plugins/amcrest/README.mdType選擇Doorbell設(shè)備名稱下方Username為admin設(shè)備初始化時設(shè)置的本地管理員賬號不是 Amcrest Smart Home 云賬號Doorbell Type選擇Amcrest Doorbell對應(yīng)源碼中的 AMCREST_DOORBELL_TYPE可選值還有Dahua Doorbell若雙向?qū)χv開始時門鈴重啟/崩潰用 Amcrest Smart Home 應(yīng)用在 Device Information 中關(guān)閉Record Audio選項代價是 SD 卡不再錄音。雙向?qū)χv的音頻通路當事件把binaryState置真后可通過Intercom接口發(fā)起對講。startIntercom() 對 Amcrest 門鈴非 Dahua的路徑是把媒體轉(zhuǎn)成 FFmpeg 輸入用 FFmpeg 重編碼為AACadts 封裝后以 1024 字節(jié)分塊 POST 到http://ip/cgi-bin/audio.cgi?actionpostAudiohttptypesinglepartchannel通道號Content-Type為Audio/AACDahua 門鈴則走pcm_alaw/Audio/G.711A編碼。另外 main.ts#L757 的注釋提示ONVIF 雙向音頻在大多數(shù)機型上表現(xiàn)更好但AD110 例外添加設(shè)備時插件會自動探測devAudioOutput.cgi并默認選擇ONVIF見 checkTwoWayAudio()。AD410 特有的 caps 怪癖configureCodecs() 中有一段針對 AD410 的特殊處理源碼注釋明確寫道ad410 doesnt return a camera number if accessed directly——當直連 AD410不經(jīng)過 NVR查詢編碼能力時encode.cgi?actiongetConfigCaps返回的鍵不帶通道編號前綴。解析器因此在caps[0].MainFormat[0]找不到值時回退到caps.MainFormat[0]。如果你在為 AD410 配置碼率/分辨率時遇到能力查詢異常這是一個已知的設(shè)備側(cè)差異而非配置錯誤。設(shè)備信息獲取方面插件通過 probe.ts 的magicBox.cgi?actiongetSystemInfo解析deviceType/serialNumber等設(shè)備參數(shù)來校驗憑據(jù)與型號main.ts 的 updateDeviceInfo() 還會逐一查詢getVendor/getSerialNo/getDeviceType/getSoftwareVersion失敗僅記錄錯誤而不阻塞設(shè)備使用。小結(jié)AD410 的一次門鈴呼叫會產(chǎn)生 12 個 multipart 事件幀核心信號是_DoTalkAction_的 Invite/Hangup 脈沖與PhoneCallDetect的 Start/Stop其余_CallRemoveMask、AlarmLocal、CallNoAnswered;actionStop為插件忽略的內(nèi)部簿記事件事件流由eventManager.cgi?actionattachcodes[All]長連接推送分幀為邊界 Content-Type/Content-Length 頭 定長 bodydata字段攜帶跨行 JSON插件通過 AmcrestEvent 枚舉 做子串匹配把事件翻譯成BinarySensor門鈴與MotionSensor20 秒超時回落狀態(tài)并由 listenLoop 提供重連與空閑看門狗保活配置門鈴時需將設(shè)備Type設(shè)為Doorbell、Doorbell Type設(shè)為Amcrest Doorbell并使用設(shè)備本地admin憑據(jù)調(diào)試原始事件幀可開啟設(shè)備debug設(shè)置ad410.md 與 ad110.md 是兩份可對照的真實抓包樣本。贊分享音視頻后端物聯(lián)網(wǎng)計算機視覺【免費下載鏈接】scryptedScrypted is a high performance video integration and automation platform項目地址https://gitcode.com/gh_mirrors/sc/scrypted點擊查看免費下載相關(guān)推薦Scrypted Amcrest 插件實戰(zhàn)接入 Amcrest 攝像頭、門鈴與 NVR 的完整配置指南Scrypted Amcrest 插件實戰(zhàn)接入 Amcrest 攝像頭、門鈴與 NVR 的完整配置指南 本篇技術(shù)文章圍繞 Scrypted 倉庫中的 Amcr音視頻后端物聯(lián)網(wǎng)計算機視覺go2rtc項目中Amcrest AD410門鈴雙向音頻配置指南go2rtc項目中Amcrest AD410門鈴雙向音頻配置指南 背景介紹 在智能家居監(jiān)控系統(tǒng)中Amcrest AD410門鈴是一款基于Dahua技術(shù)的流行設(shè)音視頻后端Mistral-Nemo-Instruct-2407代碼生成實戰(zhàn)從基礎(chǔ)編程到復(fù)雜算法實現(xiàn)終極指南Mistral Nemo Instruct 2407代碼生成實戰(zhàn)從基礎(chǔ)編程到復(fù)雜算法實現(xiàn)終極指南 Mistral Nemo Instruct 2407 是一款上一篇解鎖創(chuàng)意工坊WorkshopDL跨平臺工具全解析下一篇LangChain為什么它是構(gòu)建AI代理的首選框架3個關(guān)鍵優(yōu)勢解析創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考