diff --git a/src/components/thumbnail.ts b/src/components/thumbnail.ts
index 1043dfbe..cc5676bb 100644
--- a/src/components/thumbnail.ts
+++ b/src/components/thumbnail.ts
@@ -9,7 +9,7 @@ import thumbnailStyle from '../scss/thumbnail.scss';
import type {
FrigateBrowseMediaSource,
FrigateEvent,
- FrigateRecording,
+ FrigateRecording
} from '../types.js';
import { stopEventFromActivatingCardWideActions } from '../utils/action.js';
import { prettifyTitle } from '../utils/basic.js';
@@ -102,6 +102,12 @@ export class FrigateCardThumbnailDetailsRecording extends LitElement {
}
return html`
${prettifyTitle(this.recording.camera) || ''}
+ ${this.recording.seek_time
+ ? html`
+ ${localize('recording.seek')}
+ ${format(fromUnixTime(this.recording.seek_time), 'HH:mm:ss')}
+
`
+ : html``}
${this.recording.events}
diff --git a/src/components/timeline.ts b/src/components/timeline.ts
index 00d1c8e4..0fd14ee0 100644
--- a/src/components/timeline.ts
+++ b/src/components/timeline.ts
@@ -1,5 +1,3 @@
-// TODO: In viewer, the seek is being applied to the 2nd media. Change away from play_time?
-
import { HomeAssistant } from 'custom-card-helpers';
import {
add,
@@ -550,7 +548,7 @@ export class FrigateCardTimelineCore extends LitElement {
* provided segments to reach the target time provided.
* @param time Target time.
* @param segments A RecordingSegments object.
- * @returns
+ * @returns
*/
protected _getSeekTime(time: Date, segments: RecordingSegments): number | null {
if (!segments.length) {
@@ -578,7 +576,7 @@ export class FrigateCardTimelineCore extends LitElement {
* @param time The target time for the recordings.
* @param onlyMatchingHour If `true` only shows the hour matching the target
* for the provided cameras, otherwise shows all hours.
- * @returns
+ * @returns
*/
protected _createRecordingChildren(
results: Map
,
@@ -637,7 +635,10 @@ export class FrigateCardTimelineCore extends LitElement {
start_time: getUnixTime(startHour),
end_time: getUnixTime(endHour),
events: hourData.events,
- ...(isMatchingHour && { play_time: seekSeconds }),
+ ...(isMatchingHour && {
+ seek_seconds: seekSeconds,
+ seek_time: time.getTime() / 1000,
+ }),
},
},
),
@@ -714,7 +715,7 @@ export class FrigateCardTimelineCore extends LitElement {
/**
* Called whenever the range is in the process of being changed.
- * @param properties
+ * @param properties
*/
protected _timelineRangeChangeHandler(
properties: TimelineEventPropertiesResult,
diff --git a/src/components/viewer.ts b/src/components/viewer.ts
index a62623cf..0304949a 100644
--- a/src/components/viewer.ts
+++ b/src/components/viewer.ts
@@ -684,14 +684,14 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
super._selectSlideMediaShowHandler();
// If this is a recording and play is desired to be started from a
- // particular point, seek to that point.
- if (this.view?.media?.frigate?.recording?.play_time) {
- const player = this._getPlayer();
- if (player) {
- player.seek(this.view.media.frigate.recording.play_time);
- // TODO: Fix this bug.
- console.info(`Seeking on ${this.view.media.media_content_id}`);
- }
+ // particular point, seek to that point. Use the media off the slide itself
+ // -- when the slide is changed, the media show event may be dispatched
+ // before this.view has been updated to reflect the new selection.
+ const player = this._getPlayer() as FrigateCardMediaPlayer & {
+ media?: FrigateBrowseMediaSource;
+ };
+ if (player && player.media && player.media.frigate?.recording?.seek_seconds) {
+ player.seek(player.media.frigate.recording.seek_seconds);
}
}
@@ -716,6 +716,8 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
return;
}
+ // The media is attached to the player as '.media' which is used in
+ // `_selectSlideMediaShowHandler` (and not used by the player itself).
return html`
${mediaToRender.media_content_type === 'video'
@@ -730,6 +732,7 @@ export class FrigateCardViewerCarousel extends FrigateCardMediaCarousel {
url=${ifDefined(
lazyLoad ? undefined : this._canonicalizeHAURL(resolvedMedia?.url),
)}
+ .media=${mediaToRender}
.hass=${this.hass}
@frigate-card:media-show=${(e: CustomEvent) =>
this._mediaShowEventHandler(slideIndex, e)}
diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json
index 0984b2a8..bcb5e7c7 100644
--- a/src/localize/languages/en.json
+++ b/src/localize/languages/en.json
@@ -295,7 +295,8 @@
"score": "Score"
},
"recording": {
- "events": "Events"
+ "events": "Events",
+ "seek": "Seek"
},
"thumbnail": {
"retain_indefinitely": "Event will be indefinitely retained",
diff --git a/src/types.ts b/src/types.ts
index a7c6eb65..502e9c99 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1246,9 +1246,11 @@ export interface FrigateRecording {
end_time: number;
events: number;
- // The number of seconds at which this recording should be initially played
- // from.
- play_time?: number;
+ // Specifies the point at which this recording should be played, the
+ // seek_time is the date of the desired play point, and seek_seconds is the
+ // number of seconds to seek to reach that point.
+ seek_time?: number;
+ seek_seconds?: number;
}
export interface FrigateBrowseMediaSource extends BrowseMediaSource {