Support custom JSMPEG options.

This commit is contained in:
Dermot Duffy
2021-11-15 20:52:28 -08:00
parent 6b6b1774db
commit e691eb9755
3 changed files with 66 additions and 23 deletions
+1
View File
@@ -116,6 +116,7 @@ All variables listed are under a `live:` section.
| `webrtc.entity` | | The RTSP entity to pass WebRTC. Specify this OR `webrtc.url` (above). |
| `webrtc.*`| | Any other options in a `webrtc:` YAML dictionary are silently passed through to WebRTC. See [WebRTC Configuration](https://github.com/AlexxIT/WebRTC#configuration) for full details this external card provides.|
| `actions` | | Actions to use for the `live` view. See [actions](#actions) below.|
| `jsmpeg.options.{audio, video, pauseWhenHidden, disableGl, disableWebAssembly, preserveDrawingBuffer, progressive, throttled, chunkSize, maxAudioLag, videoBufferSize, audioBufferSize}` | | **Advanced users only**: Control the underlying [JSMPEG library options](https://github.com/phoboslab/jsmpeg#usage). This is not necessary for the vast majority of users: only set these flags if you know what you're doing, as you may entirely break video rendering in the card.|
#### Available Live Providers
+34 -18
View File
@@ -1,5 +1,11 @@
import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit';
import type { ExtendedHomeAssistant, FrigateCardConfig, MediaShowInfo, WebRTCConfig } from '../types.js';
import type {
ExtendedHomeAssistant,
FrigateCardConfig,
JSMPEGConfig,
MediaShowInfo,
WebRTCConfig,
} from '../types.js';
import { HomeAssistant } from 'custom-card-helpers';
import { customElement, property } from 'lit/decorators.js';
import { until } from 'lit/directives/until.js';
@@ -93,6 +99,7 @@ export class FrigateCardLive extends LitElement {
.hass=${this.hass}
.cameraName=${this.frigateCameraName}
.clientId=${this.config.frigate.client_id}
.jsmpegConfig=${this.config.live.jsmpeg}
@frigate-card:media-show=${this._mediaShowHandler}
>
</frigate-card-live-jsmpeg>`}`;
@@ -242,6 +249,9 @@ export class FrigateCardLiveJSMPEG extends LitElement {
@property({ attribute: false })
protected clientId?: string;
@property({ attribute: false })
protected jsmpegConfig?: JSMPEGConfig;
protected hass?: HomeAssistant & ExtendedHomeAssistant;
protected _jsmpegCanvasElement?: HTMLCanvasElement;
protected _jsmpegVideoPlayer?: JSMpeg.VideoElement;
@@ -262,7 +272,8 @@ export class FrigateCardLiveJSMPEG extends LitElement {
response = await homeAssistantSignPath(
this.hass,
`/api/frigate/${this.clientId}` + `/jsmpeg/${this.cameraName}`,
URL_SIGN_EXPIRY_SECONDS);
URL_SIGN_EXPIRY_SECONDS,
);
} catch (err) {
console.warn(err);
return null;
@@ -279,22 +290,8 @@ export class FrigateCardLiveJSMPEG extends LitElement {
*/
protected _createJSMPEGPlayer(): JSMpeg.VideoElement {
let videoDecoded = false;
return new JSMpeg.VideoElement(
this,
this._jsmpegURL,
{
preserveDrawingBuffer: true,
canvas: this._jsmpegCanvasElement,
hooks: {
play: () => {
dispatchPlayEvent(this);
},
pause: () => {
dispatchPauseEvent(this);
},
},
},
{
const jsmpegOptions = {
pauseWhenHidden: false,
protocols: [],
audio: false,
@@ -308,7 +305,26 @@ export class FrigateCardLiveJSMPEG extends LitElement {
dispatchMediaShowEvent(this, this._jsmpegCanvasElement);
}
},
};
// Override with user-specified options.
Object.assign(jsmpegOptions, this.jsmpegConfig?.options);
return new JSMpeg.VideoElement(
this,
this._jsmpegURL,
{
canvas: this._jsmpegCanvasElement,
hooks: {
play: () => {
dispatchPlayEvent(this);
},
pause: () => {
dispatchPauseEvent(this);
},
},
},
jsmpegOptions,
);
}
+28 -2
View File
@@ -127,11 +127,13 @@ const actionSchema = z.union([
]);
export type ActionType = z.infer<typeof actionSchema>;
const actionBaseSchema = z.object({
const actionBaseSchema = z
.object({
tap_action: actionSchema.optional(),
hold_action: actionSchema.optional(),
double_tap_action: actionSchema.optional(),
}).passthrough();
})
.passthrough();
export type Actions = z.infer<typeof actionBaseSchema>;
const actionsSchema = z.object({
@@ -369,11 +371,35 @@ const webrtcConfigSchema = z
.optional();
export type WebRTCConfig = z.infer<typeof webrtcConfigSchema>;
const jsmpegConfigSchema = z
.object({
options: z
.object({
// https://github.com/phoboslab/jsmpeg#usage
audio: z.boolean().optional(),
video: z.boolean().optional(),
pauseWhenHidden: z.boolean().optional(),
disableGl: z.boolean().optional(),
disableWebAssembly: z.boolean().optional(),
preserveDrawingBuffer: z.boolean().optional(),
progressive: z.boolean().optional(),
throttled: z.boolean().optional(),
chunkSize: z.number().optional(),
maxAudioLag: z.number().optional(),
videoBufferSize: z.number().optional(),
audioBufferSize: z.number().optional(),
})
.optional(),
})
.optional();
export type JSMPEGConfig = z.infer<typeof jsmpegConfigSchema>;
const liveConfigSchema = z
.object({
provider: z.enum(LIVE_PROVIDERS).default(liveConfigDefault.provider),
preload: z.boolean().default(liveConfigDefault.preload),
webrtc: webrtcConfigSchema,
jsmpeg: jsmpegConfigSchema,
})
.merge(actionsSchema)
.default(liveConfigDefault);