@scrypted/prebuffer-mixin 0.1.222 → 0.1.225

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.
@@ -1,4 +1,5 @@
1
- import { StorageSetting, StorageSettings, StorageSettingsDict } from "@scrypted/common/src/settings";
1
+ import { getH264DecoderArgs } from "@scrypted/common/src/ffmpeg-hardware-acceleration";
2
+ import { StorageSetting, StorageSettings } from "@scrypted/common/src/settings";
2
3
  import { MixinDeviceBase, ResponseMediaStreamOptions, VideoCamera } from "@scrypted/sdk";
3
4
 
4
5
  export function getDefaultPrebufferedStreams(msos: ResponseMediaStreamOptions[]) {
@@ -54,13 +55,13 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
54
55
  const streamTypes = getStreamTypes({
55
56
  defaultStream: {
56
57
  title: 'Local Stream',
57
- description: 'The media stream to use when streaming on your local network. This is the default stream. Recommended resolution: 1920x1080 to 4K.',
58
+ description: 'The media stream to use when streaming on your local network. This stream should be prebuffered. Recommended resolution: 1920x1080 to 4K.',
58
59
  hide: true,
59
60
  prefersPrebuffer: true,
60
61
  preferredResolution: 3840 * 2160,
61
62
  },
62
63
  remoteStream: {
63
- title: 'Remote/Mid Stream',
64
+ title: 'Remote (Medium Resolution) Stream',
64
65
  description: 'The media stream to use when streaming from outside your local network. Selecting a low birate stream is recommended. Recommended resolution: 1270x720.',
65
66
  hide: true,
66
67
  prefersPrebuffer: false,
@@ -71,18 +72,18 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
71
72
  description: 'The media stream to use for low resolution output, such as Apple Watch and Video Analysis. Recommended resolution: 480x360.',
72
73
  hide: true,
73
74
  prefersPrebuffer: false,
74
- preferredResolution: 480 * 320,
75
+ preferredResolution: 480 * 360,
75
76
  },
76
77
  recordingStream: {
77
78
  title: 'Local Recording Stream',
78
- description: 'The media stream to use when recording to local storage such as an NVR.',
79
+ description: 'The media stream to use when recording to local storage such as an NVR. This stream should be prebuffered. Recommended resolution: 1920x1080 to 4K.',
79
80
  hide: true,
80
81
  prefersPrebuffer: true,
81
82
  preferredResolution: 3840 * 2160,
82
83
  },
83
84
  remoteRecordingStream: {
84
85
  title: 'Remote Recording Stream',
85
- description: 'The media stream to use when recording to cloud storage such as HomeKit Secure Video clips in iCloud.',
86
+ description: 'The media stream to use when recording to cloud storage such as HomeKit Secure Video clips in iCloud. This stream should be prebuffered. Recommended resolution: 1270x720.',
86
87
  hide: true,
87
88
  prefersPrebuffer: true,
88
89
  preferredResolution: 1280 * 720,
@@ -94,21 +95,72 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
94
95
  title: 'Prebuffered Streams',
95
96
  description: 'Prebuffering maintains an active connection to the stream and improves load times. Prebuffer also retains the recent video for capturing motion events with HomeKit Secure video. Enabling Prebuffer is not recommended on Cloud cameras.',
96
97
  multiple: true,
97
- hide: true,
98
+ hide: false,
98
99
  },
99
100
  ...streamTypes,
101
+ transcodeStreams: {
102
+ group: 'Transcoding',
103
+ title: 'Transcode Streams',
104
+ description: 'The media streams to transcode. Transcoding audio and video is not recommended and should only be used when necessary. The Rebroadcast Plugin manages the system-wide Transcode settings. See the Rebroadcast Readme for optimal configuration.',
105
+ multiple: true,
106
+ choices: Object.values(streamTypes).map(st => st.title),
107
+ },
108
+ // 3/6/2022
109
+ // Ran into an issue where the RTSP source had SPS/PPS in the SDP,
110
+ // and none in the bitstream. Codec copy will not add SPS/PPS before IDR frames
111
+ // unless this flag is used.
112
+ // 3/7/2022
113
+ // This flag was enabled by default, but I believe this is causing issues with some users.
114
+ // Make it a setting.
115
+ missingCodecParameters: {
116
+ group: 'Transcoding',
117
+ title: 'Add H264 Extra Data',
118
+ description: 'Some cameras do not include H264 extra data in the stream and this causes live streaming to always fail (but recordings may be working). This is a inexpensive video filter and does not perform a transcode. Enable this setting only as necessary.',
119
+ type: 'boolean',
120
+ },
121
+ videoDecoderArguments: {
122
+ group: 'Transcoding',
123
+ title: 'Video Decoder Arguments',
124
+ description: 'FFmpeg arguments used to decode input video when transcoding a stream.',
125
+ placeholder: '-hwaccel auto',
126
+ choices: Object.keys(getH264DecoderArgs()),
127
+ combobox: true,
128
+ mapPut: (oldValue, newValue) => getH264DecoderArgs()[newValue]?.join(' ') || newValue,
129
+ }
100
130
  });
101
131
 
102
- function getMediaStream(v: StreamStorageSetting, msos: ResponseMediaStreamOptions[]) {
132
+ function getDefaultMediaStream(v: StreamStorageSetting, msos: ResponseMediaStreamOptions[]) {
103
133
  const enabledStreams = getPrebufferedStreams(storageSettings, msos);
104
134
  const prebufferPreferenceStreams = v.prefersPrebuffer && enabledStreams?.length > 0 ? enabledStreams : msos;
105
135
  return pickBestStream(prebufferPreferenceStreams, v.preferredResolution);
136
+ }
137
+
138
+ function getMediaStream(key: string, msos: ResponseMediaStreamOptions[]) {
139
+ const v: StreamStorageSetting = storageSettings.settings[key];
140
+ const value = storageSettings.values[key];
141
+ let isDefault = value === 'Default';
142
+ let stream = msos?.find(mso => mso.name === value);
143
+ if (isDefault || !stream) {
144
+ isDefault = true;
145
+ stream = getDefaultMediaStream(v, msos);
146
+ }
147
+ return {
148
+ title: streamTypes[key].title,
149
+ isDefault,
150
+ stream,
151
+ };
106
152
  };
153
+
107
154
  function createStreamOptions(v: StreamStorageSetting, msos: ResponseMediaStreamOptions[]) {
108
- const choices = msos.map(mso => mso.name);
155
+ const choices = [
156
+ 'Default',
157
+ ...msos.map(mso => mso.name),
158
+ ];
159
+ const defaultValue = getDefaultMediaStream(v, msos).name;
109
160
 
110
161
  const streamOptions = {
111
- defaultValue: getMediaStream(v, msos)?.name,
162
+ defaultValue: 'Default',
163
+ description: v.description + ` The default for this stream is ${defaultValue}.`,
112
164
  choices,
113
165
  hide: false,
114
166
  };
@@ -117,18 +169,20 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
117
169
 
118
170
  storageSettings.options = {
119
171
  onGet: async () => {
172
+ let enabledStreams: StorageSetting;
173
+
120
174
  try {
121
175
  const msos = await device.mixinDevice.getVideoStreamOptions();
122
176
 
123
- if (msos?.length > 1) {
124
- const choices = msos.map(mso => mso.name);
177
+ enabledStreams = {
178
+ defaultValue: getDefaultPrebufferedStreams(msos)?.map(mso => mso.name),
179
+ choices: msos.map(mso => mso.name),
180
+ hide: false,
181
+ };
125
182
 
183
+ if (msos?.length > 1) {
126
184
  return {
127
- enabledStreams: {
128
- defaultValue: getDefaultPrebufferedStreams(msos)?.map(mso => mso.name),
129
- choices,
130
- hide: false,
131
- },
185
+ enabledStreams,
132
186
  defaultStream: createStreamOptions(streamTypes.defaultStream, msos),
133
187
  remoteStream: createStreamOptions(streamTypes.remoteStream, msos),
134
188
  lowResolutionStream: createStreamOptions(streamTypes.lowResolutionStream, msos),
@@ -136,6 +190,11 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
136
190
  remoteRecordingStream: createStreamOptions(streamTypes.remoteRecordingStream, msos),
137
191
  }
138
192
  }
193
+ else {
194
+ return {
195
+ enabledStreams,
196
+ }
197
+ }
139
198
  }
140
199
  catch (e) {
141
200
  device.console.error('error retrieving getVideoStreamOptions', e);
@@ -147,11 +206,11 @@ export function createStreamSettings(device: MixinDeviceBase<VideoCamera>) {
147
206
  }
148
207
 
149
208
  return {
150
- getDefaultStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(streamTypes.defaultStream, msos),
151
- getRemoteStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(streamTypes.remoteStream, msos),
152
- getLowResolutionStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(streamTypes.lowResolutionStream, msos),
153
- getRecordingStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(streamTypes.recordingStream, msos),
154
- getRemoteRecordingStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(streamTypes.remoteRecordingStream, msos),
209
+ getDefaultStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(storageSettings.keys.defaultStream, msos),
210
+ getRemoteStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(storageSettings.keys.remoteStream, msos),
211
+ getLowResolutionStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(storageSettings.keys.lowResolutionStream, msos),
212
+ getRecordingStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(storageSettings.keys.recordingStream, msos),
213
+ getRemoteRecordingStream: (msos: ResponseMediaStreamOptions[]) => getMediaStream(storageSettings.keys.remoteRecordingStream, msos),
155
214
  storageSettings,
156
215
  };
157
216
  }