Move player logic back to clips

This commit is contained in:
Nick Mowen 2023-04-21 08:47:48 -06:00
parent 5d0e4f799d
commit 50e4b82b01
2 changed files with 41 additions and 57 deletions

View File

@ -1,19 +1,14 @@
import { h } from 'preact'; import { h } from 'preact';
import useSWR from 'swr'; import useSWR from 'swr';
import Heading from './Heading';
import ActivityIndicator from './ActivityIndicator'; import ActivityIndicator from './ActivityIndicator';
import { formatUnixTimestampToDateTime } from '../utils/dateUtil'; import { formatUnixTimestampToDateTime } from '../utils/dateUtil';
import PlayIcon from '../icons/Play'; import PlayIcon from '../icons/Play';
import ExitIcon from '../icons/Exit'; import ExitIcon from '../icons/Exit';
import { Zone } from '../icons/Zone'; import { Zone } from '../icons/Zone';
import { useState } from 'preact/hooks'; import { useState } from 'preact/hooks';
import { useApiHost } from '../api';
import Button from './Button'; import Button from './Button';
import VideoPlayer from './VideoPlayer';
export default function TimelineSummary({ event }) { export default function TimelineSummary({ event, onFrameSelected }) {
const apiHost = useApiHost();
const eventDuration = event.end_time - event.start_time;
const { data: eventTimeline } = useSWR([ const { data: eventTimeline } = useSWR([
'timeline', 'timeline',
{ {
@ -23,16 +18,11 @@ export default function TimelineSummary({ event }) {
const { data: config } = useSWR('config'); const { data: config } = useSWR('config');
const [timeIndex, setTimeIndex] = useState(0); const [timeIndex, setTimeIndex] = useState(-1);
const onSelectMoment = async (index) => { const onSelectMoment = async (index) => {
setTimeIndex(index); setTimeIndex(index);
onFrameSelected(eventTimeline[index].timestamp);
if (this.player) {
const videoOffset = this.player.duration() - eventDuration;
const startTime = videoOffset + (eventTimeline[index].timestamp - event.start_time);
this.player.currentTime(startTime);
}
}; };
if (!eventTimeline || !config) { if (!eventTimeline || !config) {
@ -68,29 +58,6 @@ export default function TimelineSummary({ event }) {
)} )}
</div> </div>
</div> </div>
<div className="text-center">
<Heading size="sm">{getTimelineItemDescription(config, eventTimeline[timeIndex], event)}</Heading>
<VideoPlayer
options={{
preload: 'auto',
autoplay: false,
sources: [
{
src: `${apiHost}vod/event/${event.id}/master.m3u8`,
type: 'application/vnd.apple.mpegurl',
},
],
}}
seekOptions={{ forward: 10, backward: 5 }}
onReady={(player) => {
this.player = player;
}}
onDispose={() => {
this.player = null;
}}
/>
</div>
</div> </div>
); );
} }

View File

@ -181,6 +181,17 @@ export default function Events({ path, ...props }) {
onFilter(name, items); onFilter(name, items);
}; };
const onEventFrameSelected = (event, frameTime) => {
const eventDuration = event.end_time - event.start_time;
if (this.player) {
this.player.pause();
const videoOffset = this.player.duration() - eventDuration;
const startTime = videoOffset + (frameTime - event.start_time);
this.player.currentTime(startTime);
}
};
const datePicker = useRef(); const datePicker = useRef();
const downloadButton = useRef(); const downloadButton = useRef();
@ -283,7 +294,7 @@ export default function Events({ path, ...props }) {
}; };
const handleEventDetailTabChange = (index) => { const handleEventDetailTabChange = (index) => {
setEventDetailType(index == 0 ? 'clip' : index == 1 ? 'image' : 'timeline'); setEventDetailType(index == 0 ? 'clip' : 'image');
}; };
if (!config) { if (!config) {
@ -563,20 +574,22 @@ export default function Events({ path, ...props }) {
<div className="mx-auto max-w-7xl"> <div className="mx-auto max-w-7xl">
<div className="flex justify-center w-full py-2"> <div className="flex justify-center w-full py-2">
<Tabs <Tabs
selectedIndex={ selectedIndex={event.has_clip && eventDetailType == 'clip' ? 0 : 1}
event.has_clip && eventDetailType == 'clip' ? 0 : eventDetailType == 'timeline' ? 2 : 1
}
onChange={handleEventDetailTabChange} onChange={handleEventDetailTabChange}
className="justify" className="justify"
> >
<TextTab text="Clip" disabled={!event.has_clip} /> <TextTab text="Clip" disabled={!event.has_clip} />
<TextTab text={event.has_snapshot ? 'Snapshot' : 'Thumbnail'} /> <TextTab text={event.has_snapshot ? 'Snapshot' : 'Thumbnail'} />
<TextTab text="Timeline" disabled={!event.has_clip} />
</Tabs> </Tabs>
</div> </div>
<div> <div>
{eventDetailType == 'clip' && event.has_clip ? ( {eventDetailType == 'clip' && event.has_clip ? (
<div>
<TimelineSummary
event={event}
onFrameSelected={(frameTime) => onEventFrameSelected(event, frameTime)}
/>
<VideoPlayer <VideoPlayer
options={{ options={{
preload: 'auto', preload: 'auto',
@ -589,8 +602,14 @@ export default function Events({ path, ...props }) {
], ],
}} }}
seekOptions={{ forward: 10, backward: 5 }} seekOptions={{ forward: 10, backward: 5 }}
onReady={() => {}} onReady={(player) => {
this.player = player;
}}
onDispose={() => {
this.player = null;
}}
/> />
</div>
) : null} ) : null}
{eventDetailType == 'image' || !event.has_clip ? ( {eventDetailType == 'image' || !event.has_clip ? (
@ -606,8 +625,6 @@ export default function Events({ path, ...props }) {
/> />
</div> </div>
) : null} ) : null}
{eventDetailType == 'timeline' ? <TimelineSummary event={event} /> : null}
</div> </div>
</div> </div>
</div> </div>