fix videojs bug when switching cameras, support recording delay, fix navigation highlight

This commit is contained in:
Jason Hunter
2021-06-02 23:20:07 -04:00
committed by Blake Blackshear
parent ca20c735f7
commit 9822d614e2
6 changed files with 108 additions and 28 deletions

View File

@@ -27,13 +27,17 @@ export default function Sidebar() {
) : null
}
</Match>
<Match path="/recordings/:camera/:date?/:hour?">
<Match path="/recordings/:camera/:date?/:hour?/:seconds?">
{({ matches }) =>
matches ? (
<Fragment>
<Separator />
{cameras.map((camera) => (
<Destination href={`/recordings/${camera}`} text={camera} />
<Destination
path={`/recordings/${camera}/:date?/:hour?/:seconds?`}
href={`/recordings/${camera}`}
text={camera}
/>
))}
<Separator />
</Fragment>

View File

@@ -1,13 +1,14 @@
import { h } from 'preact';
import { differenceInSeconds, fromUnixTime, format, startOfHour } from 'date-fns';
import { addSeconds, differenceInSeconds, fromUnixTime, format, startOfHour } from 'date-fns';
import Link from '../components/Link';
import { useApiHost } from '../api';
export default function EventCard({ camera, event }) {
export default function EventCard({ camera, event, delay }) {
const apiHost = useApiHost();
const start = fromUnixTime(event.start_time);
const end = fromUnixTime(event.end_time);
const seconds = Math.max(differenceInSeconds(start, startOfHour(start)) - 10, 0);
const duration = addSeconds(new Date(0), differenceInSeconds(end, start));
const seconds = Math.max(differenceInSeconds(start, startOfHour(start)) - delay - 10, 0);
return (
<Link className="" href={`/recordings/${camera}/${format(start, 'yyyy-MM-dd')}/${format(start, 'HH')}/${seconds}`}>
<div className="rounded-lg shadow-lg bg-gray-600 w-full flex flex-row flex-wrap p-3 antialiased mb-2">
@@ -20,18 +21,11 @@ export default function EventCard({ camera, event }) {
<div className="text-lg text-white leading-tight">{(event.top_score * 100).toFixed(1)}%</div>
<div className="text-xs md:text-normal text-gray-300 hover:text-gray-400 cursor-pointer">
<span className="border-b border-dashed border-gray-500 pb-1">
{format(start, 'HH:mm:ss')} - {format(end, 'HH:mm:ss')}
{format(start, 'HH:mm:ss')} ({format(duration, 'mm:ss')})
</span>
</div>
</div>
</div>
<div className="hidden md:block w-full text-right">
<div className="text-sm text-gray-300 hover:text-gray-400 cursor-pointer md:absolute pt-3 md:pt-0 bottom-0 right-0">
{event.zones.map((zone) => (
<div>{zone}</div>
))}
</div>
</div>
</div>
</Link>
);

View File

@@ -7,7 +7,7 @@ import Link from '../components/Link';
import Menu from '../icons/Menu';
import MenuOpen from '../icons/MenuOpen';
export default function RecordingPlaylist({ camera, recordings, selectedDate }) {
export default function RecordingPlaylist({ camera, recordings, selectedDate, selectedHour }) {
const [active, setActive] = useState(true);
const toggle = () => setActive(!active);
@@ -19,13 +19,17 @@ export default function RecordingPlaylist({ camera, recordings, selectedDate })
{recording.recordings.map((item) => (
<div className="mb-2">
<div className="text-white bg-black bg-opacity-50 border-b border-gray-500 py-2 px-4 mb-1">
<Link href={`/recordings/${camera}/${recording.date}/${item.hour}`} type="text">
{item.hour}:00
</Link>
{recording.date === selectedDate && item.hour === selectedHour ? (
<span className="text-green-500">{item.hour}:00</span>
) : (
<Link href={`/recordings/${camera}/${recording.date}/${item.hour}`} type="text">
{item.hour}:00
</Link>
)}
<span className="float-right">{item.events.length} Events</span>
</div>
{item.events.map((event) => (
<EventCard camera={camera} event={event} />
<EventCard camera={camera} event={event} delay={item.delay} />
))}
</div>
))}

View File

@@ -1,4 +1,5 @@
import { h, Component } from 'preact';
import { useEffect, useRef } from 'preact/hooks';
import videojs from 'video.js';
import 'videojs-playlist';
import 'video.js/dist/video-js.css';
@@ -8,6 +9,27 @@ const defaultOptions = {
fluid: true,
};
// export default function VideoPlayer({ children, options, onReady = () => {} }) {
// const playerRef = useRef(null);
// useEffect(() => {
// if (playerRef.current) {
// const player = videojs(playerRef.current, { ...defaultOptions, ...options }, () => {
// onReady(player);
// });
// return () => {
// player.dispose();
// };
// }
// }, [options, onReady]);
// return (
// <div data-vjs-player>
// <video ref={playerRef} className="video-js vjs-default-skin" controls playsInline />
// {children}
// </div>
// );
// }
export default class VideoPlayer extends Component {
componentDidMount() {
const { options, onReady = () => {} } = this.props;
@@ -21,14 +43,16 @@ export default class VideoPlayer extends Component {
}
componentWillUnmount() {
const { onDispose = () => {} } = this.props;
if (this.player) {
this.player.dispose();
onDispose();
}
}
shouldComponentUpdate() {
return false;
}
// shouldComponentUpdate() {
// return false;
// }
render() {
const { style, children } = this.props;

View File

@@ -44,7 +44,7 @@ export default function Recording({ camera, date, hour, seconds }) {
const selectedHour = hours.indexOf(hour);
if (this.player !== undefined) {
if (this.player) {
this.player.playlist([]);
this.player.playlist(playlist);
this.player.playlist.autoadvance(0);
@@ -74,8 +74,11 @@ export default function Recording({ camera, date, hour, seconds }) {
this.player = player;
}
}}
onDispose={() => {
this.player = null;
}}
>
<RecordingPlaylist camera={camera} recordings={data} selectedDate={selectedKey} />
<RecordingPlaylist camera={camera} recordings={data} selectedDate={selectedKey} selectedHour={hour} />
</VideoPlayer>
</div>
);