UNPKG

@scrypted/amcrest

Version:

Amcrest Plugin for Scrypted

2 lines 173 kB
/*! For license information please see main.nodejs.js.LICENSE.txt */ (()=>{var e={66:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BitStream=t.dumpBuffer=t.BufferChain=t.BitWriter2=t.BitWriter=void 0,t.random16=function(){return s.jspack.Unpack("!H",(0,n.randomBytes)(2))[0]},t.random32=function(){return s.jspack.Unpack("!L",(0,n.randomBytes)(4))[0]},t.bufferXor=function(e,t){if(e.length!==t.length)throw new TypeError("[webrtc-stun] You can not XOR buffers which length are different");const r=e.length,n=Buffer.allocUnsafe(r);for(let s=0;s<r;s++)n[s]=e[s]^t[s];return n},t.bufferArrayXor=function(e){const t=[...e].sort(((e,t)=>e.length-t.length)).reverse()[0].length,r=Buffer.allocUnsafe(t);for(let n=0;n<t;n++)r[n]=0,e.forEach((e=>{r[n]^=e[n]??0}));return r},t.getBit=function(e,t,r=1){let n=e.toString(2).split("");n=[...Array(8-n.length).fill("0"),...n];const s=n.slice(t,t+r).join("");return Number.parseInt(s,2)},t.paddingByte=function(e){const t=e.toString(2).split("");return[...[...Array(8-t.length)].map((()=>"0")),...t].join("")},t.paddingBits=function(e,t){const r=e.toString(2);return[...[...Array(t-r.length)].map((()=>"0")),...r].join("")},t.bufferWriter=function(e,t){return i(e)(t)},t.createBufferWriter=i,t.bufferWriterLE=function(e,t){const r=e.reduce(((e,t)=>e+t),0),n=Buffer.alloc(r);let s=0;return t.forEach(((t,r)=>{const i=e[r];8===i?n.writeBigUInt64LE(t,s):n.writeUIntLE(t,s,i),s+=i})),n},t.bufferReader=function(e,t){let r=0;return t.map((t=>{let n;return n=8===t?e.readBigUInt64BE(r):e.readUIntBE(r,t),r+=t,n}))},t.buffer2ArrayBuffer=function(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)};const n=r(6982),s=r(4694);t.BitWriter=class{constructor(e){this.bitLength=e,this.value=0}set(e,t,r){return r&=(1<<e)-1,this.value|=r<<this.bitLength-e-t,this}get buffer(){const e=Math.ceil(this.bitLength/8),t=Buffer.alloc(e);return t.writeUIntBE(this.value,0,e),t}};function i(e,t){const r=e.reduce(((e,t)=>e+t),0),n=t?Buffer.alloc(r):void 0;return t=>{const s=n||Buffer.alloc(r);let i=0;return t.forEach(((t,r)=>{const n=e[r];8===n?s.writeBigUInt64BE(t,i):s.writeUIntBE(t,i,n),i+=n})),s}}t.BitWriter2=class{constructor(e){if(this.bitLength=e,this._value=0n,this.offset=0n,e>32)throw new Error}set(e,t=1){let r=BigInt(e);const n=BigInt(t);return r&=(1n<<n)-1n,this._value|=r<<BigInt(this.bitLength)-n-this.offset,this.offset+=n,this}get value(){return Number(this._value)}get buffer(){const e=Math.ceil(this.bitLength/8),t=Buffer.alloc(e);return t.writeUIntBE(this.value,0,e),t}};t.BufferChain=class{constructor(e){this.buffer=Buffer.alloc(e)}writeInt16BE(e,t){return this.buffer.writeInt16BE(e,t),this}writeUInt8(e,t){return this.buffer.writeUInt8(e,t),this}};t.dumpBuffer=e=>"0x"+e.toString("hex").replace(/(.)(.)/g,"$1$2 ").split(" ").filter((e=>null!=e&&e.length>0)).join(",0x");t.BitStream=class{constructor(e){this.uint8Array=e,this.position=0,this.bitsPending=0}writeBits(e,t){if(0==e)return this;let r;return t&=4294967295>>>32-e,this.bitsPending>0?this.bitsPending>e?(this.uint8Array[this.position-1]|=t<<this.bitsPending-e,r=e,this.bitsPending-=e):this.bitsPending==e?(this.uint8Array[this.position-1]|=t,r=e,this.bitsPending=0):(this.uint8Array[this.position-1]|=t>>e-this.bitsPending,r=this.bitsPending,this.bitsPending=0):(r=Math.min(8,e),this.bitsPending=8-r,this.uint8Array[this.position++]=t>>e-r<<this.bitsPending),(e-=r)>0&&this.writeBits(e,t),this}readBits(e,t){if("undefined"==typeof t&&(t=0),0==e)return t;let r,n;if(this.bitsPending>0){const t=this.uint8Array[this.position-1]&255>>8-this.bitsPending;n=Math.min(this.bitsPending,e),this.bitsPending-=n,r=t>>this.bitsPending}else n=Math.min(8,e),this.bitsPending=8-n,r=this.uint8Array[this.position++]>>this.bitsPending;return t=t<<n|r,(e-=n)>0?this.readBits(e,t):t}seekTo(e){this.position=e/8|0,this.bitsPending=e%8,this.bitsPending>0&&(this.bitsPending=8-this.bitsPending,this.position++)}}},148:(e,t,r)=>{const n=r(2018),s=r(9023);t.init=function(e){e.inspectOpts={};const r=Object.keys(t.inspectOpts);for(let n=0;n<r.length;n++)e.inspectOpts[r[n]]=t.inspectOpts[r[n]]},t.log=function(...e){return process.stderr.write(s.format(...e)+"\n")},t.formatArgs=function(r){const{namespace:n,useColors:s}=this;if(s){const t=this.color,s="[3"+(t<8?t:"8;5;"+t),i=` ${s};1m${n} `;r[0]=i+r[0].split("\n").join("\n"+i),r.push(s+"m+"+e.exports.humanize(this.diff)+"")}else r[0]=function(){if(t.inspectOpts.hideDate)return"";return(new Date).toISOString()+" "}()+n+" "+r[0]},t.save=function(e){e?process.env.DEBUG=e:delete process.env.DEBUG},t.load=function(){return process.env.DEBUG},t.useColors=function(){return"colors"in t.inspectOpts?Boolean(t.inspectOpts.colors):n.isatty(process.stderr.fd)},t.destroy=s.deprecate((()=>{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=r(Object(function(){var e=new Error("Cannot find module 'supports-color'");throw e.code="MODULE_NOT_FOUND",e}()));e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const r=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let n=process.env[t];return n=!!/^(yes|on|true|enabled)$/i.test(n)||!/^(no|off|false|disabled)$/i.test(n)&&("null"===n?null:Number(n)),e[r]=n,e}),{}),e.exports=r(5729)(t);const{formatters:i}=e.exports;i.o=function(e){return this.inspectOpts.colors=this.useColors,s.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},i.O=function(e){return this.inspectOpts.colors=this.useColors,s.inspect(e,this.inspectOpts)}},314:(e,t,r)=>{const n=r(2018),s=r(9023);t.init=function(e){e.inspectOpts={};const r=Object.keys(t.inspectOpts);for(let n=0;n<r.length;n++)e.inspectOpts[r[n]]=t.inspectOpts[r[n]]},t.log=function(...e){return process.stderr.write(s.formatWithOptions(t.inspectOpts,...e)+"\n")},t.formatArgs=function(r){const{namespace:n,useColors:s}=this;if(s){const t=this.color,s="[3"+(t<8?t:"8;5;"+t),i=` ${s};1m${n} `;r[0]=i+r[0].split("\n").join("\n"+i),r.push(s+"m+"+e.exports.humanize(this.diff)+"")}else r[0]=function(){if(t.inspectOpts.hideDate)return"";return(new Date).toISOString()+" "}()+n+" "+r[0]},t.save=function(e){e?process.env.DEBUG=e:delete process.env.DEBUG},t.load=function(){return process.env.DEBUG},t.useColors=function(){return"colors"in t.inspectOpts?Boolean(t.inspectOpts.colors):n.isatty(process.stderr.fd)},t.destroy=s.deprecate((()=>{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=r(8551);e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const r=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let n=process.env[t];return n=!!/^(yes|on|true|enabled)$/i.test(n)||!/^(no|off|false|disabled)$/i.test(n)&&("null"===n?null:Number(n)),e[r]=n,e}),{}),e.exports=r(2887)(t);const{formatters:i}=e.exports;i.o=function(e){return this.inspectOpts.colors=this.useColors,s.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},i.O=function(e){return this.inspectOpts.colors=this.useColors,s.inspect(e,this.inspectOpts)}},336:function(e,t,r){"use strict";var n,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var s=Object.getOwnPropertyDescriptor(t,r);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},n(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=n(e),o=0;o<r.length;o++)"default"!==r[o]&&s(t,e,r[o]);return i(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.RtspServer=t.RtspClient=t.RtspBase=t.RtspStatusError=t.H265_NAL_TYPE_SEI_SUFFIX=t.H265_NAL_TYPE_SEI_PREFIX=t.H265_NAL_TYPE_FU=t.H265_NAL_TYPE_CRA_NUT=t.H265_NAL_TYPE_IDR_N_LP=t.H265_NAL_TYPE_IDR_W_RADL=t.H265_NAL_TYPE_BLA_N_LP=t.H265_NAL_TYPE_BLA_W_RADL=t.H265_NAL_TYPE_BLA_W_LP=t.H265_NAL_TYPE_PPS=t.H265_NAL_TYPE_SPS=t.H265_NAL_TYPE_VPS=t.H265_NAL_TYPE_AGG=t.H264_NAL_TYPE_MTAP32=t.H264_NAL_TYPE_MTAP16=t.H264_NAL_TYPE_FU_B=t.H264_NAL_TYPE_FU_A=t.H264_NAL_TYPE_STAP_B=t.H264_NAL_TYPE_STAP_A=t.H264_NAL_TYPE_PPS=t.H264_NAL_TYPE_SPS=t.H264_NAL_TYPE_SEI=t.H264_NAL_TYPE_IDR=t.H264_NAL_TYPE_RESERVED31=t.H264_NAL_TYPE_RESERVED30=t.H264_NAL_TYPE_RESERVED0=t.RTSP_FRAME_MAGIC=void 0,t.readMessage=w,t.readBody=b,t.writeMessage=_,t.findH264NaluType=function(e,t){if("h264"!==e.type)return;return P(e.chunks[e.chunks.length-1].subarray(12),t)},t.findH265NaluType=function(e,t){if("h265"!==e.type)return;return E(e.chunks[e.chunks.length-1].subarray(12),t)},t.parseH264NaluType=C,t.findH264NaluTypeInNalu=P,t.findH265NaluTypeInNalu=E,t.getStartedH264NaluTypes=A,t.getNaluTypesInNalu=I,t.getStartedH265NaluTypes=O,t.getNaluTypesInH265Nalu=R,t.isH265KeyFrameRelatedInSet=D,t.createRtspParser=function(e){let r;return{container:"rtsp",tcpProtocol:"rtsp://127.0.0.1/"+(0,c.randomBytes)(8).toString("hex"),inputArguments:["-rtsp_transport","tcp"],outputArguments:["-rtsp_transport","tcp",...e?.vcodec||[],...e?.acodec||[],"-pkt_size","32000","-f","rtsp"],findSyncFrame(e){for(let r=0;r<e.length;r++){const n=e[r];if("h264"===n.type){const s=A(n);if(s.has(t.H264_NAL_TYPE_SPS)||s.has(t.H264_NAL_TYPE_IDR))return e.slice(r)}else if("h265"===n.type){if(D(O(n)))return e.slice(r)}}},sdp:new Promise((e=>r=e)),async*parse(e,t,n){const s=new B(e);await s.handleSetup(),r(s.sdp);for await(const{type:e,rtcp:r,header:i,packet:o}of s.handleRecord())yield{chunks:[i,o],type:`${r?"rtcp-":""}${e}`,width:t,height:n}}}},t.parseHeaders=M,t.getFirstAuthenticateHeader=k,t.parseSemicolonDelimited=x,t.listenSingleRtspClient=async function(e){const t=e?.pathToken||c.default.randomBytes(8).toString("hex");let{url:r,clientPromise:n,server:s}=await(0,f.listenZeroSingleClient)(e?.hostname);const i="/"+t;r=r.replace("tcp:","rtsp:")+i;const o=n.then((t=>{const r=(e?.createServer||(e=>new B(e)))(t);return r.checkRequest=async(e,t,n,s)=>{r.checkRequest=void 0;return new p.URL(t).pathname===i},r}));return{url:r,rtspServerPromise:o,server:s}};const c=o(r(6982)),d=r(4434),u=a(r(9278)),l=a(r(4756)),p=r(7016),h=r(3290),f=r(3515),m=r(488),g=r(8460),y=r(4890),v=r(7724),S=["realm","nonce"];async function w(e){let t=[];for(;;){let r=await(0,g.readLine)(e);if(r=r.trim(),!r)return t;t.push(r)}}async function b(e,t){const r=parseInt(t["content-length"]);if(r)return(0,g.readLength)(e,r)}function _(e,t,r,n,s){let i=void 0!==t?`${t}\r\n`:"";r&&(n["Content-Length"]=r.length.toString());for(const[e,t]of Object.entries(n))i+=`${e}: ${t}\r\n`;i+="\r\n",e.write(i),s?.log("rtsp outgoing message\n",i),s?.log(),r&&e.write(r)}function C(e){return 31&e}function P(e,r){const n=C(e[0]);if(n===t.H264_NAL_TYPE_STAP_A){let t=1;for(;t<e.length;){const n=e.readUInt16BE(t);t+=2;if(C(e[t])===r)return e.subarray(t,t+n);t+=n}}else if(n===t.H264_NAL_TYPE_FU_A){const t=C(e[1]),n=!!(128&e[1]);if(t===r&&n)return e.subarray(1)}else if(n===r)return e}function T(e){return(126&e)>>1}function E(e,r){const n=T(e[0]);if(n===t.H265_NAL_TYPE_AGG){let t=1;for(;t<e.length;){const n=e.readUInt16BE(t);t+=2;if(T(e[t])===r)return e.subarray(t,t+n);t+=n}}else if(n===r)return e}function A(e){return"h264"!==e.type?new Set:I(e.chunks[e.chunks.length-1].subarray(12),!0)}function I(e,r=!1,n=!1){const s=new Set,i=C(e[0]);if(i===t.H264_NAL_TYPE_STAP_A){s.add(t.H264_NAL_TYPE_STAP_A);let r=1;for(;r<e.length;){const t=e.readUInt16BE(r);r+=2;const n=C(e[r]);s.add(n),r+=t}}else if(i===t.H264_NAL_TYPE_FU_A){s.add(t.H264_NAL_TYPE_FU_A);const i=C(e[1]);if(r){!!(128&e[1])&&s.add(i)}else if(n){!!(64&e[1])&&s.add(i)}else s.add(i)}else s.add(i);return s}function O(e){return"h265"!==e.type?new Set:R(e.chunks[e.chunks.length-1].subarray(12),!0)}function R(e,r=!1,n=!1){const s=new Set,i=T(e[0]);if(i===t.H265_NAL_TYPE_AGG){s.add(t.H265_NAL_TYPE_AGG);let r=2;for(;r<e.length;){const t=e.readUInt16BE(r);r+=2;const n=T(e[r]);s.add(n),r+=t}}else if(i===t.H265_NAL_TYPE_FU){s.add(t.H265_NAL_TYPE_FU);const i=63&e[2];if(r){!!(128&e[2])&&s.add(i)}else if(n){!!(64&e[2])&&s.add(i)}else s.add(i)}else s.add(i);return s}function D(e,r=!0){return!!(e.has(t.H265_NAL_TYPE_IDR_N_LP)||e.has(t.H265_NAL_TYPE_IDR_W_RADL)||e.has(t.H265_NAL_TYPE_CRA_NUT)||e.has(t.H265_NAL_TYPE_BLA_N_LP)||e.has(t.H265_NAL_TYPE_BLA_W_LP)||e.has(t.H265_NAL_TYPE_BLA_W_RADL))||!(!r||!(e.has(t.H265_NAL_TYPE_VPS)||e.has(t.H265_NAL_TYPE_SPS)||e.has(t.H265_NAL_TYPE_PPS)))}function M(e){const t={};for(const r of e.slice(1)){const e=r.indexOf(":");let n="";-1!==e&&(n=r.substring(e+1).trim());t[r.substring(0,e).toLowerCase()]=n}return t}function k(e){for(const t of e.slice(1)){const e=t.indexOf(":");let r="";-1!==e&&(r=t.substring(e+1).trim());if("www-authenticate"===t.substring(0,e).toLowerCase())return r}}function x(e){const t={};for(const r of e.split(";")){const[e,n]=r.split("=",2);t[e]=n}return t}t.RTSP_FRAME_MAGIC=36,t.H264_NAL_TYPE_RESERVED0=0,t.H264_NAL_TYPE_RESERVED30=30,t.H264_NAL_TYPE_RESERVED31=31,t.H264_NAL_TYPE_IDR=5,t.H264_NAL_TYPE_SEI=6,t.H264_NAL_TYPE_SPS=7,t.H264_NAL_TYPE_PPS=8,t.H264_NAL_TYPE_STAP_A=24,t.H264_NAL_TYPE_STAP_B=25,t.H264_NAL_TYPE_FU_A=28,t.H264_NAL_TYPE_FU_B=29,t.H264_NAL_TYPE_MTAP16=26,t.H264_NAL_TYPE_MTAP32=27,t.H265_NAL_TYPE_AGG=48,t.H265_NAL_TYPE_VPS=32,t.H265_NAL_TYPE_SPS=33,t.H265_NAL_TYPE_PPS=34,t.H265_NAL_TYPE_BLA_W_LP=16,t.H265_NAL_TYPE_BLA_W_RADL=17,t.H265_NAL_TYPE_BLA_N_LP=18,t.H265_NAL_TYPE_IDR_W_RADL=19,t.H265_NAL_TYPE_IDR_N_LP=20,t.H265_NAL_TYPE_CRA_NUT=21,t.H265_NAL_TYPE_FU=49,t.H265_NAL_TYPE_SEI_PREFIX=39,t.H265_NAL_TYPE_SEI_SUFFIX=40;class L extends Error{constructor(e){super(`RTSP Error: ${e.line}`),this.status=e}}t.RtspStatusError=L;class F{constructor(){}write(e,t,r){_(this.client,e,r,t,this.console)}async readMessage(){const e=await w(this.client);return this.console?.log("rtsp incoming message\n",e.join("\n")),this.console?.log(),e}}t.RtspBase=F;t.RtspClient=class extends F{constructor(e){super(),this.url=e,this.cseq=0,this.needKeepAlive=!1,this.setupOptions=new Map,this.issuedTeardown=!1,this.hasGetParameter=!0;const t=new p.URL(e),r=parseInt(t.port)||554;e.startsWith("rtsps")?this.client=l.default.connect({rejectUnauthorized:!1,port:r,host:t.hostname}):this.client=u.default.connect(r,t.hostname),this.client.on("error",(e=>{this.console?.log("client error",e)}))}async safeTeardown(){if(!this.issuedTeardown){this.issuedTeardown=!0;try{this.writeTeardown(),await(0,v.sleep)(500)}catch(e){}finally{this.client.destroy()}}}async writeRequest(e,t,r,n){let s;t=t||{},r?r.includes("rtsp://")||r.includes("rtsps://")||"*"===r?s=r:(s=this.contentBase||this.url,s+=(s.endsWith("/")?"":"/")+r):s=this.url;const i=new p.URL(s);i.username="",i.password="";const o=`${e} ${i} RTSP/1.0`,a=this.cseq++;t.CSeq=a.toString(),t["User-Agent"]="Scrypted",this.wwwAuthenticate&&(t.Authorization=await this.createAuthorizationHeader(e,new p.URL(s))),this.session&&(t.Session=this.session),this.write(o,t,n)}async handleDataPayload(e){if(e[0]!==t.RTSP_FRAME_MAGIC)throw new Error("RTSP Client received invalid frame magic. This may be a bug in your camera firmware. If this error persists, switch your RTSP Parser to FFmpeg or Scrypted (UDP): "+e.toString());const r=e.readUInt8(1),n=e.readUInt16BE(2),s=await(0,g.readLength)(this.client,n),i=this.setupOptions.get(r);i?.onRtp?.(e,s)}async readDataPayload(){const e=await(0,g.readLength)(this.client,4);return this.handleDataPayload(e)}createBadHeader(e){return new Error("RTSP Client received invalid frame magic. This may be a bug in your camera firmware. If this error persists, switch your RTSP Parser to FFmpeg or Scrypted (UDP): "+e.toString())}async readLoopLegacy(){try{for(;;)this.needKeepAlive&&(this.needKeepAlive=!1,this.hasGetParameter?await this.getParameter():await this.options()),await this.readDataPayload()}catch(e){throw this.client.destroy(e),e}}async*handleStream(){for(;;){const e=await(0,g.readLength)(this.client,4);if(e[0]!==t.RTSP_FRAME_MAGIC){if("RTSP"!==e.toString())throw this.createBadHeader(e);this.client.unshift(e);const t=await super.readMessage();await this.readBody(M(t));continue}const r=e.readUInt16BE(2),n=await(0,g.readLength)(this.client,r),s=e.readUInt8(1);yield{channel:s,rtcp:s%2==1,header:e,packet:n}}}async readLoop(){const e=new h.Deferred;let r,n,s;const i=async()=>{this.needKeepAlive&&(this.needKeepAlive=!1,this.hasGetParameter?this.writeGetParameter():this.writeOptions());try{for(;;){if(!r){if(r=this.client.read(4),!r)return;if(r[0]!==t.RTSP_FRAME_MAGIC){if("RTSP"!==r.toString())throw this.createBadHeader(r);this.client.unshift(r),r=void 0,this.client.removeListener("readable",i);const e=await super.readMessage();await this.readBody(M(e));this.client.on("readable",i);continue}n=r.readUInt8(1),s=r.readUInt16BE(2)}const e=this.client.read(s);if(!e)return;const o=r;r=void 0;const a=this.setupOptions.get(n);a?.onRtp?.(o,e)}}catch(t){e.finished||e.reject(t),this.client.destroy()}};i(),this.client.on("readable",i),await Promise.all([(0,d.once)(this.client,"end")])}async readMessage(){for(;;){const e=await(0,g.readLength)(this.client,4);if(e[0]!==t.RTSP_FRAME_MAGIC){if("RTSP"===e.toString()){this.client.unshift(e);return await super.readMessage()}throw this.createBadHeader(e)}await this.handleDataPayload(e)}}async createAuthorizationHeader(e,t){if(!this.wwwAuthenticate)throw new Error("no WWW-Authenticate found");const{BASIC:n}=await Promise.resolve().then(r.bind(r,7284)),{parseHTTPHeadersQuotedKeyValueSet:s}=await Promise.resolve().then(r.bind(r,2238)),i=new p.URL(this.url),o=decodeURIComponent(i.username),a=decodeURIComponent(i.password);if(this.wwwAuthenticate.includes("Basic")){return`Basic ${n.computeHash({username:o,password:a})}`}const d=s(this.wwwAuthenticate,{indexOf:()=>0},S),u=new p.URL(t.toString());u.username="",u.password="";const l=c.default.createHash("md5").update(`${o}:${d.realm}:${a}`).digest("hex"),h=c.default.createHash("md5").update(`${e}:${u}`).digest("hex"),f=c.default.createHash("md5").update(`${l}:${d.nonce}:${h}`).digest("hex"),m={username:o,realm:d.realm,nonce:d.nonce,uri:u.toString(),algorithm:"MD5",response:f};return`Digest ${Object.entries(m).map((([e,t])=>{return`${e}=${t&&(r=t,`"${r.replace(/"/g,'\\"')}"`)}`;var r})).join(", ")}`}async readBody(e){return b(this.client,e)}async request(e,t,r,n,s){await this.writeRequest(e,t,r,n);const i=this.requestTimeout?await(0,m.timeoutPromise)(this.requestTimeout,this.readMessage()):await this.readMessage(),o=i[0],[a,c,d]=o.split(" ",3),u=parseInt(c),l=M(i),p={line:o,code:u,version:a,reason:d};if(200!==u&&!l["www-authenticate"])throw new L(p);const h=k(i)||l["www-authenticate"];if(h){if(s)throw new Error("auth failed");return this.wwwAuthenticate=h,this.request(e,t,r,n,!0)}return{headers:l,body:await this.readBody(l),status:p}}async options(){const e=await this.request("OPTIONS",{}),t=e.headers.public;return t&&(this.hasGetParameter=t.toLowerCase().includes("get_parameter")),e}writeOptions(){return this.writeRequest("OPTIONS")}async getParameter(){return this.request("GET_PARAMETER")}writeGetParameter(){return this.writeRequest("GET_PARAMETER")}async describe(e){const t=await this.request("DESCRIBE",{...e||{},Accept:"application/sdp"});return this.contentBase=t.headers["content-base"]||t.headers["content-location"],this.contentBase&&(this.contentBase=new p.URL(this.contentBase,this.url).toString()),t}async setup(e,t){const r="udp"===e.type?"":"/TCP",n="udp"===e.type?"client_port":"interleaved";let s;if("tcp"===e.type)s=e.port;else{if(!e.dgram){const t=await(0,f.createBindZero)();e.dgram=t.server,this.client.on("close",(()=>(0,f.closeQuiet)(t.server)))}s=e.dgram.address().port,e.dgram.on("message",(t=>e.onRtp(void 0,t)))}t=Object.assign({Transport:`RTP/AVP${r};unicast;${n}=${s}-${s+1}`},t);const i=await this.request("SETUP",t,e.path);let o;if(i.headers.session){const e=x(i.headers.session);let t=parseInt(e.timeout);if(t){let e=setInterval((()=>this.needKeepAlive=!0),1e3*(t-5));this.client.once("close",(()=>clearInterval(e)))}this.session=i.headers.session.split(";")[0]}if(i.headers.transport){const e=i.headers.transport.match(/.*?interleaved=([0-9]+)-([0-9]+)/);if(e){const[t,r,n]=e;r&&n&&(o={begin:parseInt(r),end:parseInt(n)})}}return"tcp"===e.type&&this.setupOptions.set(o?o.begin:s,e),Object.assign({interleaved:o,options:e},i)}async play(e={},t="0.000"){return e.Range=`npt=${t}-`,this.request("PLAY",e)}writePlay(e="0.000"){const t={Range:`npt=${e}-`};return this.writeRequest("PLAY",t)}writeRtpPayload(e,t){return this.client.write(e),this.client.write(Buffer.from(t))}send(e,r){const n=Buffer.alloc(4);return n.writeUInt8(t.RTSP_FRAME_MAGIC,0),n.writeUInt8(r,1),n.writeUInt16BE(e.length,2),this.writeRtpPayload(n,e)}async pause(){return this.request("PAUSE")}async teardown(){try{return await this.request("TEARDOWN")}finally{this.client.destroy()}}writeTeardown(){this.writeRequest("TEARDOWN")}};class B{constructor(e,t,r,n){this.client=e,this.sdp=t,this.udp=r,this.checkRequest=n,this.setupTracks={},this.availableOptions=["DESCRIBE","OPTIONS","PAUSE","PLAY","SETUP","TEARDOWN","ANNOUNCE","RECORD","GET_PARAMETER"],this.session=(0,c.randomBytes)(4).toString("hex"),t&&(t=t.trim()),e instanceof u.default.Socket&&e.setNoDelay(!0)}async handleSetup(e=["play","record","teardown"]){let t=[];for(;;){let r=await(0,g.readLine)(this.client);if(r=r.trim(),r)t.push(r);else{const r=await this.headers(t);if(e.includes(r))return r;t=[]}}}async handlePlayback(){return this.handleSetup()}async handleTeardown(){return this.handleSetup()}async*handleRecord(){for(;;){const e=await(0,g.readLength)(this.client,4);if(e[0]!==t.RTSP_FRAME_MAGIC)throw new Error("RTSP Server expected frame magic but received: "+e.toString());const r=e.readUInt16BE(2),n=await(0,g.readLength)(this.client,r),s=e.readUInt8(1),i=s-s%2,o=Object.values(this.setupTracks).find((e=>e.destination===i));if(!o)throw new Error("RSTP Server received unknown channel: "+s);yield{type:o.codec,rtcp:s%2==1,header:e,packet:n}}}writeRtpPayload(e,t){return this.client.write(e),this.client.write(Buffer.from(t))}send(e,t){const r=Buffer.alloc(4);return r.writeUInt8(36,0),r.writeUInt8(t,1),r.writeUInt16BE(e.length,2),this.writeRtpPayload(r,e)}sendUdp(e,t,r){e.send(r,t,"127.0.0.1")}sendTrack(e,t,r){const n=this.setupTracks[e];return n?"udp"===n.protocol?(this.udp?this.sendUdp(r?n.rtcp:n.rtp,n.destination,t):this.console?.warn("RTSP Server UDP socket not available."),!0):this.send(t,r?n.destination+1:n.destination):(this.console?.warn("RTSP Server track not found:",e),!0)}options(e,t){const r={};r.Public=this.availableOptions.join(", "),this.respond(200,"OK",t,r)}async get_parameter(e,t){this.respond(200,"OK",t,{})}describe(e,t){const r={};r["Content-Base"]=e,r["Content-Type"]="application/sdp",this.respond(200,"OK",t,r,Buffer.from(this.sdp))}setupInterleaved(e,t,r){this.setupTracks[e.control]={control:e.control,protocol:"tcp",destination:t,codec:e.codec}}async setup(e,t){const r={};let n=t.transport;r.Session=this.session;const s=(0,y.parseSdp)(this.sdp).msections.find((t=>e.endsWith(t.control)));if(s){if(n.includes("TCP"))if(this.resolveInterleaved){const[e,t]=this.resolveInterleaved(s);this.setupInterleaved(s,e,t),n=`RTP/AVP/TCP;unicast;interleaved=${e}-${t}`}else{const e=n.match(/.*?interleaved=([0-9]+)-([0-9]+)/);if(e){const t=parseInt(e[1]),r=parseInt(e[2]);this.setupInterleaved(s,t,r)}}else{if(!this.udp)return void this.respond(461,"Unsupported Transport",t,{});const e=n.match(/.*?client_port=([0-9]+)-([0-9]+)/),[r,i,o]=e,[a,c]=await(0,f.createSquentialBindZero)();this.client.on("close",(()=>(0,f.closeQuiet)(a.server))),this.client.on("close",(()=>(0,f.closeQuiet)(c.server))),this.setupTracks[s.control]={control:s.control,protocol:"udp",destination:parseInt(i),codec:s.codec,rtp:a.server,rtcp:c.server},n=n.replace("RTP/AVP/UDP","RTP/AVP").replace("RTP/AVP","RTP/AVP/UDP"),n+=`;server_port=${a.port}-${c.port}`}r.Transport=n,this.respond(200,"OK",t,r)}else this.respond(404,"Not Found",t,r)}play(e,t){const r={},n=Object.values(this.setupTracks).map((t=>`url=${e}/${t.control}`)).join(",");r["RTP-Info"]=n,r.Range="npt=now-",r.Session=this.session,this.respond(200,"OK",t,r)}async announce(e,t){const r=parseInt(t["content-length"]),n=await(0,g.readLength)(this.client,r);this.sdp=n.toString();const s={};s.Session=this.session,this.respond(200,"OK",t,s)}async record(e,t){const r={};r.Session=this.session,this.respond(200,"OK",t,r)}async teardown(e,t){const r={};r.Session=this.session,this.respond(200,"OK",t,r),this.client.destroy()}async headers(e){this.console?.log("request headers",e.join("\n"));let[t,r]=e[0].split(" ",2);t=t.toLowerCase();const n=M(e);if(this.checkRequest){let s;try{s=await this.checkRequest(t,r,n,e)}catch(e){this.console?.error("error checking request",e)}if(!s)throw this.respond(400,"Bad Request",n,{}),this.client.destroy(),new Error("check request failed")}if(this[t]&&this.availableOptions.includes(t.toUpperCase()))return await this[t](r,n),t;this.respond(400,"Bad Request",n,{})}respond(e,t,r,n,s){let i=`RTSP/1.0 ${e} ${t}\r\n`;r.cseq&&(n.CSeq=r.cseq),s&&(n["Content-Length"]=s.length.toString());for(const[e,t]of Object.entries(n))i+=`${e}: ${t}\r\n`;this.console?.log("response headers",i),i+="\r\n",this.client.write(i),s&&(this.client.write(s),this.console?.log("response body",s.toString()))}destroy(){this.client.destroy();for(const e of Object.values(this.setupTracks))(0,f.closeQuiet)(e.rtp),(0,f.closeQuiet)(e.rtcp)}}t.RtspServer=B},394:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=394,e.exports=t},431:function(e,t,r){"use strict";var n,s=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var s=Object.getOwnPropertyDescriptor(t,r);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||(n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r);return t},n(e)},function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r=n(e),o=0;o<r.length;o++)"default"!==r[o]&&s(t,e,r[o]);return i(t,e),t}),a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const c=r(3716),d=r(3643),u=r(8460),l=o(r(2743)),p=a(r(5317)),h=r(2203),f=r(9847),m=r(4053),g=r(8876),y=r(4504),{mediaManager:v}=l.default,S="Amcrest Doorbell",w="Dahua Doorbell",b={subgroup:"Advanced",key:"rtspChannel",title:"Channel Number Override",description:"The channel number to use for snapshots and video. E.g., 1, 2, etc.",placeholder:"1"};class _ extends m.RtspSmartCamera{constructor(e,t){super(e,t),this.onvifIntercom=new f.OnvifIntercom(this),"true"===this.storage.getItem("amcrestDoorbell")&&(this.storage.setItem("doorbellType",S),this.storage.removeItem("amcrestDoorbell")),this.hasSmartDetection="true"===this.storage.getItem("hasSmartDetection"),this.updateDevice(),this.updateDeviceInfo()}async getVideoTextOverlays(){const e=this.getClient(),t=(await e.request({method:"GET",url:`http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=getConfig&name=VideoWidget`,responseType:"text",headers:{"Content-Type":"application/xml"}})).body;if(t.startsWith("<"))throw new Error("invalid response");{const e=".EncodeBlend",r={};for(const n of t.split(/\r?\n/).filter((t=>t.includes(e+"=")))){const t=n.trim();if(!t)continue;const s=t.indexOf("=");if(-1===s)continue;let i=t.substring(0,s);i=i.substring(0,i.length-e.length),r[i]={readonly:!0}}const n=".Text";for(const e of t.split(/\r?\n/).filter((e=>e.includes(n+"=")))){const t=e.trim();if(!t)continue;const s=t.indexOf("=");if(-1===s)continue;let i=t.substring(0,s);i=i.substring(0,i.length-n.length);const o=t.substring(s+1).trim(),a=r[i];a&&(delete a.readonly,a.text=o)}return r}}async setVideoTextOverlay(e,t){e.startsWith("table.")&&(e=e.substring(6));const r=this.getClient();if(t.text){const n=`http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${e}.EncodeBlend=true&${e}.PreviewBlend=true`;await r.request({method:"GET",url:n,responseType:"text"});const s=`http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${e}.Text=${encodeURIComponent(t.text)}`;await r.request({method:"GET",url:s,responseType:"text"})}else{const t=`http://${this.getHttpAddress()}/cgi-bin/configManager.cgi?action=setConfig&${e}.EncodeBlend=false&${e}.PreviewBlend=false`;await r.request({method:"GET",url:t,responseType:"text"})}}async reboot(){const e=this.getClient();await e.reboot()}getRecordingStreamCurrentTime(e){throw new Error("Method not implemented.")}getRecordingStreamThumbnail(e){throw new Error("Method not implemented.")}async getRecordingStream(e){const t=new Date(e.startTime),r=(t.getMonth()+1).toString().padStart(2,"0"),n=t.getDate().toString().padStart(2,"0"),s=t.getFullYear(),i=t.getHours().toString().padStart(2,"0"),o=t.getMinutes().toString().padStart(2,"0"),a=t.getSeconds().toString().padStart(2,"0"),c=`rtsp://${this.getRtspAddress()}/cam/playback?channel=1&starttime=${s}_${r}_${n}_${i}_${o}_${a}`,d=this.addRtspCredentials(c);return this.createMediaStreamUrl(d,void 0)}getRecordingStreamOptions(){return this.getVideoStreamOptions()}async updateDeviceInfo(){const e=this.storage.getItem("ip");if(!e)return;const t=`http://${e}`,r={...this.info,ip:e,managementUrl:t},n=[{action:"getVendor",replace:"vendor=",parameter:"manufacturer"},{action:"getSerialNo",replace:"sn=",parameter:"serialNumber"},{action:"getDeviceType",replace:"type=",parameter:"model"},{action:"getSoftwareVersion",replace:"version=",parameter:"firmware"}];for(const e of n)try{const t=await this.getClient().request({url:`http://${this.getHttpAddress()}/cgi-bin/magicBox.cgi?action=${e.action}`,responseType:"text"}),n=String(t.body).replace(e.replace,"").trim();r[e.parameter]=n}catch(t){this.console.error("Error getting device parameter",e.action,t)}this.info=r}async setVideoStreamOptions(e){const t=parseInt(this.getRtspChannel())||1;return this.getClient().configureCodecs(t,e)}getClient(){return this.client||(this.client=new g.AmcrestCameraClient(this.getHttpAddress(),this.getUsername(),this.getPassword(),this.console)),this.client}async listenEvents(){let e;const t=()=>{clearTimeout(e),e=setTimeout((()=>{this.motionDetected=!1}),2e4)},r=new g.AmcrestCameraClient(this.getHttpAddress(),this.getUsername(),this.getPassword(),this.console),n=await r.listenEvents(),s=this.storage.getItem("doorbellType"),i=this.storage.getItem("callerID"),o="true"===this.storage.getItem("multipleCallIds");let a;return n.on("event",((e,r,n)=>{const c=this.getRtspChannel();if(c){if((parseInt(r)+1).toString()!==c)return}e===g.AmcrestEvent.MotionStart||e===g.AmcrestEvent.SmartMotionHuman||e===g.AmcrestEvent.SmartMotionVehicle||e===g.AmcrestEvent.CrossLineDetection||e===g.AmcrestEvent.CrossRegionDetection?(this.motionDetected=!0,t()):e===g.AmcrestEvent.MotionInfo?(this.motionDetected||(this.motionDetected=!0),t()):e===g.AmcrestEvent.MotionStop||(e===g.AmcrestEvent.AudioStart?this.audioDetected=!0:e===g.AmcrestEvent.AudioStop?this.audioDetected=!1:e===g.AmcrestEvent.TalkInvite||e===g.AmcrestEvent.PhoneCallDetectStart||e===g.AmcrestEvent.AlarmIPCStart||e===g.AmcrestEvent.DahuaTalkInvite?e===g.AmcrestEvent.DahuaTalkInvite&&n&&o?n.includes(i)&&(this.binaryState=!0):this.binaryState=!0:e===g.AmcrestEvent.TalkHangup||e===g.AmcrestEvent.PhoneCallDetectStop||e===g.AmcrestEvent.AlarmIPCStop||e===g.AmcrestEvent.DahuaCallDeny||e===g.AmcrestEvent.DahuaTalkHangup?this.binaryState=!1:e===g.AmcrestEvent.TalkPulse&&s===S?n.includes("Invite")?this.binaryState=!0:n.includes("Hangup")&&(this.binaryState=!1):e===g.AmcrestEvent.DahuaTalkPulse&&s===w&&(clearTimeout(a),a=setTimeout((()=>this.binaryState=!1),3e3),this.binaryState=!0))})),n.on("smart",((e,t)=>{this.hasSmartDetection||(this.hasSmartDetection=!0,this.storage.setItem("hasSmartDetection","true"),this.updateDevice());const r={timestamp:Date.now(),detections:[{score:1,className:e}]};this.onDeviceEvent(l.ScryptedInterface.ObjectDetector,r)})),n}async getDetectionInput(e,t){}async getObjectTypes(){return{classes:["person","face","car"]}}async getOtherSettings(){const e=await super.getOtherSettings();e.push({subgroup:"Advanced",title:"Doorbell Type",choices:["Not a Doorbell",S,w],description:"If this device is a doorbell, select the appropriate doorbell type.",value:this.storage.getItem("doorbellType")||"Not a Doorbell",key:"doorbellType"});const t=this.storage.getItem("doorbellType"),r=t===S||t===w;let n=this.storage.getItem("twoWayAudio");const s=["Amcrest","ONVIF"];r||s.unshift("None"),n=s.find((e=>e===n)),n||(n=r?"Amcrest":"None"),t==w&&(e.push({title:"Enable Dahua Lock",key:"enableDahuaLock",description:"Some Dahua Doorbells have a built in lock/door access control.",type:"boolean",value:("true"===this.storage.getItem("enableDahuaLock")).toString()}),e.push({title:"Multiple Call Buttons",key:"multipleCallIds",description:"Some Dahua Doorbells integrate multiple Call Buttons for apartment buildings.",type:"boolean",value:("true"===this.storage.getItem("multipleCallIds")).toString()}));this.storage.getItem("multipleCallIds")&&e.push({title:"Caller ID",key:"callerID",description:"Caller ID",type:"number",value:this.storage.getItem("callerID")}),e.push({subgroup:"Advanced",title:"Two Way Audio",value:n,key:"twoWayAudio",description:"Amcrest cameras may support both Amcrest and ONVIF two way audio protocols. ONVIF generally performs better when supported.",choices:s});const i={...c.automaticallyConfigureSettings,subgroup:"Advanced"};return i.type="button",e.push(i),e.push({...y.amcrestAutoConfigureSettings,subgroup:"Advanced"}),e}async takeSmartCameraPicture(e){return this.createMediaObject(await this.getClient().jpegSnapshot(e?.timeout),"image/jpeg")}async getUrlSettings(){return[{...b,value:this.storage.getItem("rtspChannel")},...await super.getUrlSettings()]}getRtspChannel(){return this.storage.getItem("rtspChannel")}createRtspMediaStreamOptions(e,t){const r=(0,m.createRtspMediaStreamOptions)(e,t);return r.tool="scrypted",r}async getConstructedVideoStreamOptions(){const e=this.getClient();return this.videoStreamOptions||(this.videoStreamOptions=(async()=>{const t=parseInt(this.getRtspChannel())||1;try{let r;try{r=await e.getCodecs(t),this.storage.setItem("vsosJSON",JSON.stringify(r))}catch(e){this.console.error("error retrieving stream configurations",e),r=JSON.parse(this.storage.getItem("vsosJSON"))}for(const[e,n]of r.entries())n.tool="scrypted",n.url=`rtsp://${this.getRtspAddress()}/cam/realmonitor?channel=${t}&subtype=${e}`;return r}catch(e){this.videoStreamOptions=void 0;return[...Array(2).keys()].map((e=>{const r=(0,m.createRtspMediaStreamOptions)(`rtsp://${this.getRtspAddress()}/cam/realmonitor?channel=${t}&subtype=${e}`,e);return r.tool="scrypted",r}))}})()),this.videoStreamOptions}updateDevice(){const e=this.storage.getItem("doorbellType"),t=e===S||e===w,r="true"===this.storage.getItem("twoWayAudio")||"ONVIF"===this.storage.getItem("twoWayAudio")||"Amcrest"===this.storage.getItem("twoWayAudio"),n=this.provider.getInterfaces();let s;t&&(s=l.ScryptedDeviceType.Doorbell,n.push(l.ScryptedInterface.BinarySensor)),(t||r)&&n.push(l.ScryptedInterface.Intercom);const i="true"===this.storage.getItem("enableDahuaLock");t&&e===w&&i&&n.push(l.ScryptedInterface.Lock);"true"===this.storage.getItem("continuousRecording")&&n.push(l.ScryptedInterface.VideoRecorder),this.hasSmartDetection&&n.push(l.ScryptedInterface.ObjectDetector),this.provider.updateDevice(this.nativeId,this.name,n,s)}async putSetting(e,t){if(e!==c.automaticallyConfigureSettings.key){if("continuousRecording"===e)if("true"===t)try{await this.getClient().enableContinousRecording(parseInt(this.getRtspChannel())||1),this.storage.setItem("continuousRecording","true")}catch(e){this.log.a("There was an error enabling continuous recording."),this.console.error("There was an error enabling continuous recording.",e)}else this.storage.removeItem("continuousRecording");this.client=void 0,this.videoStreamOptions=void 0,super.putSetting(e,t),this.updateDevice(),this.updateDeviceInfo()}else{const e=this.getClient();(0,y.autoconfigureSettings)(e,parseInt(this.getRtspChannel())||1).then((()=>{this.log.a("Successfully configured settings.")})).catch((e=>{this.log.a("There was an error automatically configuring settings. More information can be viewed in the console."),this.console.error("error autoconfiguring",e)}))}}async startIntercom(e){if("ONVIF"===this.storage.getItem("twoWayAudio")){const t=(await this.getConstructedVideoStreamOptions())[0],r=new URL(t.url);return r.searchParams.set("proto","Onvif"),this.onvifIntercom.url=r.toString(),this.onvifIntercom.startIntercom(e)}const t=this.storage.getItem("doorbellType"),r=parseInt(this.getRtspChannel())||1,n=await v.convertMediaObjectToBuffer(e,l.ScryptedMimeTypes.FFmpegInput),s=JSON.parse(n.toString()).inputArguments.slice();let i;s.unshift("-hide_banner"),t==w?(s.push("-vn","-acodec","pcm_alaw","-ac","1","-ar","8000","-sample_fmt","s16","-f","alaw","pipe:3"),i="Audio/G.711A"):(s.push("-vn","-acodec","aac","-f","adts","pipe:3"),i="Audio/AAC"),this.console.log("ffmpeg intercom",s);const o=await v.getFFmpegPath();this.cp=p.default.spawn(o,s,{stdio:["pipe","pipe","pipe","pipe"]}),this.cp.on("exit",(()=>this.cp=void 0)),(0,d.ffmpegLogInitialOutput)(this.console,this.cp);const a=this.cp.stdio[3];(async()=>{const e=`http://${this.getHttpAddress()}/cgi-bin/audio.cgi?action=postAudio&httptype=singlepart&channel=${r}`;this.console.log("posting audio data to",e);const t=new h.PassThrough,n=new AbortController;this.getClient().request({url:e,method:"POST",headers:{"Content-Type":i,"Content-Length":"9999999"},signal:n.signal,responseType:"readable"},t).catch((()=>{})).finally((()=>this.console.log("request finished")));try{for(;;){const e=await(0,u.readLength)(a,1024);t.push(e)}}catch(e){}finally{this.console.log("audio finished"),t.destroy(),n.abort()}this.stopIntercom()})()}async stopIntercom(){if("ONVIF"===this.storage.getItem("twoWayAudio"))return this.onvifIntercom.stopIntercom();this.cp?.kill(),this.cp=void 0}showRtspUrlOverride(){return!1}async lock(){this.client.lock()||this.console.error("Could not lock")}async unlock(){this.client.unlock()||this.console.error("Could not unlock")}}class C extends m.RtspProvider{constructor(e){super(e),(0,c.checkPluginNeedsAutoConfigure)(this)}getAdditionalInterfaces(){return[l.ScryptedInterface.Reboot,l.ScryptedInterface.VideoCameraConfiguration,l.ScryptedInterface.Camera,l.ScryptedInterface.AudioSensor,l.ScryptedInterface.MotionSensor,l.ScryptedInterface.VideoTextOverlays]}getScryptedDeviceCreator(){return"Amcrest Camera"}async createDevice(e,t){const r=`${e.ip}:${e.httpPort||80}`;let n={};const s=e.username?.toString(),i=e.password?.toString(),o="true"===e.skipValidate?.toString();let a;const c=new g.AmcrestCameraClient(r,s,i,this.console);if(e.autoconfigure){const t=parseInt(e.rtspChannel)||1;await(0,y.autoconfigureSettings)(c,t)}if(!o){try{const t=await c.getDeviceInfo();e.newCamera=t.deviceType,n.model=t.deviceType,n.serialNumber=t.serialNumber}catch(e){throw this.console.error("Error adding Amcrest camera",e),e}try{await c.checkTwoWayAudio()&&(a="ONVIF")}catch(e){this.console.warn("Error probing two way audio",e)}}e.newCamera||="Amcrest Camera",t=await super.createDevice(e,t);const d=await this.getDevice(t);return d.info=n,d.putSetting("username",s),d.putSetting("password",i),e.rtspChannel&&d.putSetting("rtspChannel",e.rtspChannel),d.setHttpPortOverride(e.httpPort?.toString()),d.setIPAddress(e.ip?.toString()),a&&d.putSetting("twoWayAudio",a),d.updateDeviceInfo(),t}async getCreateDeviceSettings(){return[{key:"username",title:"Username"},{key:"password",title:"Password",type:"password"},{key:"ip",title:"IP Address",placeholder:"192.168.2.222"},b,{subgroup:"Advanced",key:"httpPort",title:"HTTP Port",description:"Optional: Override the HTTP Port from the default value of 80.",placeholder:"80"},c.automaticallyConfigureSettings,y.amcrestAutoConfigureSettings,{subgroup:"Advanced",key:"skipValidate",title:"Skip Validation",description:"Add the device without verifying the credentials and network settings.",type:"boolean"}]}createCamera(e){return new _(e,this)}}t.default=C},488:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TimeoutError=void 0,t.singletonPromise=function(e,t,r=0){if(e?.promise)return e;const n=t();e?e.promise=n:e={promise:n,cacheDuration:r};return n.finally((()=>setTimeout((()=>e.promise=void 0),e.cacheDuration))),e},t.timeoutPromise=function(e,t){return new Promise(((n,s)=>{const i=setTimeout((()=>s(new r(t))),e);t.then((e=>{clearTimeout(i),n(e)})).catch((e=>{clearTimeout(i),s(e)}))}))},t.timeoutFunction=function(e,t){return new Promise(((n,s)=>{let i=!1;const o=t((()=>i)),a=setTimeout((()=>{i=!0,s(new r(o))}),e);o.then((e=>{clearTimeout(a),n(e)})).catch((e=>{clearTimeout(a),s(e)}))}))},t.createPromiseDebouncer=function(){let e;return t=>(e||(e=t().finally((()=>e=void 0))),e)},t.createMapPromiseDebouncer=function(){const e=new Map;return(t,r,n)=>{const s=JSON.stringify(t);let i=e.get(s);return i||(i=n().finally((()=>{r?setTimeout((()=>e.delete(s)),r):e.delete(s)})),e.set(s,i)),i}};class r extends Error{constructor(e){super("Operation Timed Out"),this.promise=e}}t.TimeoutError=r},673:function(e,t,r){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.debug=t.WeriftError=void 0;const s=n(r(4652));class i extends Error{constructor(e){super(e.message)}toJSON(){return{message:this.message,payload:JSON.parse(JSON.stringify(this.payload)),path:this.path}}}t.WeriftError=i,t.debug=s.default.debug},857:e=>{"use strict";e.exports=require("os")},932:e=>{"use strict";e.exports=require("process")},1193:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RtpPacket=t.RtpHeader=t.ExtensionProfiles=void 0;const n=r(9543);t.ExtensionProfiles={OneByte:48862,TwoByte:4096};class s{constructor(e={}){this.version=2,this.padding=!1,this.paddingSize=0,this.extension=!1,this.marker=!1,this.payloadOffset=0,this.payloadType=0,this.sequenceNumber=0,this.timestamp=0,this.ssrc=0,this.csrcLength=0,this.csrc=[],this.extensionProfile=t.ExtensionProfiles.OneByte,this.extensions=[],Object.assign(this,e)}static deSerialize(e){const r=new s;let i=0;const o=e[i++];r.version=(0,n.getBit)(o,0,2),r.padding=(0,n.getBit)(o,2)>0,r.extension=(0,n.getBit)(o,3)>0,r.csrcLength=(0,n.getBit)(o,4,4),r.csrc=[...Array(r.csrcLength)].map((()=>{const t=e.readUInt32BE(i);return i+=4,t})),i+=11;const a=e[1];r.marker=(0,n.getBit)(a,0)>0,r.payloadType=(0,n.getBit)(a,1,7),r.sequenceNumber=e.readUInt16BE(2),r.timestamp=e.readUInt32BE(4),r.ssrc=e.readUInt32BE(8);for(let t=0;t<r.csrc.length;t++){const n=12+4*t;r.csrc[t]=e.subarray(n).readUInt32BE()}if(r.extension){r.extensionProfile=e.subarray(i).readUInt16BE(),i+=2;const n=4*e.subarray(i).readUInt16BE();switch(r.extensionLength=n,i+=2,r.extensionProfile){case t.ExtensionProfiles.OneByte:{const t=i+n;for(;i<t;){if(0===e[i]){i++;continue}const t=e[i]>>4,n=1+(e[i]&(240^e[i]));if(i++,15===t)break;const s={id:t,payload:e.subarray(i,i+n)};r.extensions=[...r.extensions,s],i+=n}}break;case t.ExtensionProfiles.TwoByte:{const t=i+n;for(;i<t;){if(0===e[i]){i++;continue}const t=e[i];i++;const n=e[i];i++;const s={id:t,payload:e.subarray(i,i+n)};r.extensions=[...r.extensions,s],i+=n}}break;default:{const t={id:0,payload:e.subarray(i,i+n)};r.extensions=[...r.extensions,t],i+=r.extensions[0].payload.length}}}return r.payloadOffset=i,r.padding&&(r.paddingSize=e[e.length-1]),r}get serializeSize(){const{csrc:e,extensionProfile:r,extensions:n}=this;let s=12+4*e.length;if(n.length>0||!0===this.extension){let e=4;switch(r){case t.ExtensionProfiles.OneByte:for(const t of n)e+=1+t.payload.length;break;case t.ExtensionProfiles.TwoByte:for(const t of n)e+=2+t.payload.length;break;default:e+=n[0].payload.length}s+=4*Math.floor((e+3)/4)}return s}serialize(e){const r=Buffer.alloc(e);let s=0;const i=new n.BitWriter(8);i.set(2,0,this.version),this.padding&&i.set(1,2,1),this.extensions.length>0&&(this.extension=!0),this.extension&&i.set(1,3,1),i.set(4,4,this.csrc.length),r.writeUInt8(i.value,s++);const o=new n.BitWriter(8);this.marker&&o.set(1,0,1),o.set(7,1,this.payloadType),r.writeUInt8(o.value,s++),r.writeUInt16BE(this.sequenceNumber,2),s+=2,r.writeUInt32BE(this.timestamp,4),s+=4,r.writeUInt32BE(this.ssrc,8),s+=4;for(const e of this.csrc)r.writeUInt32BE(e,s),s+=4;if(this.extension){const e=s;r.writeUInt16BE(this.extensionProfile,s),s+=4;const n=s;switch(this.extensionProfile){case t.ExtensionProfiles.OneByte:for(const e of this.extensions)r.writeUInt8(e.id<<4|e.payload.length-1,s++),e.payload.copy(r,s),s+=e.payload.length;break;case t.ExtensionProfiles.TwoByte:for(const e of this.extensions)r.writeUInt8(e.id,s++),r.writeUInt8(e.payload.length,s++),e.payload.copy(r,s),s+=e.payload.length;break;default:{const e=this.extensions[0].payload.length;if(e%4!=0)throw new Error;this.extensions[0].payload.copy(r,s),s+=e}}const i=s-n,o=4*Math.trunc((i+3)/4);r.writeUInt16BE(Math.trunc(o/4),e+2);for(let e=0;e<o-i;e++)r.writeUInt8(0,s),s++}return this.payloadOffset=s,r}}t.RtpHeader=s;class i{constructor(e,t){this.header=e,this.payload=t}get serializeSize(){return this.header.serializeSize+this.payload.length}clone(){return new i(new s({...this.header}),this.payload)}serialize(){let e=this.header.serialize(this.header.serializeSize+this.payload.length);const{payloadOffset:t}=this.header;if(this.payload.copy(e,t),this.header.padding){const t=Buffer.alloc(this.header.paddingSize);t.writeUInt8(this.header.paddingSize,this.header.paddingSize-1),e=Buffer.concat([e,t])}return e}static deSerialize(e){const t=s.deSerialize(e);return new i(t,e.subarray(t.payloadOffset,e.length-t.paddingSize))}clear(){this.payload=null}}t.RtpPacket=i},1251:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.authHttpFetch=void 0;const n=r(9049),s=r(3750);t.authHttpFetch=(0,s.createAuthFetch)(n.httpFetch,n.httpFetchParseIncomingMessage)},1470:(e,t,r)=>{"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?e.exports=r(9710):e.exports=r(148)},2018:e=>{"use strict";e.exports=require("tty")},2203:e=>{"use strict";e.exports=require("stream")},2238:(e,t,r)=>{"use strict";r.d(t,{$:()=>d,parseHTTPHeadersQuotedKeyValueSet:()=>c});var n=r(7371);const s='"',i="=",o=", ",a=/\w+=(".*?"|[^",]+)(?=,|$)/g;function c(e,t,r=[],s=[]){const o=e.trim().match(a);if(!o)throw new n.w("E_MALFORMED_QUOTEDKEYVALUE",e);const c=o.map(((e,t)=>{const[r,...s]=e.split(i),o=s.join(i);if(0===s.length)throw new n.w("E_MALFORMED_QUOTEDKEYVALUE",t,e);return[r,o]})).reduce((function(e,[r,i],o){const a=r.toLowerCase();if(-1===t.indexOf(a))throw new n.w("E_UNAUTHORIZED_KEY",o,a);const c=i.replace(/^"(.+(?="$))"$/,"$1");return e[a]=s.includes(a)?c.toLowerCase():c,e}),{});return u(r,c),c}function d(e,t,r=[]){return u(r,e),t.reduce((function(t,r){return e[r]?t+(t?o:"")+r+i+s+e[r]+s:t}),"")}function u(e,t){e.forEach((e=>{if("undefined"==typeof t[e])throw new n.w("E_REQUIRED_KEY",e)}))}},2613:e=>{"use strict";e.exports=require("assert")},2743:function(e,t,r){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r);var s=Object.getOwnPropertyDescriptor(t,r);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),s=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||n(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.sdk=t.MixinDeviceBase=t.ScryptedDeviceBase=void 0,s(r(9849),t);const i=r(9849);r(3339);class o extends i.DeviceBase{constructor(e){super(),this.nativeId=e}get storage(){return this._storage||(this._storage=t.sdk.deviceManager.getDeviceStorage(this.nativeId)),this._storage}get log(){return this._log||(this._log=t.sdk.deviceManager.getDeviceLogger(this.nativeId)),this._log}get console(){return this._console||(this._console=t.sdk.deviceManager.getDeviceConsole(this.nativeId)),this._console}async createMediaObject(e,r){return t.sdk.mediaManager.createMediaObject(e,r,{sourceId:this.id})}getMediaObjectConsole(e){return"string"!=typeof e.sourceId?this.console:t.sdk.deviceManager.getMixinConsole(e.sou