Move more static information into the media.
This commit is contained in:
@@ -32,7 +32,11 @@ export class CameraManagerEngineFactory {
|
|||||||
return cameraConfig ? this.getEngineForCamera(cameraConfig) : null;
|
return cameraConfig ? this.getEngineForCamera(cameraConfig) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEngineForCamera(cameraConfig: CameraConfig): CameraManagerEngine | null {
|
public getEngineForCamera(cameraConfig?: CameraConfig): CameraManagerEngine | null {
|
||||||
|
if (!cameraConfig) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
let engineKey: string | null = null;
|
let engineKey: string | null = null;
|
||||||
if (cameraConfig.frigate.camera_name) {
|
if (cameraConfig.frigate.camera_name) {
|
||||||
engineKey = 'frigate';
|
engineKey = 'frigate';
|
||||||
|
|||||||
@@ -53,11 +53,13 @@ export interface CameraManagerEngine {
|
|||||||
): Promise<QueryReturnType<RecordingSegmentsQuery> | null>;
|
): Promise<QueryReturnType<RecordingSegmentsQuery> | null>;
|
||||||
|
|
||||||
generateMediaFromEvents(
|
generateMediaFromEvents(
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
query: EventQuery,
|
query: EventQuery,
|
||||||
results: QueryReturnType<EventQuery>,
|
results: QueryReturnType<EventQuery>,
|
||||||
): ViewMedia[] | null;
|
): ViewMedia[] | null;
|
||||||
|
|
||||||
generateMediaFromRecordings(
|
generateMediaFromRecordings(
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
query: RecordingQuery,
|
query: RecordingQuery,
|
||||||
results: QueryReturnType<RecordingQuery>,
|
results: QueryReturnType<RecordingQuery>,
|
||||||
): ViewMedia[] | null;
|
): ViewMedia[] | null;
|
||||||
|
|||||||
@@ -161,12 +161,11 @@ export class FrigateCameraManagerEngine implements CameraManagerEngine {
|
|||||||
media: ViewMedia,
|
media: ViewMedia,
|
||||||
favorite: boolean,
|
favorite: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const clientID = cameraConfig.frigate.client_id;
|
|
||||||
if (!FrigateViewMediaClassifier.isFrigateEvent(media)) {
|
if (!FrigateViewMediaClassifier.isFrigateEvent(media)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await retainEvent(hass, clientID, media.getID(cameraConfig), favorite);
|
await retainEvent(hass, cameraConfig.frigate.client_id, media.getID(), favorite);
|
||||||
media.setFavorite(favorite);
|
media.setFavorite(favorite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +308,7 @@ export class FrigateCameraManagerEngine implements CameraManagerEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public generateMediaFromEvents(
|
public generateMediaFromEvents(
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
query: EventQuery,
|
query: EventQuery,
|
||||||
results: QueryReturnType<EventQuery>,
|
results: QueryReturnType<EventQuery>,
|
||||||
): ViewMedia[] | null {
|
): ViewMedia[] | null {
|
||||||
@@ -336,6 +336,7 @@ export class FrigateCameraManagerEngine implements CameraManagerEngine {
|
|||||||
const media = FrigateViewMediaFactory.createEventViewMedia(
|
const media = FrigateViewMediaFactory.createEventViewMedia(
|
||||||
mediaType,
|
mediaType,
|
||||||
query.cameraID,
|
query.cameraID,
|
||||||
|
cameraConfig,
|
||||||
event,
|
event,
|
||||||
);
|
);
|
||||||
if (media) {
|
if (media) {
|
||||||
@@ -346,6 +347,7 @@ export class FrigateCameraManagerEngine implements CameraManagerEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public generateMediaFromRecordings(
|
public generateMediaFromRecordings(
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
query: RecordingQuery,
|
query: RecordingQuery,
|
||||||
results: QueryReturnType<RecordingQuery>,
|
results: QueryReturnType<RecordingQuery>,
|
||||||
): ViewMedia[] | null {
|
): ViewMedia[] | null {
|
||||||
@@ -358,6 +360,7 @@ export class FrigateCameraManagerEngine implements CameraManagerEngine {
|
|||||||
const media = FrigateViewMediaFactory.createRecordingViewMedia(
|
const media = FrigateViewMediaFactory.createRecordingViewMedia(
|
||||||
query.cameraID,
|
query.cameraID,
|
||||||
recording,
|
recording,
|
||||||
|
cameraConfig,
|
||||||
);
|
);
|
||||||
if (media) {
|
if (media) {
|
||||||
output.push(media);
|
output.push(media);
|
||||||
|
|||||||
+75
-73
@@ -12,16 +12,27 @@ import {
|
|||||||
getEventMediaContentID,
|
getEventMediaContentID,
|
||||||
getEventThumbnailURL,
|
getEventThumbnailURL,
|
||||||
getEventTitle,
|
getEventTitle,
|
||||||
|
getRecordingID,
|
||||||
getRecordingMediaContentID,
|
getRecordingMediaContentID,
|
||||||
getRecordingTitle,
|
getRecordingTitle,
|
||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
export class FrigateEventViewMedia extends ViewMedia implements EventViewMedia {
|
export class FrigateEventViewMedia extends ViewMedia implements EventViewMedia {
|
||||||
protected _event: FrigateEvent;
|
protected _event: FrigateEvent;
|
||||||
|
protected _contentID: string;
|
||||||
|
protected _thumbnail: string;
|
||||||
|
|
||||||
constructor(mediaType: ViewMediaType, cameraID: string, event: FrigateEvent) {
|
constructor(
|
||||||
|
mediaType: ViewMediaType,
|
||||||
|
cameraID: string,
|
||||||
|
event: FrigateEvent,
|
||||||
|
contentID: string,
|
||||||
|
thumbnail: string,
|
||||||
|
) {
|
||||||
super(mediaType, cameraID);
|
super(mediaType, cameraID);
|
||||||
this._event = event;
|
this._event = event;
|
||||||
|
this._contentID = contentID;
|
||||||
|
this._thumbnail = thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasClip(): boolean {
|
public hasClip(): boolean {
|
||||||
@@ -33,36 +44,17 @@ export class FrigateEventViewMedia extends ViewMedia implements EventViewMedia {
|
|||||||
public getEndTime(): Date | null {
|
public getEndTime(): Date | null {
|
||||||
return this._event.end_time ? fromUnixTime(this._event.end_time) : null;
|
return this._event.end_time ? fromUnixTime(this._event.end_time) : null;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getID(): string {
|
||||||
public getID(_cameraConfig?: CameraConfig): string {
|
|
||||||
return this._event.id;
|
return this._event.id;
|
||||||
}
|
}
|
||||||
public getContentID(cameraConfig?: CameraConfig): string | null {
|
public getContentID(): string {
|
||||||
if (
|
return this._contentID;
|
||||||
!cameraConfig ||
|
|
||||||
!cameraConfig.frigate.client_id ||
|
|
||||||
!cameraConfig.frigate.camera_name
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getEventMediaContentID(
|
|
||||||
cameraConfig.frigate.client_id,
|
|
||||||
cameraConfig.frigate.camera_name,
|
|
||||||
this._event,
|
|
||||||
this._mediaType === 'clip' ? 'clips' : 'snapshots',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
public getTitle(): string | null {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
public getTitle(_cameraConfig?: CameraConfig): string | null {
|
|
||||||
return getEventTitle(this._event);
|
return getEventTitle(this._event);
|
||||||
}
|
}
|
||||||
|
public getThumbnail(): string | null {
|
||||||
public getThumbnail(cameraConfig?: CameraConfig): string | null {
|
return this._thumbnail;
|
||||||
if (cameraConfig?.frigate.client_id) {
|
|
||||||
return getEventThumbnailURL(cameraConfig.frigate.client_id, this._event);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public isFavorite(): boolean | null {
|
public isFavorite(): boolean | null {
|
||||||
return this._event.retain_indefinitely ?? null;
|
return this._event.retain_indefinitely ?? null;
|
||||||
@@ -89,37 +81,31 @@ export class FrigateEventViewMedia extends ViewMedia implements EventViewMedia {
|
|||||||
isEqual(this.getWhat(), that.getWhat())
|
isEqual(this.getWhat(), that.getWhat())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getClipEquivalent(): EventViewMedia | null {
|
|
||||||
if (!this.hasClip()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return FrigateViewMediaFactory.createEventViewMedia(
|
|
||||||
'clip',
|
|
||||||
this._cameraID,
|
|
||||||
this._event,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FrigateRecordingViewMedia extends ViewMedia implements RecordingViewMedia {
|
export class FrigateRecordingViewMedia extends ViewMedia implements RecordingViewMedia {
|
||||||
protected _recording: FrigateRecording;
|
protected _recording: FrigateRecording;
|
||||||
|
protected _id: string;
|
||||||
|
protected _contentID: string;
|
||||||
|
protected _title: string;
|
||||||
|
|
||||||
constructor(mediaType: ViewMediaType, cameraID: string, recording: FrigateRecording) {
|
constructor(
|
||||||
|
mediaType: ViewMediaType,
|
||||||
|
cameraID: string,
|
||||||
|
recording: FrigateRecording,
|
||||||
|
id: string,
|
||||||
|
contentID: string,
|
||||||
|
title: string,
|
||||||
|
) {
|
||||||
super(mediaType, cameraID);
|
super(mediaType, cameraID);
|
||||||
this._recording = recording;
|
this._recording = recording;
|
||||||
|
this._id = id;
|
||||||
|
this._contentID = contentID;
|
||||||
|
this._title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getID(cameraConfig?: CameraConfig): string | null {
|
public getID(): string {
|
||||||
// ID name is derived from the real camera name (not CameraID) since the
|
return this._id;
|
||||||
// recordings for the same camera across multiple zones will be the same and
|
|
||||||
// can be dedup'd from this id.
|
|
||||||
if (cameraConfig) {
|
|
||||||
return `${cameraConfig.frigate?.client_id ?? ''}/${
|
|
||||||
cameraConfig.frigate.camera_name ?? ''
|
|
||||||
}/${this._recording.startTime.getTime()}/${this._recording.endTime.getTime()}}`;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public getStartTime(): Date {
|
public getStartTime(): Date {
|
||||||
return this._recording.startTime;
|
return this._recording.startTime;
|
||||||
@@ -127,26 +113,11 @@ export class FrigateRecordingViewMedia extends ViewMedia implements RecordingVie
|
|||||||
public getEndTime(): Date {
|
public getEndTime(): Date {
|
||||||
return this._recording.endTime;
|
return this._recording.endTime;
|
||||||
}
|
}
|
||||||
public getContentID(cameraConfig?: CameraConfig): string | null {
|
public getContentID(): string | null {
|
||||||
if (
|
return this._contentID;
|
||||||
!cameraConfig ||
|
|
||||||
!cameraConfig.frigate.client_id ||
|
|
||||||
!cameraConfig.frigate.camera_name
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getRecordingMediaContentID(
|
|
||||||
cameraConfig.frigate.client_id,
|
|
||||||
cameraConfig.frigate.camera_name,
|
|
||||||
this._recording,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getTitle(): string | null {
|
||||||
public getTitle(cameraConfig?: CameraConfig): string | null {
|
return this._title;
|
||||||
if (!cameraConfig) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getRecordingTitle(cameraConfig, this._recording);
|
|
||||||
}
|
}
|
||||||
public getEventCount(): number {
|
public getEventCount(): number {
|
||||||
return this._recording.events;
|
return this._recording.events;
|
||||||
@@ -155,23 +126,54 @@ export class FrigateRecordingViewMedia extends ViewMedia implements RecordingVie
|
|||||||
|
|
||||||
export class FrigateViewMediaFactory {
|
export class FrigateViewMediaFactory {
|
||||||
static createEventViewMedia(
|
static createEventViewMedia(
|
||||||
type: 'clip' | 'snapshot',
|
mediaType: 'clip' | 'snapshot',
|
||||||
cameraID: string,
|
cameraID: string,
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
event: FrigateEvent,
|
event: FrigateEvent,
|
||||||
): FrigateEventViewMedia | null {
|
): FrigateEventViewMedia | null {
|
||||||
if (
|
if (
|
||||||
(type === 'clip' && event.has_clip) ||
|
(mediaType === 'clip' && !event.has_clip) ||
|
||||||
(type === 'snapshot' && event.has_snapshot)
|
(mediaType === 'snapshot' && !event.has_snapshot) ||
|
||||||
|
!cameraConfig.frigate.client_id ||
|
||||||
|
!cameraConfig.frigate.camera_name
|
||||||
) {
|
) {
|
||||||
return new FrigateEventViewMedia(type, cameraID, event);
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
return new FrigateEventViewMedia(
|
||||||
|
mediaType,
|
||||||
|
cameraID,
|
||||||
|
event,
|
||||||
|
getEventMediaContentID(
|
||||||
|
cameraConfig.frigate.client_id,
|
||||||
|
cameraConfig.frigate.camera_name,
|
||||||
|
event,
|
||||||
|
mediaType === 'clip' ? 'clips' : 'snapshots',
|
||||||
|
),
|
||||||
|
getEventThumbnailURL(cameraConfig.frigate.client_id, event),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createRecordingViewMedia(
|
static createRecordingViewMedia(
|
||||||
cameraID: string,
|
cameraID: string,
|
||||||
recording: FrigateRecording,
|
recording: FrigateRecording,
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
): FrigateRecordingViewMedia | null {
|
): FrigateRecordingViewMedia | null {
|
||||||
return new FrigateRecordingViewMedia('recording', cameraID, recording);
|
if (!cameraConfig.frigate.client_id || !cameraConfig.frigate.camera_name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FrigateRecordingViewMedia(
|
||||||
|
'recording',
|
||||||
|
cameraID,
|
||||||
|
recording,
|
||||||
|
getRecordingID(cameraConfig, recording),
|
||||||
|
getRecordingMediaContentID(
|
||||||
|
cameraConfig.frigate.client_id,
|
||||||
|
cameraConfig.frigate.camera_name,
|
||||||
|
recording,
|
||||||
|
),
|
||||||
|
getRecordingTitle(cameraConfig, recording),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,3 +82,18 @@ export const getRecordingMediaContentID = (
|
|||||||
String(recording.startTime.getHours()).padStart(2, '0'),
|
String(recording.startTime.getHours()).padStart(2, '0'),
|
||||||
].join('/');
|
].join('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a recording ID for internal de-duping.
|
||||||
|
*/
|
||||||
|
export const getRecordingID = (
|
||||||
|
cameraConfig: CameraConfig,
|
||||||
|
recording: FrigateRecording,
|
||||||
|
): string => {
|
||||||
|
// ID name is derived from the real camera name (not CameraID) since the
|
||||||
|
// recordings for the same camera across multiple zones will be the same and
|
||||||
|
// can be dedup'd from this id.
|
||||||
|
return `${cameraConfig.frigate?.client_id ?? ''}/${
|
||||||
|
cameraConfig.frigate.camera_name ?? ''
|
||||||
|
}/${recording.startTime.getTime()}/${recording.endTime.getTime()}}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -184,19 +184,21 @@ export class CameraManager {
|
|||||||
|
|
||||||
const mediaArray: ViewMedia[] = [];
|
const mediaArray: ViewMedia[] = [];
|
||||||
for (const [query, result] of results.entries()) {
|
for (const [query, result] of results.entries()) {
|
||||||
const engine = this._engineFactory.getEngineForQuery(this._cameras, query);
|
const cameraConfig = this._cameras.get(query.cameraID);
|
||||||
if (engine) {
|
const engine = this._engineFactory.getEngineForCamera(cameraConfig);
|
||||||
|
|
||||||
|
if (engine && cameraConfig) {
|
||||||
let media: ViewMedia[] | null = null;
|
let media: ViewMedia[] | null = null;
|
||||||
if (
|
if (
|
||||||
QueryClassifier.isEventQuery(query) &&
|
QueryClassifier.isEventQuery(query) &&
|
||||||
QueryResultClassifier.isEventQueryResult(result)
|
QueryResultClassifier.isEventQueryResult(result)
|
||||||
) {
|
) {
|
||||||
media = engine.generateMediaFromEvents(query, result);
|
media = engine.generateMediaFromEvents(cameraConfig, query, result);
|
||||||
} else if (
|
} else if (
|
||||||
QueryClassifier.isRecordingQuery(query) &&
|
QueryClassifier.isRecordingQuery(query) &&
|
||||||
QueryResultClassifier.isRecordingQuery(result)
|
QueryResultClassifier.isRecordingQuery(result)
|
||||||
) {
|
) {
|
||||||
media = engine.generateMediaFromRecordings(query, result);
|
media = engine.generateMediaFromRecordings(cameraConfig, query, result);
|
||||||
}
|
}
|
||||||
if (media) {
|
if (media) {
|
||||||
mediaArray.push(...media);
|
mediaArray.push(...media);
|
||||||
@@ -210,7 +212,7 @@ export class CameraManager {
|
|||||||
// are assumed to be unique.
|
// are assumed to be unique.
|
||||||
uniqBy(
|
uniqBy(
|
||||||
mediaArray,
|
mediaArray,
|
||||||
(media) => media.getID(this._cameras.get(media.getCameraID())) ?? media,
|
(media) => media.getID() ?? media,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Sort all items leading with the most recent.
|
// Sort all items leading with the most recent.
|
||||||
|
|||||||
+3
-3
@@ -1402,10 +1402,10 @@ export class FrigateCard extends LitElement {
|
|||||||
const media = this._view.queryResults?.getSelectedResult();
|
const media = this._view.queryResults?.getSelectedResult();
|
||||||
|
|
||||||
if (this._view.isViewerView() && media && this._cameras) {
|
if (this._view.isViewerView() && media && this._cameras) {
|
||||||
media_content_id = media.getContentID(cameraConfig);
|
media_content_id = media.getContentID();
|
||||||
media_content_type = media.getContentType();
|
media_content_type = media.getContentType();
|
||||||
title = media.getTitle(cameraConfig);
|
title = media.getTitle();
|
||||||
thumbnail = media.getThumbnail(cameraConfig);
|
thumbnail = media.getThumbnail();
|
||||||
} else if (this._view?.is('live') && cameraEntity) {
|
} else if (this._view?.is('live') && cameraEntity) {
|
||||||
media_content_id = `media-source://camera/${cameraEntity}`;
|
media_content_id = `media-source://camera/${cameraEntity}`;
|
||||||
media_content_type = 'application/vnd.apple.mpegurl';
|
media_content_type = 'application/vnd.apple.mpegurl';
|
||||||
|
|||||||
@@ -256,8 +256,8 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const thumbnail = this.media.getThumbnail(this.cameraConfig);
|
const thumbnail = this.media.getThumbnail();
|
||||||
const title = this.media.getTitle(this.cameraConfig) ?? '';
|
const title = this.media.getTitle() ?? '';
|
||||||
|
|
||||||
const starClasses = {
|
const starClasses = {
|
||||||
star: true,
|
star: true,
|
||||||
@@ -271,7 +271,6 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
// Only show timeline control if the recording has a start & end time.
|
// Only show timeline control if the recording has a start & end time.
|
||||||
(this.media.getStartTime() && this.media.getEndTime()));
|
(this.media.getStartTime() && this.media.getEndTime()));
|
||||||
|
|
||||||
const clientID = this.cameraConfig?.frigate.client_id;
|
|
||||||
return html` ${ViewMediaClassifier.isEvent(this.media)
|
return html` ${ViewMediaClassifier.isEvent(this.media)
|
||||||
? html`<frigate-card-thumbnail-feature-event
|
? html`<frigate-card-thumbnail-feature-event
|
||||||
aria-label="${title ?? ''}"
|
aria-label="${title ?? ''}"
|
||||||
@@ -289,7 +288,7 @@ export class FrigateCardThumbnail extends LitElement {
|
|||||||
.date=${this.media.getStartTime() ?? undefined}
|
.date=${this.media.getStartTime() ?? undefined}
|
||||||
></frigate-card-thumbnail-feature-recording>`
|
></frigate-card-thumbnail-feature-recording>`
|
||||||
: html``}
|
: html``}
|
||||||
${this.show_favorite_control && this.media && this.hass && clientID
|
${this.show_favorite_control && this.media && this.hass
|
||||||
? html` <ha-icon
|
? html` <ha-icon
|
||||||
class="${classMap(starClasses)}"
|
class="${classMap(starClasses)}"
|
||||||
icon=${this.media.isFavorite() ? 'mdi:star' : 'mdi:star-outline'}
|
icon=${this.media.isFavorite() ? 'mdi:star' : 'mdi:star-outline'}
|
||||||
|
|||||||
+4
-9
@@ -1,4 +1,3 @@
|
|||||||
import { CameraConfig } from '../types.js';
|
|
||||||
export type ViewMediaType = 'clip' | 'snapshot' | 'recording';
|
export type ViewMediaType = 'clip' | 'snapshot' | 'recording';
|
||||||
|
|
||||||
export class ViewMedia {
|
export class ViewMedia {
|
||||||
@@ -18,8 +17,7 @@ export class ViewMedia {
|
|||||||
public getMediaType(): ViewMediaType {
|
public getMediaType(): ViewMediaType {
|
||||||
return this._mediaType;
|
return this._mediaType;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getID(): string | null {
|
||||||
public getID(_cameraConfig?: CameraConfig): string | null {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public getStartTime(): Date | null {
|
public getStartTime(): Date | null {
|
||||||
@@ -28,16 +26,13 @@ export class ViewMedia {
|
|||||||
public getEndTime(): Date | null {
|
public getEndTime(): Date | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getContentID(): string | null {
|
||||||
public getContentID(_cameraConfig?: CameraConfig): string | null {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getTitle(): string | null {
|
||||||
public getTitle(_cameraConfig?: CameraConfig): string | null {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
public getThumbnail(): string | null {
|
||||||
public getThumbnail(_cameraConfig?: CameraConfig): string | null {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public isFavorite(): boolean | null {
|
public isFavorite(): boolean | null {
|
||||||
|
|||||||
Reference in New Issue
Block a user