Skip to content

Commit

Permalink
Fix jump controls
Browse files Browse the repository at this point in the history
Allow to jump when video player is playing. If current time is in the middle of the active segment, jump back to the beginning of this segment.
  • Loading branch information
Dennis Benz committed Apr 26, 2024
1 parent 09d4fb1 commit e4cf493
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
12 changes: 11 additions & 1 deletion src/main/SubtitleVideoArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ import {
setIsPlayPreview,
setCurrentlyAtAndTriggerPreview,
} from "../redux/subtitleSlice";
import { selectIsMuted, selectVideos, selectVolume, setIsMuted, setVolume } from "../redux/videoSlice";
import {
selectIsMuted,
selectVideos,
selectVolume,
selectJumpTriggered,
setIsMuted,
setVolume,
setJumpTriggered,
} from "../redux/videoSlice";
import { Flavor } from "../types";
import { settings } from "../config";
import { useTranslation } from "react-i18next";
Expand Down Expand Up @@ -128,11 +136,13 @@ const SubtitleVideoArea: React.FC = () => {
selectCurrentlyAtInSeconds={selectCurrentlyAtInSeconds}
selectPreviewTriggered={selectPreviewTriggered}
selectClickTriggered={selectClickTriggered}
selectJumpTriggered={selectJumpTriggered}
selectAspectRatio={selectAspectRatio}
setIsPlaying={setIsPlaying}
selectVolume={selectVolume}
setPreviewTriggered={setPreviewTriggered}
setClickTriggered={setClickTriggered}
setJumpTriggered={setJumpTriggered}
setCurrentlyAt={setCurrentlyAtAndTriggerPreview}
setAspectRatio={setAspectRatio}
/>
Expand Down
12 changes: 12 additions & 0 deletions src/main/VideoPlayers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
selectAspectRatio,
setClickTriggered,
selectClickTriggered,
setJumpTriggered,
selectJumpTriggered,
setCurrentlyAt,
} from "../redux/videoSlice";

Expand Down Expand Up @@ -80,10 +82,12 @@ const VideoPlayers: React.FC<{
selectCurrentlyAtInSeconds={selectCurrentlyAtInSeconds}
selectPreviewTriggered={selectPreviewTriggered}
selectClickTriggered={selectClickTriggered}
selectJumpTriggered={selectJumpTriggered}
selectAspectRatio={selectAspectRatio}
setIsPlaying={setIsPlaying}
setPreviewTriggered={setPreviewTriggered}
setClickTriggered={setClickTriggered}
setJumpTriggered={setJumpTriggered}
setCurrentlyAt={setCurrentlyAt}
setAspectRatio={setAspectRatio}
ref={el => {
Expand Down Expand Up @@ -119,10 +123,12 @@ interface VideoPlayerProps {
selectCurrentlyAtInSeconds: (state: RootState) => number,
selectPreviewTriggered: (state: RootState) => boolean,
selectClickTriggered: (state: RootState) => boolean,
selectJumpTriggered: (state: RootState) => boolean,
selectAspectRatio: (state: RootState) => number,
setIsPlaying: ActionCreatorWithPayload<boolean, string>,
setPreviewTriggered: ActionCreatorWithPayload<boolean, string>,
setClickTriggered: ActionCreatorWithPayload<boolean, string>,
setJumpTriggered: ActionCreatorWithPayload<any, string>,
setCurrentlyAt: ActionCreatorWithPayload<number, string> | AsyncThunk<void, number, AsyncThunkConfig>,
setAspectRatio: ActionCreatorWithPayload<{ dataKey: number; } & { width: number, height: number; }, string>,
}
Expand All @@ -147,6 +153,7 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
selectCurrentlyAtInSeconds,
selectPreviewTriggered,
selectClickTriggered,
selectJumpTriggered,
selectAspectRatio,
setIsPlaying,
setPreviewTriggered,
Expand All @@ -166,6 +173,7 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
const duration = useAppSelector(selectDurationInSeconds);
const previewTriggered = useAppSelector(selectPreviewTriggered);
const clickTriggered = useAppSelector(selectClickTriggered);
const jumpTriggered = useAppSelector(selectJumpTriggered);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const aspectRatio = useAppSelector(selectAspectRatio);
const theme = useTheme();
Expand Down Expand Up @@ -247,6 +255,10 @@ export const VideoPlayer = React.forwardRef<VideoPlayerForwardRef, VideoPlayerPr
ref.current.seekTo(currentlyAt, "seconds");
dispatch(setClickTriggered(false));
}
if (jumpTriggered && ref.current && ready) {
ref.current.seekTo(currentlyAt, "seconds");
dispatch(setJumpTriggered(false));
}
});

