@scrypted/prebuffer-mixin 0.1.81 → 0.1.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.nodejs.js +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/main.ts +35 -11
package/dist/main.nodejs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(()=>{var e={454:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AutoenableMixinProvider=void 0;var i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=n(t);if(r&&r.has(e))return r.get(e);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&Object.prototype.hasOwnProperty.call(e,s)){var a=o?Object.getOwnPropertyDescriptor(e,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=e[s]}i.default=e,r&&r.set(e,i);return i}(r(510));function n(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(n=function(e){return e?r:t})(e)}const{systemManager:o}=i.default,s="v4";class AutoenableMixinProvider extends i.ScryptedDeviceBase{constructor(e){var t,r,n;super(e),n={},(r="hasEnabledMixin")in(t=this)?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n;try{this.hasEnabledMixin=JSON.parse(this.storage.getItem("hasEnabledMixin"))}catch(e){this.hasEnabledMixin={}}this.pluginsComponent=o.getComponent("plugins"),o.listen((async(e,t,r)=>{t.eventInterface!==i.ScryptedInterface.ScryptedDevice||t.property||this.maybeEnableMixin(e)}));for(const e of Object.keys(o.getSystemState())){const t=o.getDeviceById(e);this.maybeEnableMixin(t)}}async maybeEnableMixin(e){var t;if(!e||null!==(t=e.mixins)&&void 0!==t&&t.includes(this.id))return;if(this.hasEnabledMixin[e.id]===s)return;if(!await this.canMixin(e.type,e.interfaces))return;this.log.i("auto enabling mixin for "+e.name);const r=(e.mixins||[]).slice();r.push(this.id);const i=await this.pluginsComponent;await i.setMixins(e.id,r),this.setHasEnabledMixin(e.id)}setHasEnabledMixin(e){this.hasEnabledMixin[e]!==s&&(this.hasEnabledMixin[e]=s,this.storage.setItem("hasEnabledMixin",JSON.stringify(this.hasEnabledMixin)))}}t.AutoenableMixinProvider=AutoenableMixinProvider},201:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createRebroadcaster=h,t.parseAudioCodec=f,t.parseResolution=l,t.parseVideoCodec=m,t.startRebroadcastSession=async function(e,t){let r,a=0,c=!0;const p=new s.EventEmitter,{console:g}=t;let v,y,S;function b(){c&&(p.emit("killed"),p.emit("error",new Error("killed"))),c=!1,null==D||D.kill();for(const e of x)null==e||e.close()}function M(){t.timeout&&(clearTimeout(r),r=setTimeout(b,t.timeout))}M();const P={},O=e.inputArguments.slice(),x=[];let I;const w=new Promise((e=>I=e));for(const n of Object.keys(t.parsers)){const s=t.parsers[n],d=n+"-data";if(P[n]={mediaStreamOptions:e.mediaStreamOptions},!t.parseOnly){const{server:t,port:i}=await h({connect:(e,t)=>{a++,clearTimeout(r);const i=()=>{p.removeListener(d,e),p.removeListener("killed",t),a--,0===a&&M(),t()};return p.on(d,e),p.once("killed",i),i}});x.push(t),e.inputArguments=["-f",n,"-i",`tcp://127.0.0.1:${i}`]}const c=(0,i.createServer)((async e=>{c.close(),I(e);try{const i=n+"-data";for await(const n of s.parse(e,parseInt(null===(t=S)||void 0===t?void 0:t[2]),parseInt(null===(r=S)||void 0===r?void 0:r[3]))){var t,r;p.emit(i,n)}}catch(e){g.error("rebroadcast parse error",e),b()}}));x.push(c);const u=await(0,o.listenZeroCluster)(c);O.push(...s.outputArguments,`tcp://127.0.0.1:${u}`)}O.unshift("-hide_banner"),g.log(O);const D=n.default.spawn(await u.getFFmpegPath(),O);return(0,d.ffmpegLogInitialOutput)(g,D),D.on("exit",b),f(D).then((e=>v=e)),m(D).then((e=>y=e)),l(D).then((e=>S=e)),await w,{inputAudioCodec:v,inputVideoCodec:y,inputVideoResolution:S,events:p,resetActivityTimer:M,isActive:()=>c,kill:b,servers:x,cp:D,ffmpegInputs:P}};var i=r(808),n=c(r(81)),o=r(769),s=r(361),a=c(r(510)),d=r(833);function c(e){return e&&e.__esModule?e:{default:e}}const{mediaManager:u}=a.default;async function l(e){return new Promise((t=>{const r=i=>{const n=i.toString(),o=/(([0-9]{2,5})x([0-9]{2,5}))/.exec(n);o&&(e.stdout.removeListener("data",r),e.stderr.removeListener("data",r),t(o))};e.stdout.on("data",r),e.stderr.on("data",r)}))}async function p(e,t){return new Promise((r=>{const i=n=>{const o=n.toString(),s=o.indexOf(`${t}: `);if(-1!==s){const n=o.substring(s+t.length+1).trim();let a=n.indexOf(" ");const d=n.indexOf(",");-1!==a&&d<a&&(a=d),-1!==a&&(e.stdout.removeListener("data",i),e.stderr.removeListener("data",i),r(n.substring(0,a)))}};e.stdout.on("data",i),e.stderr.on("data",i)}))}async function m(e){return p(e,"Video")}async function f(e){return p(e,"Audio")}async function h(e){const t=(0,i.createServer)((t=>{let r=!0;const i=()=>{t.removeAllListeners(),t.destroy();const e=n;n=void 0,null==e||e()};let n=null==e?void 0:e.connect((e=>{r&&(r=!1,e.startStream&&t.write(e.startStream));for(const r of e.chunks)t.write(r);return t.writableLength}),i);t.on("end",i),t.on("close",i),t.on("error",i)}));return{server:t,port:await(0,o.listenZeroCluster)(t)}}},769:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.listenZeroCluster=async function(e){for(;;){const t=1e4+Math.round(3e4*Math.random());e.listen(t);try{return await(0,i.once)(e,"listening"),e.address().port}catch(e){}}};var i=r(361)},833:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=r(568);Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===i[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}))},701:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.readLength=async function(e,t){if(!t)return Buffer.alloc(0);{const r=e.read(t);if(r)return r}return new Promise(((r,i)=>{const n=()=>{const i=e.read(t);i&&(s(),r(i))},o=()=>{s(),i(new Error(`stream ended during read for minimum ${t} bytes`))},s=()=>{e.removeListener("readable",n),e.removeListener("end",o)};e.on("readable",n),e.on("end",o)}))}},567:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SettingsMixinDeviceBase=void 0;var i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=n(t);if(r&&r.has(e))return r.get(e);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&Object.prototype.hasOwnProperty.call(e,s)){var a=o?Object.getOwnPropertyDescriptor(e,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=e[s]}i.default=e,r&&r.set(e,i);return i}(r(510));function n(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(n=function(e){return e?r:t})(e)}const{deviceManager:o}=i.default;class SettingsMixinDeviceBase extends i.MixinDeviceBase{constructor(e,t,r){super(e,r.mixinDeviceInterfaces,t,r.providerNativeId),this.settingsGroup=r.group,this.settingsGroupKey=r.groupKey}async getSettings(){const e=this.mixinDeviceInterfaces.includes(i.ScryptedInterface.Settings)?this.mixinDevice.getSettings():void 0,t=await this.getMixinSettings();for(const e of t)e.group=e.group||this.settingsGroup,e.key=this.settingsGroupKey+":"+e.key;const r=await e||[];return r.push(...t),r}async putSetting(e,t){var r;const n=this.settingsGroupKey+":";if(null==e||!e.startsWith(n))return this.mixinDevice.putSetting(e,t);await this.putMixinSetting(e.substring(n.length),t),null===(r=o.onMixinEvent)||void 0===r||r.call(o,this.id,this.mixinProviderNativeId,i.ScryptedInterface.Settings,null)}}t.SettingsMixinDeviceBase=SettingsMixinDeviceBase},129:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PIXEL_FORMAT_YUV420P=t.PIXEL_FORMAT_RGB24=void 0,t.createFragmentedMp4Parser=function(e){return{container:"mp4",outputArguments:[...(null==e?void 0:e.vcodec)||[],...(null==e?void 0:e.acodec)||[],"-movflags","frag_keyframe+empty_moov+default_base_moof","-f","mp4"],async*parse(e){const t=a(e);let r,i,n;for await(const e of t)r?i||(i=e):r=e,yield{startStream:n,chunks:[e.header,e.data],type:e.type},r&&i&&!n&&(n=Buffer.concat([r.header,r.data,i.header,i.data]))},findSyncFrame:o}},t.createMpegTsParser=function(e){return{container:"mpegts",outputArguments:[...(null==e?void 0:e.vcodec)||[],...(null==e?void 0:e.acodec)||[],"-f","mpegts"],parse:s(188,(e=>{if(71!=e[0])throw new Error("Invalid sync byte in mpeg-ts packet. Terminating stream.")})),findSyncFrame(e){for(let t=0;t<e.length;t++){const r=e[t];for(let i=0;i<r.chunks.length;i++){const n=r.chunks[i];let o=0;for(;o+188<n.length;){const r=n.subarray(o,o+188);if(256==((31&r[1])<<8|r[2])&&32&r[3]&&r[4]>0&&64&r[5])return e.slice(t);o+=188}}}return e}}},t.createPCMParser=function(){return{container:"s16le",outputArguments:["-vn","-acodec","pcm_s16le","-f","s16le"],parse:s(512),findSyncFrame:o}},t.createRawVideoParser=function(e){var t;const r=(null===(t=e)||void 0===t?void 0:t.pixelFormat)||d;let i;e=e||{};const{size:s,everyNFrames:a}=e;s&&(i=`scale=${s.width}:${s.height}`);a&&a>1&&(i?i+=",":i="",i+=`select=not(mod(n\\,${a}))`);return{container:"rawvideo",outputArguments:[...i?["-vf",i]:[],"-an","-vcodec","rawvideo","-pix_fmt",r.name,"-f","rawvideo"],async*parse(e,t,i){if(!t||!i)throw new Error("error parsing rawvideo, unknown width and height");t=(null==s?void 0:s.width)||t,i=(null==s?void 0:s.height)||i;const o=r.computeLength(t,i);for(;;){const r=await(0,n.readLength)(e,o);yield{chunks:[r],width:t,height:i}}},findSyncFrame:o}},t.parseFragmentedMP4=a;var i=r(361),n=r(701);function o(e){return e}function s(e,t){return async function*(r){let n=[],o=0;for(;;){const s=r.read();if(!s){await(0,i.once)(r,"readable");continue}if(n.push(s),o+=s.length,o<e)continue;const a=Buffer.concat(n);null==t||t(a);const d=a.length%e,c=a.slice(0,a.length-d),u=a.slice(a.length-d);n=[u],o=u.length,yield{chunks:[c]}}}}async function*a(e){for(;;){const t=await(0,n.readLength)(e,8),r=t.readInt32BE(0)-8,i=t.slice(4).toString(),o=await(0,n.readLength)(e,r);yield{header:t,length:r,type:i,data:o}}}const d={name:"yuv420p",computeLength:(e,t)=>e*t*1.5};t.PIXEL_FORMAT_YUV420P=d;t.PIXEL_FORMAT_RGB24={name:"rgb24",computeLength:(e,t)=>e*t*3}},510:(e,t,r)=>{"use strict";var i=Object.create?function(e,t,r,i){void 0===i&&(i=r),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]},n=function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||i(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.MixinDeviceBase=t.ScryptedDeviceBase=void 0,n(r(393),t);const o=r(393);class ScryptedDeviceBase extends o.DeviceBase{constructor(e){super(),this.nativeId=e}get storage(){return this._storage||(this._storage=deviceManager.getDeviceStorage(this.nativeId)),this._storage}get log(){return this._log||(this._log=deviceManager.getDeviceLogger(this.nativeId)),this._log}get console(){return this._console||(this._console=deviceManager.getDeviceConsole(this.nativeId)),this._console}_lazyLoadDeviceState(){this._deviceState||(this.nativeId?this._deviceState=deviceManager.getDeviceState(this.nativeId):this._deviceState=deviceManager.getDeviceState())}onDeviceEvent(e,t){return deviceManager.onDeviceEvent(this.nativeId,e,t)}}t.ScryptedDeviceBase=ScryptedDeviceBase;class MixinDeviceBase extends o.DeviceBase{constructor(e,t,r,i){super(),this.mixinDevice=e,this.mixinDeviceInterfaces=t,this.mixinProviderNativeId=i,this._deviceState=r}get storage(){return this._storage||(this._storage=deviceManager.getMixinStorage(this.id,this.mixinProviderNativeId)),this._storage}get console(){return this._console||(deviceManager.getMixinConsole?this._console=deviceManager.getMixinConsole(this.id,this.mixinProviderNativeId):this._console=deviceManager.getDeviceConsole(this.mixinProviderNativeId)),this._console}onDeviceEvent(e,t){return deviceManager.onMixinEvent(this.id,this.mixinProviderNativeId,e,t)}_lazyLoadDeviceState(){}release(){}}t.MixinDeviceBase=MixinDeviceBase,function(){function e(e){return function(){return this._lazyLoadDeviceState(),this._deviceState[e]}}function t(e){return function(t){this._lazyLoadDeviceState(),this._deviceState[e]=t}}for(var r of Object.values(o.ScryptedInterfaceProperty))Object.defineProperty(ScryptedDeviceBase.prototype,r,{set:t(r),get:e(r)}),Object.defineProperty(MixinDeviceBase.prototype,r,{set:t(r),get:e(r)})}();let s={};try{s=Object.assign(s,{log:deviceManager.getDeviceLogger(void 0),deviceManager,endpointManager,mediaManager,systemManager,pluginHostAPI})}catch(e){console.error("sdk initialization error, import @scrypted/sdk/types instead",e)}t.default=s},393:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ThermostatMode=t.TemperatureUnit=t.ScryptedMimeTypes=t.ScryptedInterfaceProperty=t.ScryptedInterfaceDescriptors=t.ScryptedInterface=t.ScryptedDeviceType=t.SCRYPTED_MEDIA_SCHEME=t.MediaPlayerState=t.LockState=t.HumidityMode=t.FanMode=t.DeviceBase=void 0;let r;t.DeviceBase=class DeviceBase{},t.ScryptedInterfaceProperty=r,function(e){e.id="id",e.info="info",e.interfaces="interfaces",e.mixins="mixins",e.name="name",e.providedInterfaces="providedInterfaces",e.providedName="providedName",e.providedRoom="providedRoom",e.providedType="providedType",e.providerId="providerId",e.room="room",e.type="type",e.on="on",e.brightness="brightness",e.colorTemperature="colorTemperature",e.rgb="rgb",e.hsv="hsv",e.running="running",e.paused="paused",e.docked="docked",e.thermostatActiveMode="thermostatActiveMode",e.thermostatAvailableModes="thermostatAvailableModes",e.thermostatMode="thermostatMode",e.thermostatSetpoint="thermostatSetpoint",e.thermostatSetpointHigh="thermostatSetpointHigh",e.thermostatSetpointLow="thermostatSetpointLow",e.temperature="temperature",e.temperatureUnit="temperatureUnit",e.humidity="humidity",e.lockState="lockState",e.entryOpen="entryOpen",e.batteryLevel="batteryLevel",e.online="online",e.updateAvailable="updateAvailable",e.fromMimeType="fromMimeType",e.toMimeType="toMimeType",e.binaryState="binaryState",e.intrusionDetected="intrusionDetected",e.powerDetected="powerDetected",e.audioDetected="audioDetected",e.motionDetected="motionDetected",e.occupied="occupied",e.flooded="flooded",e.ultraviolet="ultraviolet",e.luminance="luminance",e.position="position",e.humiditySetting="humiditySetting",e.fan="fan"}(r||(t.ScryptedInterfaceProperty=r={}));let i,n,o,s,a,d,c,u,l;t.ScryptedInterfaceDescriptors={ScryptedDevice:{name:"ScryptedDevice",methods:["listen","setName","setRoom","setType"],properties:["id","info","interfaces","mixins","name","providedInterfaces","providedName","providedRoom","providedType","providerId","room","type"]},OnOff:{name:"OnOff",methods:["turnOff","turnOn"],properties:["on"]},Brightness:{name:"Brightness",methods:["setBrightness"],properties:["brightness"]},ColorSettingTemperature:{name:"ColorSettingTemperature",methods:["getTemperatureMaxK","getTemperatureMinK","setColorTemperature"],properties:["colorTemperature"]},ColorSettingRgb:{name:"ColorSettingRgb",methods:["setRgb"],properties:["rgb"]},ColorSettingHsv:{name:"ColorSettingHsv",methods:["setHsv"],properties:["hsv"]},Notifier:{name:"Notifier",methods:["sendNotification"],properties:[]},StartStop:{name:"StartStop",methods:["start","stop"],properties:["running"]},Pause:{name:"Pause",methods:["pause","resume"],properties:["paused"]},Dock:{name:"Dock",methods:["dock"],properties:["docked"]},TemperatureSetting:{name:"TemperatureSetting",methods:["setThermostatMode","setThermostatSetpoint","setThermostatSetpointHigh","setThermostatSetpointLow"],properties:["thermostatActiveMode","thermostatAvailableModes","thermostatMode","thermostatSetpoint","thermostatSetpointHigh","thermostatSetpointLow"]},Thermometer:{name:"Thermometer",methods:[],properties:["temperature","temperatureUnit"]},HumiditySensor:{name:"HumiditySensor",methods:[],properties:["humidity"]},Camera:{name:"Camera",methods:["getPictureOptions","takePicture"],properties:[]},VideoCamera:{name:"VideoCamera",methods:["getVideoStream","getVideoStreamOptions"],properties:[]},Intercom:{name:"Intercom",methods:["startIntercom","stopIntercom"],properties:[]},Lock:{name:"Lock",methods:["lock","unlock"],properties:["lockState"]},PasswordStore:{name:"PasswordStore",methods:["addPassword","getPasswords","removePassword"],properties:[]},Authenticator:{name:"Authenticator",methods:["checkPassword"],properties:[]},Scene:{name:"Scene",methods:["activate","deactivate","isReversible"],properties:[]},Entry:{name:"Entry",methods:["closeEntry","openEntry"],properties:[]},EntrySensor:{name:"EntrySensor",methods:[],properties:["entryOpen"]},DeviceProvider:{name:"DeviceProvider",methods:["discoverDevices","getDevice"],properties:[]},Battery:{name:"Battery",methods:[],properties:["batteryLevel"]},Refresh:{name:"Refresh",methods:["getRefreshFrequency","refresh"],properties:[]},MediaPlayer:{name:"MediaPlayer",methods:["getMediaStatus","load","seek","skipNext","skipPrevious"],properties:[]},Online:{name:"Online",methods:[],properties:["online"]},SoftwareUpdate:{name:"SoftwareUpdate",methods:["checkForUpdate","installUpdate"],properties:["updateAvailable"]},BufferConverter:{name:"BufferConverter",methods:["convert"],properties:["fromMimeType","toMimeType"]},Settings:{name:"Settings",methods:["getSettings","putSetting"],properties:[]},BinarySensor:{name:"BinarySensor",methods:[],properties:["binaryState"]},IntrusionSensor:{name:"IntrusionSensor",methods:[],properties:["intrusionDetected"]},PowerSensor:{name:"PowerSensor",methods:[],properties:["powerDetected"]},AudioSensor:{name:"AudioSensor",methods:[],properties:["audioDetected"]},MotionSensor:{name:"MotionSensor",methods:[],properties:["motionDetected"]},OccupancySensor:{name:"OccupancySensor",methods:[],properties:["occupied"]},FloodSensor:{name:"FloodSensor",methods:[],properties:["flooded"]},UltravioletSensor:{name:"UltravioletSensor",methods:[],properties:["ultraviolet"]},LuminanceSensor:{name:"LuminanceSensor",methods:[],properties:["luminance"]},PositionSensor:{name:"PositionSensor",methods:[],properties:["position"]},MediaSource:{name:"MediaSource",methods:["getMedia"],properties:[]},OauthClient:{name:"OauthClient",methods:["getOauthUrl","onOauthCallback"],properties:[]},MixinProvider:{name:"MixinProvider",methods:["canMixin","getMixin","releaseMixin"],properties:[]},HttpRequestHandler:{name:"HttpRequestHandler",methods:["onRequest"],properties:[]},EngineIOHandler:{name:"EngineIOHandler",methods:["onConnection"],properties:[]},PushHandler:{name:"PushHandler",methods:["onPush"],properties:[]},Program:{name:"Program",methods:["run"],properties:[]},Scriptable:{name:"Scriptable",methods:["eval","loadScripts","saveScript"],properties:[]},ObjectDetector:{name:"ObjectDetector",methods:["getDetectionInput","getObjectTypes"],properties:[]},HumiditySetting:{name:"HumiditySetting",methods:["setHumidity"],properties:["humiditySetting"]},Fan:{name:"Fan",methods:["setFan"],properties:["fan"]}},t.ScryptedDeviceType=i,function(e){e.Builtin="Builtin",e.Camera="Camera",e.Fan="Fan",e.Light="Light",e.Switch="Switch",e.Outlet="Outlet",e.Sensor="Sensor",e.Scene="Scene",e.Program="Program",e.Automation="Automation",e.Vacuum="Vacuum",e.Notifier="Notifier",e.Thermostat="Thermostat",e.Lock="Lock",e.PasswordControl="PasswordControl",e.Display="Display",e.Speaker="Speaker",e.Event="Event",e.Entry="Entry",e.Garage="Garage",e.DeviceProvider="DeviceProvider",e.DataSource="DataSource",e.API="API",e.Doorbell="Doorbell",e.Irrigation="Irrigation",e.Valve="Valve",e.Person="Person",e.Unknown="Unknown"}(i||(t.ScryptedDeviceType=i={})),t.HumidityMode=n,function(e){e.Humidify="Humidify",e.Dehumidify="Dehumidify",e.Auto="Auto",e.Off="Off"}(n||(t.HumidityMode=n={})),t.FanMode=o,function(e){e.Auto="Auto",e.Manual="Manual"}(o||(t.FanMode=o={})),t.TemperatureUnit=s,function(e){e.C="C",e.F="F"}(s||(t.TemperatureUnit=s={})),t.ThermostatMode=a,function(e){e.Off="Off",e.Cool="Cool",e.Heat="Heat",e.HeatCool="HeatCool",e.Auto="Auto",e.FanOnly="FanOnly",e.Purifier="Purifier",e.Eco="Eco",e.Dry="Dry",e.On="On"}(a||(t.ThermostatMode=a={})),t.LockState=d,function(e){e.Locked="Locked",e.Unlocked="Unlocked",e.Jammed="Jammed"}(d||(t.LockState=d={})),t.MediaPlayerState=c,function(e){e.Idle="Idle",e.Playing="Playing",e.Paused="Paused",e.Buffering="Buffering"}(c||(t.MediaPlayerState=c={})),t.ScryptedInterface=u,function(e){e.ScryptedDevice="ScryptedDevice",e.OnOff="OnOff",e.Brightness="Brightness",e.ColorSettingTemperature="ColorSettingTemperature",e.ColorSettingRgb="ColorSettingRgb",e.ColorSettingHsv="ColorSettingHsv",e.Notifier="Notifier",e.StartStop="StartStop",e.Pause="Pause",e.Dock="Dock",e.TemperatureSetting="TemperatureSetting",e.Thermometer="Thermometer",e.HumiditySensor="HumiditySensor",e.Camera="Camera",e.VideoCamera="VideoCamera",e.Intercom="Intercom",e.Lock="Lock",e.PasswordStore="PasswordStore",e.Authenticator="Authenticator",e.Scene="Scene",e.Entry="Entry",e.EntrySensor="EntrySensor",e.DeviceProvider="DeviceProvider",e.Battery="Battery",e.Refresh="Refresh",e.MediaPlayer="MediaPlayer",e.Online="Online",e.SoftwareUpdate="SoftwareUpdate",e.BufferConverter="BufferConverter",e.Settings="Settings",e.BinarySensor="BinarySensor",e.IntrusionSensor="IntrusionSensor",e.PowerSensor="PowerSensor",e.AudioSensor="AudioSensor",e.MotionSensor="MotionSensor",e.OccupancySensor="OccupancySensor",e.FloodSensor="FloodSensor",e.UltravioletSensor="UltravioletSensor",e.LuminanceSensor="LuminanceSensor",e.PositionSensor="PositionSensor",e.MediaSource="MediaSource",e.OauthClient="OauthClient",e.MixinProvider="MixinProvider",e.HttpRequestHandler="HttpRequestHandler",e.EngineIOHandler="EngineIOHandler",e.PushHandler="PushHandler",e.Program="Program",e.Scriptable="Scriptable",e.ObjectDetector="ObjectDetector",e.HumiditySetting="HumiditySetting",e.Fan="Fan"}(u||(t.ScryptedInterface=u={})),t.ScryptedMimeTypes=l,function(e){e.AcceptUrlParameter="accept-url",e.Url="text/x-uri",e.InsecureLocalUrl="text/x-insecure-local-uri",e.LocalUrl="text/x-local-uri",e.PushEndpoint="text/x-push-endpoint",e.MediaStreamUrl="text/x-media-url",e.FFmpegInput="x-scrypted/x-ffmpeg-input",e.RTCAVOffer="x-scrypted/x-rtc-av-offer",e.RTCAVAnswer="x-scrypted/x-rtc-av-answer"}(l||(t.ScryptedMimeTypes=l={}));t.SCRYPTED_MEDIA_SCHEME="scryped-media://"},568:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ffmpegLogInitialOutput=function(e,t,i){var n,o;function s(e){const n=o=>{const s=o.toString();for(const e of r)if(-1!==s.indexOf(e))return;if(!i&&(-1!==s.indexOf("frame=")||-1!==s.indexOf("size=")))return e(s),e("video/audio detected, discarding further input"),t.stdout.removeListener("data",n),void t.stderr.removeListener("data",n);e(s)};return n}null===(n=t.stdout)||void 0===n||n.on("data",s(e.log)),null===(o=t.stderr)||void 0===o||o.on("data",s(e.error)),t.on("exit",(()=>e.log("ffmpeg exited")))},t.probeVideoCamera=async function(e){let t;try{t=await e.getVideoStreamOptions()||[]}catch(e){}const r=t&&t.length&&null===t[0].audio;return{options:t,noAudio:r}};const r=["decode_slice_header error","no frame!","non-existing PPS"]},81:e=>{"use strict";e.exports=require("child_process")},361:e=>{"use strict";e.exports=require("events")},808:e=>{"use strict";e.exports=require("net")}},t={};function r(i){var n=t[i];if(void 0!==n)return n.exports;var o=t[i]={exports:{}};return e[i](o,o.exports,r),o.exports}var i={};(()=>{"use strict";var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t=l(r(510)),n=l(r(361)),o=r(567),s=r(201),a=r(833),d=r(129),c=r(454);function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(u=function(e){return e?r:t})(e)}function l(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=u(t);if(r&&r.has(e))return r.get(e);var i={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var s=n?Object.getOwnPropertyDescriptor(e,o):null;s&&(s.get||s.set)?Object.defineProperty(i,o,s):i[o]=e[o]}return i.default=e,r&&r.set(e,i),i}function p(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const{mediaManager:m,log:f,systemManager:h,deviceManager:g}=t.default,v=1e4,y="prebufferDuration",S="sendKeyframe",b="MPEG-TS/MP4 Compatible or No Audio (Copy)",M="Other Audio",P="PCM Audio",O=["aac","mp3","mp2","",void 0,null];class PrebufferSession{constructor(e,t,r){p(this,"prebuffers",{mp4:[],mpegts:[],s16le:[]}),p(this,"events",new n.default),p(this,"detectedIdrInterval",0),p(this,"prevIdr",0),p(this,"incompatibleDetected",!1),p(this,"allowImmediateRestart",!1),p(this,"AUDIO_CONFIGURATION","audioConfiguration-"+this.streamId),this.mixin=e,this.streamName=t,this.streamId=r,this.storage=e.storage,this.console=e.console,this.mixinDevice=e.mixinDevice}ensurePrebufferSession(){this.parserSessionPromise||this.mixin.released||(this.console.log("prebuffer session started",this.streamId),this.parserSessionPromise=this.startPrebufferSession(),this.parserSessionPromise.catch((()=>this.parserSessionPromise=void 0)))}getAudioConfig(){const e=this.storage.getItem(this.AUDIO_CONFIGURATION)||"",t=-1!==e.indexOf(P),r=-1!==e.indexOf(M)||!t&&this.incompatibleDetected;return{audioConfig:e,pcmAudio:t,reencodeAudio:r}}async getMixinSettings(){var e,t,r;const i=[],n=this.parserSession;let o=0,s=0;for(const e of this.prebuffers.mp4){s=s||e.time;for(const t of e.chunk.chunks)o+=t.byteLength}const a=Date.now()-s,d=Math.round(o/a*8),c=this.streamName?`Rebroadcast: ${this.streamName}`:"Rebroadcast";return i.push({title:"Audio Codec Transcoding",group:c,description:"Configuring your camera to output AAC, MP3, or MP2 is recommended. PCM/G711 cameras should set this to Reencode.",type:"string",key:this.AUDIO_CONFIGURATION,value:this.storage.getItem(this.AUDIO_CONFIGURATION)||b,choices:[b,"Other Audio (Transcode)","PCM Audio (Copy, !Experimental!)"]},{key:"detectedResolution",group:c,title:"Detected Resolution and Bitrate",readonly:!0,value:`${(null==n||null===(e=n.inputVideoResolution)||void 0===e?void 0:e[0])||"unknown"} @ ${d||"unknown"} Kb/s`,description:"Configuring your camera to 1920x1080, 2000Kb/S, Variable Bit Rate, is recommended."},{key:"detectedCodec",group:c,title:"Detected Video/Audio Codecs",readonly:!0,value:((null==n||null===(t=n.inputVideoCodec)||void 0===t?void 0:t.toString())||"unknown")+"/"+((null==n||null===(r=n.inputAudioCodec)||void 0===r?void 0:r.toString())||"unknown"),description:"Configuring your camera to H264 video and AAC/MP3/MP2 audio is recommended."},{key:"detectedKeyframe",group:c,title:"Detected Keyframe Interval",description:"Configuring your camera to 4 seconds is recommended (IDR aka Frame Interval = FPS * 4 seconds).",readonly:!0,value:((this.detectedIdrInterval||0)/1e3).toString()||"none"}),i}async startPrebufferSession(){var e,r,i;this.prebuffers.mp4=[],this.prebuffers.mpegts=[],this.prebuffers.s16le=[];const n=parseInt(this.storage.getItem(y))||v,o=await(0,a.probeVideoCamera)(this.mixinDevice);let c;o.options&&(c=o.options.find((e=>e.id===this.streamId)));const u=null==o||null===(e=o.options)||void 0===e||null===(r=e[0])||void 0===r||null===(i=r.audio)||void 0===i?void 0:i.codec;this.incompatibleDetected=this.incompatibleDetected||u&&!O.includes(u),this.incompatibleDetected&&this.console.warn("configure your camera to output aac, mp3, or mp2 audio. incompatibl audio codec detected",u);const l=await this.mixinDevice.getVideoStream(c),p=await m.convertMediaObjectToBuffer(l,t.ScryptedMimeTypes.FFmpegInput),h=JSON.parse(p.toString()),{audioConfig:g,pcmAudio:S,reencodeAudio:b}=this.getAudioConfig();let M;M=o.noAudio||S?["-an"]:b?["-bsf:a","aac_adtstoasc","-acodec","libfdk_aac","-profile:a","aac_low"]:["-acodec","copy"];const P=["-vcodec","copy"],x={console:this.console,parsers:{mp4:(0,d.createFragmentedMp4Parser)({vcodec:P,acodec:M}),mpegts:(0,d.createMpegTsParser)({vcodec:P,acodec:M})},parseOnly:!0};!o.noAudio&&S&&(x.parsers.s16le=(0,d.createPCMParser)()),this.parsers=x.parsers;const I=await(0,s.startRebroadcastSession)(h,x);let w;this.parserSession=I;const D=()=>{clearTimeout(w),w=setTimeout((()=>{this.console.error("watchdog for mp4 parser timed out... killing ffmpeg session"),I.kill()}),6e4)};I.events.on("mp4-data",D),I.events.once("killed",(()=>{this.parserSessionPromise=void 0,I.events.removeListener("mp4-data",D),clearTimeout(w)})),D(),I.inputAudioCodec?O.includes(I.inputAudioCodec)||(this.console.error("Detected audio codec was not AAC.",I.inputAudioCodec),g||o.noAudio||(f.a(`${this.mixin.name} is using ${I.inputAudioCodec} audio. Enable Reencode Audio in Rebroadcast Settings Audio Configuration to disable this alert.`),this.incompatibleDetected=!0,this.allowImmediateRestart=!0)):this.console.warn("no audio detected."),"h264"!==I.inputVideoCodec&&this.console.error("video codec is not h264. If there are errors, try changing your camera's encoder output.");for(const e of["mpegts","mp4","s16le"]){const t=e+"-data";let r=this.prebuffers[e],i=0;I.events.on(t,(o=>{const s=Date.now();for("mdat"===o.type&&(this.prevIdr&&(this.detectedIdrInterval=s-this.prevIdr),this.prevIdr=s),r.push({time:s,chunk:o});r.length&&r[0].time<s-n;)r.shift(),i++;i>1e3&&(r=this.prebuffers[e]=r.slice(),i=0),this.events.emit(t,o)}))}return I}async getVideoStream(e){var t,r;this.ensurePrebufferSession();const i=await this.parserSessionPromise,n="false"!==this.storage.getItem(S),o=(null==e?void 0:e.prebuffer)||(n?1.5*Math.max(4e3,this.detectedIdrInterval||4e3):0);if(!(null!=e&&e.prebuffer||n)){return m.createFFmpegMediaObject(i.ffmpegInputs.mpegts)}this.console.log("prebuffer request started",this.streamId);const a=async e=>{const t=e+"-data",r=this.prebuffers[e],{server:n,port:a}=await(0,s.createRebroadcaster)({connect:(e,s)=>{n.close();const a=Date.now(),d=t=>{e(t)>1e8&&(this.console.log("more than 100MB has been buffered, did downstream die? killing connection."),c())},c=()=>{s(),this.console.log("prebuffer request ended"),this.events.removeListener(t,d),i.events.removeListener("killed",c)};this.events.on(t,d),i.events.once("killed",c);for(const e of r)e.time<a-o||d(e.chunk);return c}});return setTimeout((()=>n.close()),3e4),a},d=(null==e?void 0:e.container)||"mpegts",c=i.ffmpegInputs[d].mediaStreamOptions?Object.assign({},i.ffmpegInputs[d].mediaStreamOptions):{};c.prebuffer=o;const{audioConfig:u,pcmAudio:l,reencodeAudio:p}=this.getAudioConfig();c.audio=p?{codec:"aac"}:{codec:null==i?void 0:i.inputAudioCodec},c.video&&null!==(t=i.inputVideoResolution)&&void 0!==t&&t[2]&&null!==(r=i.inputVideoResolution)&&void 0!==r&&r[3]&&Object.assign(c.video,{width:parseInt(i.inputVideoResolution[2]),height:parseInt(i.inputVideoResolution[3])});const f={inputArguments:["-f",d,"-i",`tcp://127.0.0.1:${await a(d)}`],mediaStreamOptions:c};l&&f.inputArguments.push("-f","s16le","-i",`tcp://127.0.0.1:${await a("s16le")}`),this.console.log("prebuffer ffmpeg input",f);return m.createFFmpegMediaObject(f)}}class PrebufferMixin extends o.SettingsMixinDeviceBase{constructor(e,t,r,i){super(e,r,{providerNativeId:i,mixinDeviceInterfaces:t,group:"Prebuffer Settings",groupKey:"prebuffer"}),p(this,"released",!1),p(this,"sessions",new Map),this.delayStart()}delayStart(){this.console.log("prebuffer sessions starting in 5 seconds"),setTimeout((()=>this.ensurePrebufferSessions()),5e3)}async getVideoStream(e){await this.ensurePrebufferSessions();let r=null==e?void 0:e.id;if(!r&&!this.sessions.has(r)){var i;const n=await this.mixinDevice.getVideoStream(e),o=JSON.parse((await m.convertMediaObjectToBuffer(n,t.ScryptedMimeTypes.FFmpegInput)).toString());r=null==o||null===(i=o.mediaStreamOptions)||void 0===i?void 0:i.id,this.sessions.set(null==e?void 0:e.id,this.sessions.get(r))}let n=this.sessions.get(r);return n?(n.ensurePrebufferSession(),await n.parserSessionPromise,n=this.sessions.get(r),n?n.getVideoStream(e):this.mixinDevice.getVideoStream(e)):this.mixinDevice.getVideoStream(e)}async ensurePrebufferSessions(){const e=await this.mixinDevice.getVideoStreamOptions(),r=this.getEnabledMediaStreamOptions(e),i=r?r.map((e=>e.id)):[void 0];for(const t of i){let r=this.sessions.get(t);if(!r){const i=null==e?void 0:e.find((e=>e.id===t));null!=i&&i.prebuffer&&f.a(`Prebuffer is already available on ${this.name}. If this is a grouped device, disable the Rebroadcast extension.`);const o=null==i?void 0:i.name;r=new PrebufferSession(this,o,t),this.sessions.set(t,r),(async()=>{for(;this.sessions.get(t)===r&&!this.released;){this.console.log("monitoring prebuffer session"),r.ensurePrebufferSession();try{const e=await r.parserSessionPromise;await(0,n.once)(e.events,"killed"),this.console.error("prebuffer session ended")}catch(e){this.console.error("prebuffer session ended with error",e)}this.console.log("restarting prebuffer session in 5 seconds"),await new Promise((e=>setTimeout(e,5e3)))}this.console.log("exiting prebuffer session (released or restarted with new configuration)")})()}}g.onMixinEvent(this.id,this.mixinProviderNativeId,t.ScryptedInterface.Settings,void 0)}async getMixinSettings(){const e=[],t=await this.mixinDevice.getVideoStreamOptions(),r=this.getEnabledMediaStreamOptions(t);r&&(null==t?void 0:t.length)>1&&e.push({title:"Prebuffered Streams",description:"The streams to prebuffer. Enable only as necessary to reduce traffic.",key:"enabledStreams",value:r.map((e=>e.name||"")),choices:t.map((e=>e.name)),multiple:!0}),e.push({title:"Prebuffer Duration",description:"Duration of the prebuffer in milliseconds.",type:"number",key:y,value:this.storage.getItem(y)||v.toString()},{title:"Start at Previous Keyframe",description:"Start live streams from the previous key frame. Improves startup time.",type:"boolean",key:S,value:("false"!==this.storage.getItem(S)).toString()});for(const t of new Set([...this.sessions.values()]))e.push(...await t.getMixinSettings());return e}async putMixinSetting(e,t){const r=this.sessions;this.sessions=new Map,"enabledStreams"===e?this.storage.setItem(e,JSON.stringify(t)):this.storage.setItem(e,t.toString());for(const e of r.values()){var i;null===(i=e.parserSessionPromise)||void 0===i||i.then((e=>e.kill()))}this.ensurePrebufferSessions()}getEnabledMediaStreamOptions(e){if(e&&e.length){try{const t=JSON.parse(this.storage.getItem("enabledStreams"));return e.filter((e=>t.includes(e.name)))}catch(e){}return[e[0]]}}async getVideoStreamOptions(){const e=await this.mixinDevice.getVideoStreamOptions()||[];let t=this.getEnabledMediaStreamOptions(e);const r=parseInt(this.storage.getItem(y))||v;if(t)for(const e of t)e.prebuffer=r;else e.push({prebuffer:r});return e}release(){this.console.log("prebuffer releasing if started"),this.released=!0;for(const t of this.sessions.values()){var e;null===(e=t.parserSessionPromise)||void 0===e||e.then((e=>{this.console.log("prebuffer released"),e.kill()}))}}}class PrebufferProvider extends c.AutoenableMixinProvider{constructor(e){super(e);for(const e of Object.keys(h.getSystemState())){var t;const r=h.getDeviceById(e);null!==(t=r.mixins)&&void 0!==t&&t.includes(this.id)&&r.getVideoStreamOptions()}const r=function(){var e=new Date;return e.setHours(24),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0),e.getTime()-(new Date).getTime()}()+72e5;this.log.i(`Rebroadcaster scheduled for restart at 2AM: ${Math.round(r/1e3/60)} minutes`),setTimeout((()=>g.requestRestart()),r)}async canMixin(e,r){return r.includes(t.ScryptedInterface.VideoCamera)?[t.ScryptedInterface.VideoCamera,t.ScryptedInterface.Settings]:null}async getMixin(e,t,r){return this.setHasEnabledMixin(r.id),new PrebufferMixin(e,t,r,this.nativeId)}async releaseMixin(e,t){t.release()}}var x=new PrebufferProvider;e.default=x})();var n=exports="undefined"==typeof exports?{}:exports;for(var o in i)n[o]=i[o];i.__esModule&&Object.defineProperty(n,"__esModule",{value:!0})})();
|
|
1
|
+
(()=>{var e={454:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.AutoenableMixinProvider=void 0;var i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=n(t);if(r&&r.has(e))return r.get(e);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&Object.prototype.hasOwnProperty.call(e,s)){var a=o?Object.getOwnPropertyDescriptor(e,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=e[s]}i.default=e,r&&r.set(e,i);return i}(r(510));function n(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(n=function(e){return e?r:t})(e)}const{systemManager:o}=i.default,s="v4";class AutoenableMixinProvider extends i.ScryptedDeviceBase{constructor(e){var t,r,n;super(e),n={},(r="hasEnabledMixin")in(t=this)?Object.defineProperty(t,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[r]=n;try{this.hasEnabledMixin=JSON.parse(this.storage.getItem("hasEnabledMixin"))}catch(e){this.hasEnabledMixin={}}this.pluginsComponent=o.getComponent("plugins"),o.listen((async(e,t,r)=>{t.eventInterface!==i.ScryptedInterface.ScryptedDevice||t.property||this.maybeEnableMixin(e)}));for(const e of Object.keys(o.getSystemState())){const t=o.getDeviceById(e);this.maybeEnableMixin(t)}}async maybeEnableMixin(e){var t;if(!e||null!==(t=e.mixins)&&void 0!==t&&t.includes(this.id))return;if(this.hasEnabledMixin[e.id]===s)return;if(!await this.canMixin(e.type,e.interfaces))return;this.log.i("auto enabling mixin for "+e.name);const r=(e.mixins||[]).slice();r.push(this.id);const i=await this.pluginsComponent;await i.setMixins(e.id,r),this.setHasEnabledMixin(e.id)}setHasEnabledMixin(e){this.hasEnabledMixin[e]!==s&&(this.hasEnabledMixin[e]=s,this.storage.setItem("hasEnabledMixin",JSON.stringify(this.hasEnabledMixin)))}}t.AutoenableMixinProvider=AutoenableMixinProvider},201:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createRebroadcaster=h,t.parseAudioCodec=f,t.parseResolution=l,t.parseVideoCodec=m,t.startRebroadcastSession=async function(e,t){let r,a=0,c=!0;const p=new s.EventEmitter,{console:g}=t;let v,y,S;function b(){c&&(p.emit("killed"),p.emit("error",new Error("killed"))),c=!1,null==A||A.kill();for(const e of x)null==e||e.close()}function M(){t.timeout&&(clearTimeout(r),r=setTimeout(b,t.timeout))}M();const P={},O=e.inputArguments.slice(),x=[];let D,w;const I=new Promise(((e,t)=>{D=e,w=t}));setTimeout((()=>w(new Error("timed out waiting for incoming initiate ffmpeg tcp connection"))),1e4);for(const n of Object.keys(t.parsers)){const s=t.parsers[n],d=n+"-data";if(t.parseOnly)P[n]={url:void 0,mediaStreamOptions:e.mediaStreamOptions};else{const{server:t,port:i}=await h({connect:(e,t)=>{a++,clearTimeout(r);const i=()=>{p.removeListener(d,e),p.removeListener("killed",t),a--,0===a&&M(),t()};return p.on(d,e),p.once("killed",i),i}});x.push(t);const o=`tcp://127.0.0.1:${i}`;P[n]={url:o,mediaStreamOptions:e.mediaStreamOptions,inputArguments:["-f",n,"-i",o]}}const c=(0,i.createServer)((async e=>{c.close(),D(e);try{const i=n+"-data";for await(const n of s.parse(e,parseInt(null===(t=S)||void 0===t?void 0:t[2]),parseInt(null===(r=S)||void 0===r?void 0:r[3]))){var t,r;p.emit(i,n)}}catch(e){g.error("rebroadcast parse error",e),b()}}));x.push(c);const u=await(0,o.listenZeroCluster)(c);O.push(...s.outputArguments,`tcp://127.0.0.1:${u}`)}O.unshift("-hide_banner"),g.log(O);const A=n.default.spawn(await u.getFFmpegPath(),O);return(0,d.ffmpegLogInitialOutput)(g,A),A.on("exit",b),f(A).then((e=>v=e)),m(A).then((e=>y=e)),l(A).then((e=>S=e)),await I,{inputAudioCodec:v,inputVideoCodec:y,inputVideoResolution:S,events:p,resetActivityTimer:M,isActive:()=>c,kill:b,servers:x,cp:A,ffmpegInputs:P}};var i=r(808),n=c(r(81)),o=r(769),s=r(361),a=c(r(510)),d=r(833);function c(e){return e&&e.__esModule?e:{default:e}}const{mediaManager:u}=a.default;async function l(e){return new Promise((t=>{const r=i=>{const n=i.toString(),o=/(([0-9]{2,5})x([0-9]{2,5}))/.exec(n);o&&(e.stdout.removeListener("data",r),e.stderr.removeListener("data",r),t(o))};e.stdout.on("data",r),e.stderr.on("data",r)}))}async function p(e,t){return new Promise((r=>{const i=n=>{const o=n.toString(),s=o.indexOf(`${t}: `);if(-1!==s){const n=o.substring(s+t.length+1).trim();let a=n.indexOf(" ");const d=n.indexOf(",");-1!==a&&d<a&&(a=d),-1!==a&&(e.stdout.removeListener("data",i),e.stderr.removeListener("data",i),r(n.substring(0,a)))}};e.stdout.on("data",i),e.stderr.on("data",i)}))}async function m(e){return p(e,"Video")}async function f(e){return p(e,"Audio")}async function h(e){const t=(0,i.createServer)((t=>{let r=!0;const i=()=>{t.removeAllListeners(),t.destroy();const e=n;n=void 0,null==e||e()};let n=null==e?void 0:e.connect((e=>{r&&(r=!1,e.startStream&&t.write(e.startStream));for(const r of e.chunks)t.write(r);return t.writableLength}),i);t.on("end",i),t.on("close",i),t.on("error",i)}));return{server:t,port:await(0,o.listenZeroCluster)(t)}}},769:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.listenZeroCluster=async function(e){for(;;){const t=1e4+Math.round(3e4*Math.random());e.listen(t);try{return await(0,i.once)(e,"listening"),e.address().port}catch(e){}}};var i=r(361)},833:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=r(568);Object.keys(i).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===i[e]||Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}}))}))},701:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.readLength=async function(e,t){if(!t)return Buffer.alloc(0);{const r=e.read(t);if(r)return r}return new Promise(((r,i)=>{const n=()=>{const i=e.read(t);i&&(s(),r(i))},o=()=>{s(),i(new Error(`stream ended during read for minimum ${t} bytes`))},s=()=>{e.removeListener("readable",n),e.removeListener("end",o)};e.on("readable",n),e.on("end",o)}))}},567:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SettingsMixinDeviceBase=void 0;var i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=n(t);if(r&&r.has(e))return r.get(e);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in e)if("default"!==s&&Object.prototype.hasOwnProperty.call(e,s)){var a=o?Object.getOwnPropertyDescriptor(e,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=e[s]}i.default=e,r&&r.set(e,i);return i}(r(510));function n(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(n=function(e){return e?r:t})(e)}const{deviceManager:o}=i.default;class SettingsMixinDeviceBase extends i.MixinDeviceBase{constructor(e,t,r){super(e,r.mixinDeviceInterfaces,t,r.providerNativeId),this.settingsGroup=r.group,this.settingsGroupKey=r.groupKey}async getSettings(){const e=this.mixinDeviceInterfaces.includes(i.ScryptedInterface.Settings)?this.mixinDevice.getSettings():void 0,t=await this.getMixinSettings();for(const e of t)e.group=e.group||this.settingsGroup,e.key=this.settingsGroupKey+":"+e.key;const r=await e||[];return r.push(...t),r}async putSetting(e,t){var r;const n=this.settingsGroupKey+":";if(null==e||!e.startsWith(n))return this.mixinDevice.putSetting(e,t);await this.putMixinSetting(e.substring(n.length),t),null===(r=o.onMixinEvent)||void 0===r||r.call(o,this.id,this.mixinProviderNativeId,i.ScryptedInterface.Settings,null)}}t.SettingsMixinDeviceBase=SettingsMixinDeviceBase},129:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PIXEL_FORMAT_YUV420P=t.PIXEL_FORMAT_RGB24=void 0,t.createFragmentedMp4Parser=function(e){return{container:"mp4",outputArguments:[...(null==e?void 0:e.vcodec)||[],...(null==e?void 0:e.acodec)||[],"-movflags","frag_keyframe+empty_moov+default_base_moof","-f","mp4"],async*parse(e){const t=a(e);let r,i,n;for await(const e of t)r?i||(i=e):r=e,yield{startStream:n,chunks:[e.header,e.data],type:e.type},r&&i&&!n&&(n=Buffer.concat([r.header,r.data,i.header,i.data]))},findSyncFrame:o}},t.createMpegTsParser=function(e){return{container:"mpegts",outputArguments:[...(null==e?void 0:e.vcodec)||[],...(null==e?void 0:e.acodec)||[],"-f","mpegts"],parse:s(188,(e=>{if(71!=e[0])throw new Error("Invalid sync byte in mpeg-ts packet. Terminating stream.")})),findSyncFrame(e){for(let t=0;t<e.length;t++){const r=e[t];for(let i=0;i<r.chunks.length;i++){const n=r.chunks[i];let o=0;for(;o+188<n.length;){const r=n.subarray(o,o+188);if(256==((31&r[1])<<8|r[2])&&32&r[3]&&r[4]>0&&64&r[5])return e.slice(t);o+=188}}}return e}}},t.createPCMParser=function(){return{container:"s16le",outputArguments:["-vn","-acodec","pcm_s16le","-f","s16le"],parse:s(512),findSyncFrame:o}},t.createRawVideoParser=function(e){var t;const r=(null===(t=e)||void 0===t?void 0:t.pixelFormat)||d;let i;e=e||{};const{size:s,everyNFrames:a}=e;s&&(i=`scale=${s.width}:${s.height}`);a&&a>1&&(i?i+=",":i="",i+=`select=not(mod(n\\,${a}))`);return{container:"rawvideo",outputArguments:[...i?["-vf",i]:[],"-an","-vcodec","rawvideo","-pix_fmt",r.name,"-f","rawvideo"],async*parse(e,t,i){if(!t||!i)throw new Error("error parsing rawvideo, unknown width and height");t=(null==s?void 0:s.width)||t,i=(null==s?void 0:s.height)||i;const o=r.computeLength(t,i);for(;;){const r=await(0,n.readLength)(e,o);yield{chunks:[r],width:t,height:i}}},findSyncFrame:o}},t.parseFragmentedMP4=a;var i=r(361),n=r(701);function o(e){return e}function s(e,t){return async function*(r){let n=[],o=0;for(;;){const s=r.read();if(!s){await(0,i.once)(r,"readable");continue}if(n.push(s),o+=s.length,o<e)continue;const a=Buffer.concat(n);null==t||t(a);const d=a.length%e,c=a.slice(0,a.length-d),u=a.slice(a.length-d);n=[u],o=u.length,yield{chunks:[c]}}}}async function*a(e){for(;;){const t=await(0,n.readLength)(e,8),r=t.readInt32BE(0)-8,i=t.slice(4).toString(),o=await(0,n.readLength)(e,r);yield{header:t,length:r,type:i,data:o}}}const d={name:"yuv420p",computeLength:(e,t)=>e*t*1.5};t.PIXEL_FORMAT_YUV420P=d;t.PIXEL_FORMAT_RGB24={name:"rgb24",computeLength:(e,t)=>e*t*3}},510:(e,t,r)=>{"use strict";var i=Object.create?function(e,t,r,i){void 0===i&&(i=r),Object.defineProperty(e,i,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]},n=function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||i(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),t.MixinDeviceBase=t.ScryptedDeviceBase=void 0,n(r(393),t);const o=r(393);class ScryptedDeviceBase extends o.DeviceBase{constructor(e){super(),this.nativeId=e}get storage(){return this._storage||(this._storage=deviceManager.getDeviceStorage(this.nativeId)),this._storage}get log(){return this._log||(this._log=deviceManager.getDeviceLogger(this.nativeId)),this._log}get console(){return this._console||(this._console=deviceManager.getDeviceConsole(this.nativeId)),this._console}_lazyLoadDeviceState(){this._deviceState||(this.nativeId?this._deviceState=deviceManager.getDeviceState(this.nativeId):this._deviceState=deviceManager.getDeviceState())}onDeviceEvent(e,t){return deviceManager.onDeviceEvent(this.nativeId,e,t)}}t.ScryptedDeviceBase=ScryptedDeviceBase;class MixinDeviceBase extends o.DeviceBase{constructor(e,t,r,i){super(),this.mixinDevice=e,this.mixinDeviceInterfaces=t,this.mixinProviderNativeId=i,this._deviceState=r}get storage(){return this._storage||(this._storage=deviceManager.getMixinStorage(this.id,this.mixinProviderNativeId)),this._storage}get console(){return this._console||(deviceManager.getMixinConsole?this._console=deviceManager.getMixinConsole(this.id,this.mixinProviderNativeId):this._console=deviceManager.getDeviceConsole(this.mixinProviderNativeId)),this._console}onDeviceEvent(e,t){return deviceManager.onMixinEvent(this.id,this.mixinProviderNativeId,e,t)}_lazyLoadDeviceState(){}release(){}}t.MixinDeviceBase=MixinDeviceBase,function(){function e(e){return function(){return this._lazyLoadDeviceState(),this._deviceState[e]}}function t(e){return function(t){this._lazyLoadDeviceState(),this._deviceState[e]=t}}for(var r of Object.values(o.ScryptedInterfaceProperty))Object.defineProperty(ScryptedDeviceBase.prototype,r,{set:t(r),get:e(r)}),Object.defineProperty(MixinDeviceBase.prototype,r,{set:t(r),get:e(r)})}();let s={};try{s=Object.assign(s,{log:deviceManager.getDeviceLogger(void 0),deviceManager,endpointManager,mediaManager,systemManager,pluginHostAPI})}catch(e){console.error("sdk initialization error, import @scrypted/sdk/types instead",e)}t.default=s},393:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ThermostatMode=t.TemperatureUnit=t.ScryptedMimeTypes=t.ScryptedInterfaceProperty=t.ScryptedInterfaceDescriptors=t.ScryptedInterface=t.ScryptedDeviceType=t.SCRYPTED_MEDIA_SCHEME=t.MediaPlayerState=t.LockState=t.HumidityMode=t.FanMode=t.DeviceBase=void 0;let r;t.DeviceBase=class DeviceBase{},t.ScryptedInterfaceProperty=r,function(e){e.id="id",e.info="info",e.interfaces="interfaces",e.mixins="mixins",e.name="name",e.providedInterfaces="providedInterfaces",e.providedName="providedName",e.providedRoom="providedRoom",e.providedType="providedType",e.providerId="providerId",e.room="room",e.type="type",e.on="on",e.brightness="brightness",e.colorTemperature="colorTemperature",e.rgb="rgb",e.hsv="hsv",e.running="running",e.paused="paused",e.docked="docked",e.thermostatActiveMode="thermostatActiveMode",e.thermostatAvailableModes="thermostatAvailableModes",e.thermostatMode="thermostatMode",e.thermostatSetpoint="thermostatSetpoint",e.thermostatSetpointHigh="thermostatSetpointHigh",e.thermostatSetpointLow="thermostatSetpointLow",e.temperature="temperature",e.temperatureUnit="temperatureUnit",e.humidity="humidity",e.lockState="lockState",e.entryOpen="entryOpen",e.batteryLevel="batteryLevel",e.online="online",e.updateAvailable="updateAvailable",e.fromMimeType="fromMimeType",e.toMimeType="toMimeType",e.binaryState="binaryState",e.intrusionDetected="intrusionDetected",e.powerDetected="powerDetected",e.audioDetected="audioDetected",e.motionDetected="motionDetected",e.occupied="occupied",e.flooded="flooded",e.ultraviolet="ultraviolet",e.luminance="luminance",e.position="position",e.humiditySetting="humiditySetting",e.fan="fan"}(r||(t.ScryptedInterfaceProperty=r={}));let i,n,o,s,a,d,c,u,l;t.ScryptedInterfaceDescriptors={ScryptedDevice:{name:"ScryptedDevice",methods:["listen","probe","setName","setRoom","setType"],properties:["id","info","interfaces","mixins","name","providedInterfaces","providedName","providedRoom","providedType","providerId","room","type"]},OnOff:{name:"OnOff",methods:["turnOff","turnOn"],properties:["on"]},Brightness:{name:"Brightness",methods:["setBrightness"],properties:["brightness"]},ColorSettingTemperature:{name:"ColorSettingTemperature",methods:["getTemperatureMaxK","getTemperatureMinK","setColorTemperature"],properties:["colorTemperature"]},ColorSettingRgb:{name:"ColorSettingRgb",methods:["setRgb"],properties:["rgb"]},ColorSettingHsv:{name:"ColorSettingHsv",methods:["setHsv"],properties:["hsv"]},Notifier:{name:"Notifier",methods:["sendNotification"],properties:[]},StartStop:{name:"StartStop",methods:["start","stop"],properties:["running"]},Pause:{name:"Pause",methods:["pause","resume"],properties:["paused"]},Dock:{name:"Dock",methods:["dock"],properties:["docked"]},TemperatureSetting:{name:"TemperatureSetting",methods:["setThermostatMode","setThermostatSetpoint","setThermostatSetpointHigh","setThermostatSetpointLow"],properties:["thermostatActiveMode","thermostatAvailableModes","thermostatMode","thermostatSetpoint","thermostatSetpointHigh","thermostatSetpointLow"]},Thermometer:{name:"Thermometer",methods:[],properties:["temperature","temperatureUnit"]},HumiditySensor:{name:"HumiditySensor",methods:[],properties:["humidity"]},Camera:{name:"Camera",methods:["getPictureOptions","takePicture"],properties:[]},VideoCamera:{name:"VideoCamera",methods:["getVideoStream","getVideoStreamOptions"],properties:[]},Intercom:{name:"Intercom",methods:["startIntercom","stopIntercom"],properties:[]},Lock:{name:"Lock",methods:["lock","unlock"],properties:["lockState"]},PasswordStore:{name:"PasswordStore",methods:["addPassword","getPasswords","removePassword"],properties:[]},Authenticator:{name:"Authenticator",methods:["checkPassword"],properties:[]},Scene:{name:"Scene",methods:["activate","deactivate","isReversible"],properties:[]},Entry:{name:"Entry",methods:["closeEntry","openEntry"],properties:[]},EntrySensor:{name:"EntrySensor",methods:[],properties:["entryOpen"]},DeviceProvider:{name:"DeviceProvider",methods:["discoverDevices","getDevice"],properties:[]},Battery:{name:"Battery",methods:[],properties:["batteryLevel"]},Refresh:{name:"Refresh",methods:["getRefreshFrequency","refresh"],properties:[]},MediaPlayer:{name:"MediaPlayer",methods:["getMediaStatus","load","seek","skipNext","skipPrevious"],properties:[]},Online:{name:"Online",methods:[],properties:["online"]},SoftwareUpdate:{name:"SoftwareUpdate",methods:["checkForUpdate","installUpdate"],properties:["updateAvailable"]},BufferConverter:{name:"BufferConverter",methods:["convert"],properties:["fromMimeType","toMimeType"]},Settings:{name:"Settings",methods:["getSettings","putSetting"],properties:[]},BinarySensor:{name:"BinarySensor",methods:[],properties:["binaryState"]},IntrusionSensor:{name:"IntrusionSensor",methods:[],properties:["intrusionDetected"]},PowerSensor:{name:"PowerSensor",methods:[],properties:["powerDetected"]},AudioSensor:{name:"AudioSensor",methods:[],properties:["audioDetected"]},MotionSensor:{name:"MotionSensor",methods:[],properties:["motionDetected"]},OccupancySensor:{name:"OccupancySensor",methods:[],properties:["occupied"]},FloodSensor:{name:"FloodSensor",methods:[],properties:["flooded"]},UltravioletSensor:{name:"UltravioletSensor",methods:[],properties:["ultraviolet"]},LuminanceSensor:{name:"LuminanceSensor",methods:[],properties:["luminance"]},PositionSensor:{name:"PositionSensor",methods:[],properties:["position"]},MediaSource:{name:"MediaSource",methods:["getMedia"],properties:[]},OauthClient:{name:"OauthClient",methods:["getOauthUrl","onOauthCallback"],properties:[]},MixinProvider:{name:"MixinProvider",methods:["canMixin","getMixin","releaseMixin"],properties:[]},HttpRequestHandler:{name:"HttpRequestHandler",methods:["onRequest"],properties:[]},EngineIOHandler:{name:"EngineIOHandler",methods:["onConnection"],properties:[]},PushHandler:{name:"PushHandler",methods:["onPush"],properties:[]},Program:{name:"Program",methods:["run"],properties:[]},Scriptable:{name:"Scriptable",methods:["eval","loadScripts","saveScript"],properties:[]},ObjectDetector:{name:"ObjectDetector",methods:["getDetectionInput","getObjectTypes"],properties:[]},ObjectDetection:{name:"ObjectDetection",methods:["detectObjects","getInferenceModels"],properties:[]},HumiditySetting:{name:"HumiditySetting",methods:["setHumidity"],properties:["humiditySetting"]},Fan:{name:"Fan",methods:["setFan"],properties:["fan"]}},t.ScryptedDeviceType=i,function(e){e.Builtin="Builtin",e.Camera="Camera",e.Fan="Fan",e.Light="Light",e.Switch="Switch",e.Outlet="Outlet",e.Sensor="Sensor",e.Scene="Scene",e.Program="Program",e.Automation="Automation",e.Vacuum="Vacuum",e.Notifier="Notifier",e.Thermostat="Thermostat",e.Lock="Lock",e.PasswordControl="PasswordControl",e.Display="Display",e.Speaker="Speaker",e.Event="Event",e.Entry="Entry",e.Garage="Garage",e.DeviceProvider="DeviceProvider",e.DataSource="DataSource",e.API="API",e.Doorbell="Doorbell",e.Irrigation="Irrigation",e.Valve="Valve",e.Person="Person",e.Unknown="Unknown"}(i||(t.ScryptedDeviceType=i={})),t.HumidityMode=n,function(e){e.Humidify="Humidify",e.Dehumidify="Dehumidify",e.Auto="Auto",e.Off="Off"}(n||(t.HumidityMode=n={})),t.FanMode=o,function(e){e.Auto="Auto",e.Manual="Manual"}(o||(t.FanMode=o={})),t.TemperatureUnit=s,function(e){e.C="C",e.F="F"}(s||(t.TemperatureUnit=s={})),t.ThermostatMode=a,function(e){e.Off="Off",e.Cool="Cool",e.Heat="Heat",e.HeatCool="HeatCool",e.Auto="Auto",e.FanOnly="FanOnly",e.Purifier="Purifier",e.Eco="Eco",e.Dry="Dry",e.On="On"}(a||(t.ThermostatMode=a={})),t.LockState=d,function(e){e.Locked="Locked",e.Unlocked="Unlocked",e.Jammed="Jammed"}(d||(t.LockState=d={})),t.MediaPlayerState=c,function(e){e.Idle="Idle",e.Playing="Playing",e.Paused="Paused",e.Buffering="Buffering"}(c||(t.MediaPlayerState=c={})),t.ScryptedInterface=u,function(e){e.ScryptedDevice="ScryptedDevice",e.OnOff="OnOff",e.Brightness="Brightness",e.ColorSettingTemperature="ColorSettingTemperature",e.ColorSettingRgb="ColorSettingRgb",e.ColorSettingHsv="ColorSettingHsv",e.Notifier="Notifier",e.StartStop="StartStop",e.Pause="Pause",e.Dock="Dock",e.TemperatureSetting="TemperatureSetting",e.Thermometer="Thermometer",e.HumiditySensor="HumiditySensor",e.Camera="Camera",e.VideoCamera="VideoCamera",e.Intercom="Intercom",e.Lock="Lock",e.PasswordStore="PasswordStore",e.Authenticator="Authenticator",e.Scene="Scene",e.Entry="Entry",e.EntrySensor="EntrySensor",e.DeviceProvider="DeviceProvider",e.Battery="Battery",e.Refresh="Refresh",e.MediaPlayer="MediaPlayer",e.Online="Online",e.SoftwareUpdate="SoftwareUpdate",e.BufferConverter="BufferConverter",e.Settings="Settings",e.BinarySensor="BinarySensor",e.IntrusionSensor="IntrusionSensor",e.PowerSensor="PowerSensor",e.AudioSensor="AudioSensor",e.MotionSensor="MotionSensor",e.OccupancySensor="OccupancySensor",e.FloodSensor="FloodSensor",e.UltravioletSensor="UltravioletSensor",e.LuminanceSensor="LuminanceSensor",e.PositionSensor="PositionSensor",e.MediaSource="MediaSource",e.OauthClient="OauthClient",e.MixinProvider="MixinProvider",e.HttpRequestHandler="HttpRequestHandler",e.EngineIOHandler="EngineIOHandler",e.PushHandler="PushHandler",e.Program="Program",e.Scriptable="Scriptable",e.ObjectDetector="ObjectDetector",e.ObjectDetection="ObjectDetection",e.HumiditySetting="HumiditySetting",e.Fan="Fan"}(u||(t.ScryptedInterface=u={})),t.ScryptedMimeTypes=l,function(e){e.AcceptUrlParameter="accept-url",e.Url="text/x-uri",e.InsecureLocalUrl="text/x-insecure-local-uri",e.LocalUrl="text/x-local-uri",e.PushEndpoint="text/x-push-endpoint",e.MediaStreamUrl="text/x-media-url",e.FFmpegInput="x-scrypted/x-ffmpeg-input",e.RTCAVOffer="x-scrypted/x-rtc-av-offer",e.RTCAVAnswer="x-scrypted/x-rtc-av-answer"}(l||(t.ScryptedMimeTypes=l={}));t.SCRYPTED_MEDIA_SCHEME="scryped-media://"},568:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ffmpegLogInitialOutput=function(e,t,i){var n,o;function s(e){const n=o=>{const s=o.toString();for(const e of r)if(-1!==s.indexOf(e))return;if(!i&&(-1!==s.indexOf("frame=")||-1!==s.indexOf("size=")))return e(s),e("video/audio detected, discarding further input"),t.stdout.removeListener("data",n),void t.stderr.removeListener("data",n);e(s)};return n}null===(n=t.stdout)||void 0===n||n.on("data",s(e.log)),null===(o=t.stderr)||void 0===o||o.on("data",s(e.error)),t.on("exit",(()=>e.log("ffmpeg exited")))},t.probeVideoCamera=async function(e){let t;try{t=await e.getVideoStreamOptions()||[]}catch(e){}const r=t&&t.length&&null===t[0].audio;return{options:t,noAudio:r}};const r=["decode_slice_header error","no frame!","non-existing PPS"]},81:e=>{"use strict";e.exports=require("child_process")},361:e=>{"use strict";e.exports=require("events")},808:e=>{"use strict";e.exports=require("net")}},t={};function r(i){var n=t[i];if(void 0!==n)return n.exports;var o=t[i]={exports:{}};return e[i](o,o.exports,r),o.exports}var i={};(()=>{"use strict";var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var t=l(r(510)),n=l(r(361)),o=r(567),s=r(201),a=r(833),d=r(129),c=r(454);function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(u=function(e){return e?r:t})(e)}function l(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var r=u(t);if(r&&r.has(e))return r.get(e);var i={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var s=n?Object.getOwnPropertyDescriptor(e,o):null;s&&(s.get||s.set)?Object.defineProperty(i,o,s):i[o]=e[o]}return i.default=e,r&&r.set(e,i),i}function p(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}const{mediaManager:m,log:f,systemManager:h,deviceManager:g}=t.default,v=1e4,y="prebufferDuration",S="sendKeyframe",b="Default",M="MP2/MP3 Audio",P="Other Audio",O="PCM or G.711 Audio",x=`${O} (Copy, !Experimental!)`,D=["aac","mp3","mp2","",void 0,null];class PrebufferSession{constructor(e,t,r){p(this,"prebuffers",{mp4:[],mpegts:[],s16le:[]}),p(this,"events",new n.default),p(this,"detectedIdrInterval",0),p(this,"prevIdr",0),p(this,"incompatibleDetected",!1),p(this,"legacyDetected",!1),p(this,"allowImmediateRestart",!1),p(this,"AUDIO_CONFIGURATION","audioConfiguration-"+this.streamId),this.mixin=e,this.streamName=t,this.streamId=r,this.storage=e.storage,this.console=e.console,this.mixinDevice=e.mixinDevice}ensurePrebufferSession(){this.parserSessionPromise||this.mixin.released||(this.console.log("prebuffer session started",this.streamId),this.parserSessionPromise=this.startPrebufferSession(),this.parserSessionPromise.catch((()=>this.parserSessionPromise=void 0)))}getAudioConfig(){const e=this.storage.getItem(this.AUDIO_CONFIGURATION)||"",t=-1!==e.indexOf(O),r=-1!==e.indexOf(M),i=-1!==e.indexOf(P)||!t&&this.incompatibleDetected;return{audioConfig:e,pcmAudio:t,legacyAudio:r,reencodeAudio:i}}async getMixinSettings(){var e,t,r;const i=[],n=this.parserSession;let o=0,s=0;for(const e of this.prebuffers.mp4){s=s||e.time;for(const t of e.chunk.chunks)o+=t.byteLength}const a=Date.now()-s,d=Math.round(o/a*8),c=this.streamName?`Rebroadcast: ${this.streamName}`:"Rebroadcast";return i.push({title:"Audio Codec Transcoding",group:c,description:"Configuring your camera to output AAC, MP3, or MP2 is recommended. PCM/G711 cameras should set this to Reencode.",type:"string",key:this.AUDIO_CONFIGURATION,value:this.storage.getItem(this.AUDIO_CONFIGURATION)||b,choices:[b,"AAC (Copy) or No Audio",M,"Other Audio (Transcode)",x]},{key:"detectedResolution",group:c,title:"Detected Resolution and Bitrate",readonly:!0,value:`${(null==n||null===(e=n.inputVideoResolution)||void 0===e?void 0:e[0])||"unknown"} @ ${d||"unknown"} Kb/s`,description:"Configuring your camera to 1920x1080, 2000Kb/S, Variable Bit Rate, is recommended."},{key:"detectedCodec",group:c,title:"Detected Video/Audio Codecs",readonly:!0,value:((null==n||null===(t=n.inputVideoCodec)||void 0===t?void 0:t.toString())||"unknown")+"/"+((null==n||null===(r=n.inputAudioCodec)||void 0===r?void 0:r.toString())||"unknown"),description:"Configuring your camera to H264 video and AAC/MP3/MP2 audio is recommended."},{key:"detectedKeyframe",group:c,title:"Detected Keyframe Interval",description:"Configuring your camera to 4 seconds is recommended (IDR aka Frame Interval = FPS * 4 seconds).",readonly:!0,value:((this.detectedIdrInterval||0)/1e3).toString()||"none"}),i}async startPrebufferSession(){var e,r,i;this.prebuffers.mp4=[],this.prebuffers.mpegts=[],this.prebuffers.s16le=[];const n=parseInt(this.storage.getItem(y))||v,o=await(0,a.probeVideoCamera)(this.mixinDevice);let c;o.options&&(c=o.options.find((e=>e.id===this.streamId)));const u=null==o||null===(e=o.options)||void 0===e||null===(r=e[0])||void 0===r||null===(i=r.audio)||void 0===i?void 0:i.codec;this.incompatibleDetected=this.incompatibleDetected||u&&!D.includes(u),this.incompatibleDetected&&this.console.warn("configure your camera to output aac, mp3, or mp2 audio. incompatible audio codec detected",u);const l=await this.mixinDevice.getVideoStream(c),p=await m.convertMediaObjectToBuffer(l,t.ScryptedMimeTypes.FFmpegInput),h=JSON.parse(p.toString()),{audioConfig:g,pcmAudio:S,reencodeAudio:b,legacyAudio:M}=this.getAudioConfig();let P;P=o.noAudio||S?["-an"]:b?["-bsf:a","aac_adtstoasc","-acodec","libfdk_aac","-profile:a","aac_low","-flags","+global_header","-ar","8k","-b:a","100k","-ac","1"]:["-acodec","copy",...M||this.legacyDetected?[]:["-bsf:a","aac_adtstoasc"]];const O=["-vcodec","copy"],x={console:this.console,parsers:{mp4:(0,d.createFragmentedMp4Parser)({vcodec:O,acodec:P}),mpegts:(0,d.createMpegTsParser)({vcodec:O,acodec:P})},parseOnly:!0};!o.noAudio&&S&&(x.parsers.s16le=(0,d.createPCMParser)()),this.parsers=x.parsers;const w=await(0,s.startRebroadcastSession)(h,x);let I;this.parserSession=w;const A=()=>{clearTimeout(I),I=setTimeout((()=>{this.console.error("watchdog for mp4 parser timed out... killing ffmpeg session"),w.kill()}),6e4)};w.events.on("mp4-data",A),w.events.once("killed",(()=>{this.parserSessionPromise=void 0,w.events.removeListener("mp4-data",A),clearTimeout(I)})),A(),w.inputAudioCodec?D.includes(w.inputAudioCodec)?"aac"!==w.inputAudioCodec&&(this.console.error("Detected audio codec was not AAC.",w.inputAudioCodec),f.a(`${this.mixin.name} is using ${w.inputAudioCodec} audio. Enable MP2/MP3 Audio in Rebroadcast Settings Audio Configuration to suppress this alert.`),this.legacyDetected=!0,this.allowImmediateRestart=!0):(this.console.error("Detected audio codec is not mp4/mpegts compatible.",w.inputAudioCodec),g||o.noAudio||(f.a(`${this.mixin.name} is using ${w.inputAudioCodec} audio. Enable Reencode Audio in Rebroadcast Settings Audio Configuration to suppress this alert.`),this.incompatibleDetected=!0,this.allowImmediateRestart=!0)):this.console.warn("no audio detected."),"h264"!==w.inputVideoCodec&&this.console.error("video codec is not h264. If there are errors, try changing your camera's encoder output.");for(const e of["mpegts","mp4","s16le"]){const t=e+"-data";let r=this.prebuffers[e],i=0;w.events.on(t,(o=>{const s=Date.now();for("mdat"===o.type&&(this.prevIdr&&(this.detectedIdrInterval=s-this.prevIdr),this.prevIdr=s),r.push({time:s,chunk:o});r.length&&r[0].time<s-n;)r.shift(),i++;i>1e3&&(r=this.prebuffers[e]=r.slice(),i=0),this.events.emit(t,o)}))}return w}async getVideoStream(e){var t,r;this.ensurePrebufferSession();const i=await this.parserSessionPromise,n="false"!==this.storage.getItem(S),o=(null==e?void 0:e.prebuffer)||(n?1.5*Math.max(4e3,this.detectedIdrInterval||4e3):0);if(!(null!=e&&e.prebuffer||n)){return m.createFFmpegMediaObject(i.ffmpegInputs.mpegts)}this.console.log("prebuffer request started",this.streamId);const a=async e=>{const t=e+"-data",r=this.prebuffers[e],{server:n,port:a}=await(0,s.createRebroadcaster)({connect:(e,s)=>{n.close();const a=Date.now(),d=t=>{e(t)>1e8&&(this.console.log("more than 100MB has been buffered, did downstream die? killing connection."),c())},c=()=>{s(),this.console.log("prebuffer request ended"),this.events.removeListener(t,d),i.events.removeListener("killed",c)};this.events.on(t,d),i.events.once("killed",c);for(const e of r)e.time<a-o||d(e.chunk);return c}});return setTimeout((()=>n.close()),3e4),a},d=(null==e?void 0:e.container)||"mpegts",c=i.ffmpegInputs[d].mediaStreamOptions?Object.assign({},i.ffmpegInputs[d].mediaStreamOptions):{};c.prebuffer=o;const{audioConfig:u,pcmAudio:l,reencodeAudio:p}=this.getAudioConfig();c.audio=p?{codec:"aac"}:{codec:null==i?void 0:i.inputAudioCodec},c.video&&null!==(t=i.inputVideoResolution)&&void 0!==t&&t[2]&&null!==(r=i.inputVideoResolution)&&void 0!==r&&r[3]&&Object.assign(c.video,{width:parseInt(i.inputVideoResolution[2]),height:parseInt(i.inputVideoResolution[3])});const f=`tcp://127.0.0.1:${await a(d)}`,h={url:f,container:d,inputArguments:["-f",d,"-i",f],mediaStreamOptions:c};l&&h.inputArguments.push("-f","s16le","-i",`tcp://127.0.0.1:${await a("s16le")}`),this.console.log("prebuffer ffmpeg input",h);return m.createFFmpegMediaObject(h)}}class PrebufferMixin extends o.SettingsMixinDeviceBase{constructor(e,t,r,i){super(e,r,{providerNativeId:i,mixinDeviceInterfaces:t,group:"Prebuffer Settings",groupKey:"prebuffer"}),p(this,"released",!1),p(this,"sessions",new Map),this.delayStart()}delayStart(){this.console.log("prebuffer sessions starting in 5 seconds"),setTimeout((()=>this.ensurePrebufferSessions()),5e3)}async getVideoStream(e){await this.ensurePrebufferSessions();let r=null==e?void 0:e.id;if(!r&&!this.sessions.has(r)){var i;const n=await this.mixinDevice.getVideoStream(e),o=JSON.parse((await m.convertMediaObjectToBuffer(n,t.ScryptedMimeTypes.FFmpegInput)).toString());r=null==o||null===(i=o.mediaStreamOptions)||void 0===i?void 0:i.id,this.sessions.set(null==e?void 0:e.id,this.sessions.get(r))}let n=this.sessions.get(r);return n?(n.ensurePrebufferSession(),await n.parserSessionPromise,n=this.sessions.get(r),n?n.getVideoStream(e):this.mixinDevice.getVideoStream(e)):this.mixinDevice.getVideoStream(e)}async ensurePrebufferSessions(){const e=await this.mixinDevice.getVideoStreamOptions(),r=this.getEnabledMediaStreamOptions(e),i=r?r.map((e=>e.id)):[void 0];for(const t of i){let r=this.sessions.get(t);if(!r){const i=null==e?void 0:e.find((e=>e.id===t));null!=i&&i.prebuffer&&f.a(`Prebuffer is already available on ${this.name}. If this is a grouped device, disable the Rebroadcast extension.`);const o=null==i?void 0:i.name;r=new PrebufferSession(this,o,t),this.sessions.set(t,r),(async()=>{for(;this.sessions.get(t)===r&&!this.released;){this.console.log("monitoring prebuffer session"),r.ensurePrebufferSession();try{const e=await r.parserSessionPromise;await(0,n.once)(e.events,"killed"),this.console.error("prebuffer session ended")}catch(e){this.console.error("prebuffer session ended with error",e)}this.console.log("restarting prebuffer session in 5 seconds"),await new Promise((e=>setTimeout(e,5e3)))}this.console.log("exiting prebuffer session (released or restarted with new configuration)")})()}}g.onMixinEvent(this.id,this.mixinProviderNativeId,t.ScryptedInterface.Settings,void 0)}async getMixinSettings(){const e=[],t=await this.mixinDevice.getVideoStreamOptions(),r=this.getEnabledMediaStreamOptions(t);r&&(null==t?void 0:t.length)>1&&e.push({title:"Prebuffered Streams",description:"The streams to prebuffer. Enable only as necessary to reduce traffic.",key:"enabledStreams",value:r.map((e=>e.name||"")),choices:t.map((e=>e.name)),multiple:!0}),e.push({title:"Prebuffer Duration",description:"Duration of the prebuffer in milliseconds.",type:"number",key:y,value:this.storage.getItem(y)||v.toString()},{title:"Start at Previous Keyframe",description:"Start live streams from the previous key frame. Improves startup time.",type:"boolean",key:S,value:("false"!==this.storage.getItem(S)).toString()});for(const t of new Set([...this.sessions.values()]))e.push(...await t.getMixinSettings());return e}async putMixinSetting(e,t){const r=this.sessions;this.sessions=new Map,"enabledStreams"===e?this.storage.setItem(e,JSON.stringify(t)):this.storage.setItem(e,t.toString());for(const e of r.values()){var i;null===(i=e.parserSessionPromise)||void 0===i||i.then((e=>e.kill()))}this.ensurePrebufferSessions()}getEnabledMediaStreamOptions(e){if(e&&e.length){try{const t=JSON.parse(this.storage.getItem("enabledStreams"));return e.filter((e=>t.includes(e.name)))}catch(e){}return[e[0]]}}async getVideoStreamOptions(){const e=await this.mixinDevice.getVideoStreamOptions()||[];let t=this.getEnabledMediaStreamOptions(e);const r=parseInt(this.storage.getItem(y))||v;if(t)for(const e of t)e.prebuffer=r;else e.push({prebuffer:r});return e}release(){this.console.log("prebuffer releasing if started"),this.released=!0;for(const t of this.sessions.values()){var e;null===(e=t.parserSessionPromise)||void 0===e||e.then((e=>{this.console.log("prebuffer released"),e.kill()}))}}}class PrebufferProvider extends c.AutoenableMixinProvider{constructor(e){super(e);for(const e of Object.keys(h.getSystemState())){var t;const r=h.getDeviceById(e);null!==(t=r.mixins)&&void 0!==t&&t.includes(this.id)&&r.getVideoStreamOptions()}const r=function(){var e=new Date;return e.setHours(24),e.setMinutes(0),e.setSeconds(0),e.setMilliseconds(0),e.getTime()-(new Date).getTime()}()+72e5;this.log.i(`Rebroadcaster scheduled for restart at 2AM: ${Math.round(r/1e3/60)} minutes`),setTimeout((()=>g.requestRestart()),r)}async canMixin(e,r){return r.includes(t.ScryptedInterface.VideoCamera)?[t.ScryptedInterface.VideoCamera,t.ScryptedInterface.Settings]:null}async getMixin(e,t,r){return this.setHasEnabledMixin(r.id),new PrebufferMixin(e,t,r,this.nativeId)}async releaseMixin(e,t){t.release()}}var w=new PrebufferProvider;e.default=w})();var n=exports="undefined"==typeof exports?{}:exports;for(var o in i)n[o]=i[o];i.__esModule&&Object.defineProperty(n,"__esModule",{value:!0})})();
|
|
2
2
|
//# sourceMappingURL=main.nodejs.js.map
|
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -14,10 +14,12 @@ const defaultPrebufferDuration = 10000;
|
|
|
14
14
|
const PREBUFFER_DURATION_MS = 'prebufferDuration';
|
|
15
15
|
const SEND_KEYFRAME = 'sendKeyframe';
|
|
16
16
|
const AUDIO_CONFIGURATION_TEMPLATE = 'audioConfiguration';
|
|
17
|
-
const
|
|
17
|
+
const DEFAULT_AUDIO = 'Default';
|
|
18
|
+
const COMPATIBLE_AUDIO = 'AAC (Copy) or No Audio';
|
|
19
|
+
const LEGACY_AUDIO = 'MP2/MP3 Audio'
|
|
18
20
|
const OTHER_AUDIO = 'Other Audio';
|
|
19
21
|
const OTHER_AUDIO_DESCRIPTION = `${OTHER_AUDIO} (Transcode)`;
|
|
20
|
-
const PCM_AUDIO = 'PCM Audio';
|
|
22
|
+
const PCM_AUDIO = 'PCM or G.711 Audio';
|
|
21
23
|
const PCM_AUDIO_DESCRIPTION = `${PCM_AUDIO} (Copy, !Experimental!)`;
|
|
22
24
|
const compatibleAudio = ['aac', 'mp3', 'mp2', '', undefined, null];
|
|
23
25
|
|
|
@@ -47,6 +49,7 @@ class PrebufferSession {
|
|
|
47
49
|
detectedIdrInterval = 0;
|
|
48
50
|
prevIdr = 0;
|
|
49
51
|
incompatibleDetected = false;
|
|
52
|
+
legacyDetected = false;
|
|
50
53
|
allowImmediateRestart = false;
|
|
51
54
|
|
|
52
55
|
mixinDevice: VideoCamera;
|
|
@@ -72,16 +75,19 @@ class PrebufferSession {
|
|
|
72
75
|
getAudioConfig(): {
|
|
73
76
|
audioConfig: string,
|
|
74
77
|
pcmAudio: boolean,
|
|
78
|
+
legacyAudio: boolean,
|
|
75
79
|
reencodeAudio: boolean,
|
|
76
80
|
} {
|
|
77
81
|
const audioConfig = this.storage.getItem(this.AUDIO_CONFIGURATION) || '';
|
|
78
82
|
// pcm audio only used when explicitly set.
|
|
79
83
|
const pcmAudio = audioConfig.indexOf(PCM_AUDIO) !== -1;
|
|
84
|
+
const legacyAudio = audioConfig.indexOf(LEGACY_AUDIO) !== -1;
|
|
80
85
|
// reencode audio will be used if explicitly set, OR an incompatible codec was detected, PCM audio was not explicitly set
|
|
81
86
|
const reencodeAudio = audioConfig.indexOf(OTHER_AUDIO) !== -1 || (!pcmAudio && this.incompatibleDetected);
|
|
82
87
|
return {
|
|
83
88
|
audioConfig,
|
|
84
89
|
pcmAudio,
|
|
90
|
+
legacyAudio,
|
|
85
91
|
reencodeAudio,
|
|
86
92
|
}
|
|
87
93
|
}
|
|
@@ -111,9 +117,11 @@ class PrebufferSession {
|
|
|
111
117
|
description: 'Configuring your camera to output AAC, MP3, or MP2 is recommended. PCM/G711 cameras should set this to Reencode.',
|
|
112
118
|
type: 'string',
|
|
113
119
|
key: this.AUDIO_CONFIGURATION,
|
|
114
|
-
value: this.storage.getItem(this.AUDIO_CONFIGURATION) ||
|
|
120
|
+
value: this.storage.getItem(this.AUDIO_CONFIGURATION) || DEFAULT_AUDIO,
|
|
115
121
|
choices: [
|
|
122
|
+
DEFAULT_AUDIO,
|
|
116
123
|
COMPATIBLE_AUDIO,
|
|
124
|
+
LEGACY_AUDIO,
|
|
117
125
|
OTHER_AUDIO_DESCRIPTION,
|
|
118
126
|
PCM_AUDIO_DESCRIPTION,
|
|
119
127
|
],
|
|
@@ -160,13 +168,13 @@ class PrebufferSession {
|
|
|
160
168
|
const probeAudioCodec = probe?.options?.[0]?.audio?.codec;
|
|
161
169
|
this.incompatibleDetected = this.incompatibleDetected || (probeAudioCodec && !compatibleAudio.includes(probeAudioCodec));
|
|
162
170
|
if (this.incompatibleDetected)
|
|
163
|
-
this.console.warn('configure your camera to output aac, mp3, or mp2 audio.
|
|
171
|
+
this.console.warn('configure your camera to output aac, mp3, or mp2 audio. incompatible audio codec detected', probeAudioCodec);
|
|
164
172
|
|
|
165
173
|
const mo = await this.mixinDevice.getVideoStream(mso);
|
|
166
174
|
const moBuffer = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.FFmpegInput);
|
|
167
175
|
const ffmpegInput = JSON.parse(moBuffer.toString()) as FFMpegInput;
|
|
168
176
|
|
|
169
|
-
const { audioConfig, pcmAudio, reencodeAudio } = this.getAudioConfig();
|
|
177
|
+
const { audioConfig, pcmAudio, reencodeAudio, legacyAudio } = this.getAudioConfig();
|
|
170
178
|
|
|
171
179
|
let acodec: string[];
|
|
172
180
|
if (probe.noAudio || pcmAudio) {
|
|
@@ -178,7 +186,11 @@ class PrebufferSession {
|
|
|
178
186
|
acodec = [
|
|
179
187
|
'-bsf:a', 'aac_adtstoasc',
|
|
180
188
|
'-acodec', 'libfdk_aac',
|
|
181
|
-
'-profile:a', 'aac_low'
|
|
189
|
+
'-profile:a', 'aac_low',
|
|
190
|
+
'-flags', '+global_header',
|
|
191
|
+
'-ar', `8k`,
|
|
192
|
+
'-b:a', `100k`,
|
|
193
|
+
'-ac', `1`,
|
|
182
194
|
];
|
|
183
195
|
}
|
|
184
196
|
else {
|
|
@@ -186,6 +198,7 @@ class PrebufferSession {
|
|
|
186
198
|
acodec = [
|
|
187
199
|
'-acodec',
|
|
188
200
|
'copy',
|
|
201
|
+
...(legacyAudio || this.legacyDetected ? [] : ['-bsf:a', 'aac_adtstoasc']),
|
|
189
202
|
];
|
|
190
203
|
}
|
|
191
204
|
|
|
@@ -242,16 +255,24 @@ class PrebufferSession {
|
|
|
242
255
|
this.console.warn('no audio detected.');
|
|
243
256
|
}
|
|
244
257
|
else if (!compatibleAudio.includes(session.inputAudioCodec)) {
|
|
245
|
-
this.console.error('Detected audio codec
|
|
258
|
+
this.console.error('Detected audio codec is not mp4/mpegts compatible.', session.inputAudioCodec);
|
|
246
259
|
// show an alert if no audio config was explicitly specified. Force the user to choose/experiment.
|
|
247
260
|
if (!audioConfig && !probe.noAudio) {
|
|
248
|
-
log.a(`${this.mixin.name} is using ${session.inputAudioCodec} audio. Enable Reencode Audio in Rebroadcast Settings Audio Configuration to
|
|
261
|
+
log.a(`${this.mixin.name} is using ${session.inputAudioCodec} audio. Enable Reencode Audio in Rebroadcast Settings Audio Configuration to suppress this alert.`);
|
|
249
262
|
this.incompatibleDetected = true;
|
|
250
263
|
this.allowImmediateRestart = true;
|
|
251
264
|
// this will probably crash ffmpeg due to mp4/mpegts not being a valid container for pcm,
|
|
252
265
|
// and then it will automatically restart with pcm handling.
|
|
253
266
|
}
|
|
254
267
|
}
|
|
268
|
+
else if (session.inputAudioCodec !== 'aac') {
|
|
269
|
+
this.console.error('Detected audio codec was not AAC.', session.inputAudioCodec);
|
|
270
|
+
log.a(`${this.mixin.name} is using ${session.inputAudioCodec} audio. Enable MP2/MP3 Audio in Rebroadcast Settings Audio Configuration to suppress this alert.`);
|
|
271
|
+
this.legacyDetected = true;
|
|
272
|
+
this.allowImmediateRestart = true;
|
|
273
|
+
// this will probably crash ffmpeg due to mp2/mp3 not supporting the aac bit stream filters,
|
|
274
|
+
// and then it will automatically restart with legacy handling.
|
|
275
|
+
}
|
|
255
276
|
|
|
256
277
|
if (session.inputVideoCodec !== 'h264') {
|
|
257
278
|
this.console.error(`video codec is not h264. If there are errors, try changing your camera's encoder output.`);
|
|
@@ -341,7 +362,7 @@ class PrebufferSession {
|
|
|
341
362
|
if (prebuffer.time < now - requestedPrebuffer)
|
|
342
363
|
continue;
|
|
343
364
|
|
|
344
|
-
|
|
365
|
+
safeWriteData(prebuffer.chunk);
|
|
345
366
|
}
|
|
346
367
|
|
|
347
368
|
// for some reason this doesn't work as well as simply guessing and dumping.
|
|
@@ -387,10 +408,13 @@ class PrebufferSession {
|
|
|
387
408
|
})
|
|
388
409
|
}
|
|
389
410
|
|
|
411
|
+
const url = `tcp://127.0.0.1:${await createContainerServer(container)}`;
|
|
390
412
|
const ffmpegInput: FFMpegInput = {
|
|
413
|
+
url,
|
|
414
|
+
container,
|
|
391
415
|
inputArguments: [
|
|
392
416
|
'-f', container,
|
|
393
|
-
'-i',
|
|
417
|
+
'-i', url,
|
|
394
418
|
],
|
|
395
419
|
mediaStreamOptions,
|
|
396
420
|
}
|
|
@@ -465,7 +489,7 @@ class PrebufferMixin extends SettingsMixinDeviceBase<VideoCamera> implements Vid
|
|
|
465
489
|
session = new PrebufferSession(this, name, id);
|
|
466
490
|
this.sessions.set(id, session);
|
|
467
491
|
|
|
468
|
-
(async() => {
|
|
492
|
+
(async () => {
|
|
469
493
|
while (this.sessions.get(id) === session && !this.released) {
|
|
470
494
|
this.console.log('monitoring prebuffer session');
|
|
471
495
|
session.ensurePrebufferSession();
|