Add support for timeline seeking locked to a camera.

This commit is contained in:
Dermot Duffy
2023-08-26 11:11:44 -07:00
parent 74f00e1985
commit 87f137b474
6 changed files with 60 additions and 24 deletions
+11
View File
@@ -854,6 +854,17 @@ timeline:
<a name="dimensions"></a>
#### Timeline Seek Behavior
The behavior of the timeline during seeking/dragging can be controlled by means of the icon on the bottom-right of the timeline.
| Option | Behavior |
| - | - |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>filmstrip-box-multiple</title><path d="M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M10,15H8V13H10V15M10,11H8V9H10V11M10,7H8V5H10V7M20,15H18V13H20V15M20,11H18V9H20V11M20,7H18V5H20V7Z" /></svg> | Dragging the timeline will seek / select across all available media from all cameras, selecting the media item with the longest duration whilst favoring (but not limited to) the currently selected camera. |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>play-box-lock</title><path d="M23 17.3V20.8C23 21.4 22.4 22 21.7 22H16.2C15.6 22 15 21.4 15 20.7V17.2C15 16.6 15.6 16 16.2 16V14.5C16.2 13.1 17.6 12 19 12C20.4 12 21.8 13.1 21.8 14.5V16C22.4 16 23 16.6 23 17.3M13 19V21H4C2.89 21 2 20.1 2 19V5C2 3.89 2.89 3 4 3H18C19.1 3 20 3.89 20 5V10.1L19 10L18 10.1C15.79 10.55 14.12 12.45 14 14.76C13.39 15.31 13 16.11 13 17V19M20.5 14.5C20.5 13.7 19.8 13.2 19 13.2C18.2 13.2 17.5 13.7 17.5 14.5V16H20.5V14.5M9 8V16L14 12L9 8Z" /></svg> | Dragging the timeline will seek within the selected media item only. |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>camera-lock</title><path d="M4 4H7L9 2H15L17 4H20C21.11 4 22 4.89 22 6V12C21.16 11.37 20.13 11 19 11C18.21 11 17.46 11.18 16.79 11.5C16.18 9.22 14.27 7 12 7C9.24 7 7 9.24 7 12C7 14.76 9.24 17 12 17C12.42 17 12.84 16.95 13.23 16.85C13.08 17.2 13 17.59 13 18V20H4C2.9 20 2 19.11 2 18V6C2 4.89 2.9 4 4 4M12 9C13.66 9 15 10.34 15 12C15 13.66 13.66 15 12 15C10.34 15 9 13.66 9 12C9 10.34 10.34 9 12 9M23 18.3V21.8C23 22.4 22.4 23 21.7 23H16.2C15.6 23 15 22.4 15 21.7V18.2C15 17.6 15.6 17 16.2 17V15.5C16.2 14.1 17.6 13 19 13C20.4 13 21.8 14.1 21.8 15.5V17C22.4 17 23 17.6 23 18.3M20.5 15.5C20.5 14.7 19.8 14.2 19 14.2C18.2 14.2 17.5 14.7 17.5 15.5V17H20.5V15.5Z" /></svg> | Dragging the timeline will seek / select across all available media from the selected camera only, selecting the media item with the longest duration. |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>pan-horizontal</title><path d="M7,8L2.5,12L7,16V8M17,8V16L21.5,12L17,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10Z" /></svg> | Dragging the timeline will pan only without selected or seeking any media. |
### Dimensions Options
These options control the aspect-ratio of the entire card to make placement in
+42 -21
View File
@@ -63,6 +63,7 @@ import {
MediaQueriesClassifier,
MediaQueriesType,
} from '../view/media-queries-classifier';
import { MediaQueriesResults } from '../view/media-queries-results';
import { View } from '../view/view';
import './date-picker.js';
import { DatePickerEvent, FrigateCardDatePicker } from './date-picker.js';
@@ -85,7 +86,7 @@ interface TimelineViewContext {
}
type TimelineItemClickAction = 'play' | 'select';
type TimelinePanBehavior = 'pan' | 'seek' | 'seek-in-media';
type TimelinePanBehavior = 'pan' | 'seek' | 'seek-in-media' | 'seek-in-camera';
declare module 'view' {
interface ViewContext {
@@ -288,13 +289,17 @@ export class FrigateCardTimelineCore extends LitElement {
? localize('timeline.pan_behavior.pan')
: this._panBehavior === 'seek'
? localize('timeline.pan_behavior.seek')
: localize('timeline.pan_behavior.seek-in-media');
: this._panBehavior === 'seek-in-media'
? localize('timeline.pan_behavior.seek-in-media')
: localize('timeline.pan_behavior.seek-in-camera');
const panIcon =
this._panBehavior === 'pan'
? 'mdi:pan-horizontal'
: this._panBehavior === 'seek'
? 'mdi:filmstrip'
: 'mdi:lock';
? 'mdi:filmstrip-box-multiple'
: this._panBehavior === 'seek-in-media'
? 'mdi:play-box-lock'
: 'mdi:camera-lock';
return html` ${capabilities?.supportsTimeline
? html` <div
@@ -314,6 +319,8 @@ export class FrigateCardTimelineCore extends LitElement {
? 'seek'
: this._panBehavior === 'seek'
? 'seek-in-media'
: this._panBehavior === 'seek-in-media'
? 'seek-in-camera'
: 'pan';
}}
aria-label="${panTitle}"
@@ -406,15 +413,18 @@ export class FrigateCardTimelineCore extends LitElement {
const targetBarOn =
this._shouldSupportSeeking() &&
(this._panBehavior === 'seek' ||
this._panBehavior === 'seek-in-camera' ||
(this._panBehavior === 'seek-in-media' &&
this._timeline.getSelection().some((id) => {
const item = this._timelineSource?.dataset?.get(id);
return (
this._panBehavior !== 'seek-in-camera' ||
item?.media?.getCameraID() === this.view?.camera,
item &&
item.start &&
item.end &&
targetTime.getTime() >= item.start &&
targetTime.getTime() <= item.end
item.start &&
item.end &&
targetTime.getTime() >= item.start &&
targetTime.getTime() <= item.end
);
})));
@@ -482,19 +492,30 @@ export class FrigateCardTimelineCore extends LitElement {
}
const canSeek = this._shouldSupportSeeking();
const newResults =
this._panBehavior === 'seek-in-media'
? results
: results
.clone()
.resetSelectedResult()
.selectBestResult(
(media) => findBestMediaIndex(media, targetTime, this.view?.camera),
{
allCameras: true,
main: true,
},
);
let newResults: MediaQueriesResults | null = null;
if (this._panBehavior === 'seek') {
newResults = results
.clone()
.resetSelectedResult()
.selectBestResult(
(mediaArray) => findBestMediaIndex(mediaArray, targetTime, this.view?.camera),
{
allCameras: true,
main: true,
},
);
} else if (this._panBehavior === 'seek-in-camera') {
newResults = results
.clone()
.resetSelectedResult()
.selectBestResult((mediaArray) => findBestMediaIndex(mediaArray, targetTime), {
cameraID: this.view.camera,
})
.promoteCameraSelectionToMainSelection(this.view.camera);
} else if (this._panBehavior === 'seek-in-media') {
newResults = results;
}
const desiredView: FrigateCardView = this.mini
? targetTime >= new Date()
+1
View File
@@ -516,6 +516,7 @@
"pan_behavior": {
"pan": "Pan",
"seek": "Pan seeks across all media",
"seek-in-camera": "Pan seeks within selected camera only",
"seek-in-media": "Pan seeks within selected media item only"
},
"select_date": "Choose date"
+1
View File
@@ -504,6 +504,7 @@
"pan_behavior": {
"pan": "",
"seek": "",
"seek-in-camera": "",
"seek-in-media": ""
},
"select_date": "Scegli la data"
+1
View File
@@ -515,6 +515,7 @@
"pan_behavior": {
"pan": "",
"seek": "",
"seek-in-camera": "",
"seek-in-media": ""
},
"select_date": "Escolha a data"
+4 -3
View File
@@ -495,9 +495,10 @@
},
"timeline": {
"pan_behavior": {
"pan": "Pan",
"seek": "Pan seeks across all media",
"seek-in-media": "Pan seeks within selected media item only"
"pan": "",
"seek": "",
"seek-in-camera": "",
"seek-in-media": ""
},
"select_date": "Selecionar a data"
}