useEffect(() => {
Expand Down
46 changes: 42 additions & 4 deletions src/redux/videoSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface video {
volume: number, // Video playback volume
previewTriggered: boolean, // Basically acts as a callback for the video players.
clickTriggered: boolean, // Another video player callback
jumpTriggered: boolean, // Another video player callback
currentlyAt: number, // Position in the video in milliseconds
segments: Segment[],
tracks: Track[],
Expand Down Expand Up @@ -54,6 +55,7 @@ export const initialState: video & httpRequestState = {
selectedWorkflowId: "",
previewTriggered: false,
clickTriggered: false,
jumpTriggered: false,
aspectRatios: [],
hasChanges: false,
waveformImages: [],
Expand Down Expand Up @@ -136,6 +138,9 @@ const videoSlice = createSlice({
setClickTriggered: (state, action: PayloadAction<video["clickTriggered"]>) => {
state.clickTriggered = action.payload;
},
setJumpTriggered: (state, action) => {
state.jumpTriggered = action.payload;
},
setCurrentlyAt: (state, action: PayloadAction<video["currentlyAt"]>) => {
updateCurrentlyAt(state, action.payload);
},
Expand All @@ -145,12 +150,18 @@ const videoSlice = createSlice({
jumpToPreviousSegment: state => {
let previousSegmentIndex = state.activeSegmentIndex - 1;

// Jump to start of active segment if current time is in interval [start + 3s, end)
if (state.currentlyAt >= state.segments[state.activeSegmentIndex].start + 3000) {
previousSegmentIndex = state.activeSegmentIndex;
}

if (state.activeSegmentIndex == 0) {
// Jump to start of first segment
previousSegmentIndex = state.activeSegmentIndex;
}

updateCurrentlyAt(state, state.segments[previousSegmentIndex].start);
state.jumpTriggered = true;
},
jumpToNextSegment: state => {
let nextSegmentIndex = state.activeSegmentIndex + 1;
Expand All @@ -161,6 +172,7 @@ const videoSlice = createSlice({
}

updateCurrentlyAt(state, state.segments[nextSegmentIndex].start);
state.jumpTriggered = true;
},
addSegment: (state, action: PayloadAction<video["segments"][0]>) => {
state.segments.push(action.payload);
Expand Down Expand Up @@ -296,6 +308,7 @@ const videoSlice = createSlice({
selectVolume: state => state.volume,
selectPreviewTriggered: state => state.previewTriggered,
selectClickTriggered: state => state.clickTriggered,
selectJumpTriggered: state => state.jumpTriggered,
selectCurrentlyAt: state => state.currentlyAt,
selectCurrentlyAtInSeconds: state => state.currentlyAt / 1000,
selectSegments: state => state.segments,
Expand Down Expand Up @@ -441,10 +454,34 @@ const setThumbnailHelper = (state: video, id: Track["id"], uri: Track["thumbnail
}
};

export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setIsMuted, setVolume, setCurrentlyAt,
setCurrentlyAtInSeconds, addSegment, setAspectRatio, setHasChanges, setWaveformImages, setThumbnails, setThumbnail,
removeThumbnail, setLock, cut, markAsDeletedOrAlive, setSelectedWorkflowIndex, mergeLeft, mergeRight, mergeAll,
setPreviewTriggered, setClickTriggered, jumpToPreviousSegment, jumpToNextSegment } = videoSlice.actions;
export const {
setTrackEnabled,
setIsPlaying,
setIsPlayPreview,
setIsMuted,
setVolume,
setCurrentlyAt,
setCurrentlyAtInSeconds,
addSegment,
setAspectRatio,
setHasChanges,
setWaveformImages,
setThumbnails,
setThumbnail,
removeThumbnail,
setLock,
cut,
markAsDeletedOrAlive,
setSelectedWorkflowIndex,
mergeLeft,
mergeRight,
mergeAll,
setPreviewTriggered,
setClickTriggered,
setJumpTriggered,
jumpToPreviousSegment,
jumpToNextSegment
} = videoSlice.actions;

export const selectVideos = createSelector(
[(state: { videoState: { tracks: video["tracks"]; }; }) => state.videoState.tracks],
Expand All @@ -459,6 +496,7 @@ export const {
selectVolume,
selectPreviewTriggered,
selectClickTriggered,
selectJumpTriggered,
selectCurrentlyAt,
selectCurrentlyAtInSeconds,
selectSegments,
Expand Down

0 comments on commit e4cf493

Please sign in to comment.