Skip to content

Commit

Permalink
Fix auto-pause pausing too much
Browse files Browse the repository at this point in the history
  • Loading branch information
R-J Lim committed Dec 28, 2022
1 parent 2e6d165 commit 3e71795
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 91 deletions.
63 changes: 37 additions & 26 deletions client/src/components/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
AsbplayerSettingsProvider,
AudioModel,
AudioTrackModel,
AutoPauseContext,
AutoPausePreference,
ImageModel,
KeyBinder,
Expand Down Expand Up @@ -222,6 +223,39 @@ export default function Player({
const lengthRef = useRef<number>(0);
lengthRef.current = trackLength(audioRef, videoRef, subtitles, true);

const handleOnStartedShowingSubtitle = useCallback(() => {
if (
playMode !== PlayMode.autoPause ||
settingsProvider.autoPausePreference !== AutoPausePreference.atStart ||
videoFileUrl // Let VideoPlayer do the auto-pausing
) {
return;
}

pause(clock, mediaAdapter, true);
}, [playMode, clock, mediaAdapter, videoFileUrl, settingsProvider]);

const handleOnWillStopShowingSubtitle = useCallback(() => {
if (
playMode !== PlayMode.autoPause ||
settingsProvider.autoPausePreference !== AutoPausePreference.atEnd ||
videoFileUrl // Let VideoPlayer do the auto-pausing
) {
return;
}

pause(clock, mediaAdapter, true);
}, [playMode, clock, mediaAdapter, videoFileUrl, settingsProvider]);

const autoPauseContext = useMemo(() => {
const context = new AutoPauseContext();
context.onStartedShowing = handleOnStartedShowingSubtitle;
context.onWillStopShowing = handleOnWillStopShowingSubtitle;
return context;
}, [handleOnStartedShowingSubtitle, handleOnWillStopShowingSubtitle]);
const autoPauseContextRef = useRef<AutoPauseContext>();
autoPauseContextRef.current = autoPauseContext;

const seek = useCallback(
async (time: number, clock: Clock, forwardToMedia: boolean) => {
clock.setTime(time);
Expand All @@ -230,6 +264,8 @@ export default function Player({
if (forwardToMedia) {
await mediaAdapter.seek(time / 1000);
}

autoPauseContextRef.current?.clear();
},
[forceUpdate, mediaAdapter]
);
Expand Down Expand Up @@ -618,30 +654,6 @@ export default function Player({
return () => clearInterval(interval);
}, [subtitles, subtitleCollection, playMode, clock, seek]);

const handleOnStartedShowingSubtitle = useCallback(() => {
if (
playMode !== PlayMode.autoPause ||
settingsProvider.autoPausePreference !== AutoPausePreference.atStart ||
videoFileUrl // Let VideoPlayer do the auto-pausing
) {
return;
}

pause(clock, mediaAdapter, true);
}, [playMode, clock, mediaAdapter, videoFileUrl, settingsProvider]);

const handleOnWillStopShowingSubtitle = useCallback(() => {
if (
playMode !== PlayMode.autoPause ||
settingsProvider.autoPausePreference !== AutoPausePreference.atEnd ||
videoFileUrl // Let VideoPlayer do the auto-pausing
) {
return;
}

pause(clock, mediaAdapter, true);
}, [playMode, clock, mediaAdapter, videoFileUrl, settingsProvider]);

useEffect(() => {
if (videoPopOut && channelId && videoFileUrl) {
window.open(
Expand Down Expand Up @@ -1079,8 +1091,7 @@ export default function Player({
onCopy={handleCopyFromSubtitlePlayer}
onOffsetChange={handleOffsetChange}
onToggleSubtitleTrack={handleToggleSubtitleTrack}
onStartedShowing={handleOnStartedShowingSubtitle}
onWillStopShowing={handleOnWillStopShowingSubtitle}
autoPauseContext={autoPauseContext}
settingsProvider={settingsProvider}
keyBinder={keyBinder}
/>
Expand Down
35 changes: 12 additions & 23 deletions client/src/components/SubtitlePlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
SubtitleModel,
SubtitleCollection,
KeyBinder,
AutoPauseContext,
} from '@project/common';
import { SubtitleTextImage } from '@project/common/components';
import FileCopy from '@material-ui/icons/FileCopy';
Expand Down Expand Up @@ -179,8 +180,7 @@ interface SubtitlePlayerProps {
) => void;
onOffsetChange: (offset: number) => void;
onToggleSubtitleTrack: (track: number) => void;
onStartedShowing?: () => void;
onWillStopShowing?: () => void;
autoPauseContext: AutoPauseContext;
playing: boolean;
subtitles?: DisplaySubtitleModel[];
subtitleCollection?: SubtitleCollection<DisplaySubtitleModel>;
Expand All @@ -206,8 +206,7 @@ export default function SubtitlePlayer({
onCopy,
onOffsetChange,
onToggleSubtitleTrack,
onStartedShowing,
onWillStopShowing,
autoPauseContext,
playing,
subtitles,
subtitleCollection,
Expand Down Expand Up @@ -241,7 +240,9 @@ export default function SubtitlePlayer({
: [],
[subtitles]
);
const subtitleCollectionRef = useRef<SubtitleCollection<DisplaySubtitleModel>>(SubtitleCollection.empty<DisplaySubtitleModel>());
const subtitleCollectionRef = useRef<SubtitleCollection<DisplaySubtitleModel>>(
SubtitleCollection.empty<DisplaySubtitleModel>()
);
subtitleCollectionRef.current = subtitleCollection ?? SubtitleCollection.empty<DisplaySubtitleModel>();
const subtitleRefsRef = useRef<RefObject<HTMLTableRowElement>[]>([]);
subtitleRefsRef.current = subtitleRefs;
Expand All @@ -260,12 +261,8 @@ export default function SubtitlePlayer({
drawerOpenRef.current = drawerOpen;
const [windowWidth] = useWindowSize(true);
const classes = useSubtitlePlayerStyles({ compressed, windowWidth, appBarHidden });
const startedShowingSubtitleRef = useRef<SubtitleModel>();
const onStartedShowingRef = useRef<() => void>();
onStartedShowingRef.current = onStartedShowing;
const willStopShowingSubtitleRef = useRef<SubtitleModel>();
const onWillStopShowingRef = useRef<() => void>();
onWillStopShowingRef.current = onWillStopShowing;
const autoPauseContextRef = useRef<AutoPauseContext>();
autoPauseContextRef.current = autoPauseContext;

// This effect should be scheduled only once as re-scheduling seems to cause performance issues.
// Therefore all of the state it operates on is contained in refs.
Expand Down Expand Up @@ -306,20 +303,12 @@ export default function SubtitlePlayer({
}
}

if (startedShowingSubtitleRef.current !== slice.startedShowing) {
if (slice.startedShowing !== undefined) {
onStartedShowingRef.current?.();
}

startedShowingSubtitleRef.current = slice.startedShowing;
if (slice.startedShowing !== undefined) {
autoPauseContextRef.current?.startedShowing(slice.startedShowing);
}

if (willStopShowingSubtitleRef.current !== slice.willStopShowing) {
if (slice.willStopShowing !== undefined) {
onWillStopShowingRef.current?.();
}

willStopShowingSubtitleRef.current = slice.willStopShowing;
if (slice.willStopShowing !== undefined) {
autoPauseContextRef.current?.willStopShowing(slice.willStopShowing);
}

requestAnimationRef.current = requestAnimationFrame(update);
Expand Down
65 changes: 31 additions & 34 deletions client/src/components/VideoPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
AnkiSettings,
SubtitleCollection,
AutoPausePreference,
AutoPauseContext,
} from '@project/common';
import { SubtitleTextImage } from '@project/common/components';
import Clock from '../services/Clock';
Expand Down Expand Up @@ -195,8 +196,6 @@ export default function VideoPlayer({
[subtitles]
);
const [showSubtitles, setShowSubtitles] = useState<IndexedSubtitleModel[]>([]);
const [startedShowingSubtitle, setStartedShowingSubtitle] = useState<IndexedSubtitleModel>();
const [willStopShowingSubtitle, setWillStopShowingSubtitle] = useState<IndexedSubtitleModel>();
const [subtitlesEnabled, setSubtitlesEnabled] = useState(true);
const [disabledSubtitleTracks, setDisabledSubtitleTracks] = useState<{ [index: number]: boolean }>({});
const [playMode, setPlayMode] = useState<PlayMode>(PlayMode.normal);
Expand All @@ -215,6 +214,26 @@ export default function VideoPlayer({
const [alertOpen, setAlertOpen] = useState<boolean>(false);
const [alertMessage, setAlertMessage] = useState<string>('');
const [alertSeverity, setAlertSeverity] = useState<Color>('info');
const autoPauseContext = useMemo(() => {
const context = new AutoPauseContext();
context.onStartedShowing = () => {
if (playMode !== PlayMode.autoPause || miscSettings.autoPausePreference !== AutoPausePreference.atStart) {
return;
}

playerChannel.pause();
};
context.onWillStopShowing = () => {
if (playMode !== PlayMode.autoPause || miscSettings.autoPausePreference !== AutoPausePreference.atEnd) {
return;
}

playerChannel.pause();
};
return context;
}, [playerChannel, miscSettings, playMode]);
const autoPauseContextRef = useRef<AutoPauseContext>();
autoPauseContextRef.current = autoPauseContext;

const keyBinder = useMemo<AppKeyBinder>(
() => new AppKeyBinder(new DefaultKeyBinder(miscSettings.keyBindSet), extension),
Expand Down Expand Up @@ -327,6 +346,7 @@ export default function VideoPlayer({

clock.stop();
clock.setTime(currentTime * 1000);
autoPauseContextRef.current?.clear();
});

playerChannel.onAudioTrackSelected((id) => {
Expand All @@ -348,6 +368,8 @@ export default function VideoPlayer({
const offset = s.start - s.originalStart;
setOffset(offset);
}

autoPauseContextRef.current?.clear();
});

playerChannel.onPlayMode((playMode) => setPlayMode(playMode));
Expand Down Expand Up @@ -441,26 +463,12 @@ export default function VideoPlayer({
}
}

if (playMode === PlayMode.autoPause) {
if (miscSettings.autoPausePreference === AutoPausePreference.atStart) {
if (
slice.startedShowing &&
slice.startedShowing !== startedShowingSubtitle &&
!disabledSubtitleTracks[slice.startedShowing.track]
) {
playerChannel.pause();
setStartedShowingSubtitle(slice.startedShowing);
}
} else {
if (
slice.willStopShowing &&
slice.willStopShowing !== willStopShowingSubtitle &&
!disabledSubtitleTracks[slice.willStopShowing.track]
) {
playerChannel.pause();
setWillStopShowingSubtitle(slice.willStopShowing);
}
}
if (slice.startedShowing && !disabledSubtitleTracks[slice.startedShowing.track]) {
autoPauseContext.startedShowing(slice.startedShowing);
}

if (slice.willStopShowing && !disabledSubtitleTracks[slice.willStopShowing.track]) {
autoPauseContext.willStopShowing(slice.willStopShowing);
}

showSubtitles = showSubtitles.sort((s1, s2) => s1.track - s2.track);
Expand All @@ -471,18 +479,7 @@ export default function VideoPlayer({
}, 100);

return () => clearTimeout(interval);
}, [
subtitleCollection,
playerChannel,
playMode,
subtitles,
disabledSubtitleTracks,
clock,
length,
miscSettings,
startedShowingSubtitle,
willStopShowingSubtitle,
]);
}, [subtitleCollection, playerChannel, subtitles, disabledSubtitleTracks, clock, length, autoPauseContext]);

const handleOffsetChange = useCallback(
(offset: number) => {
Expand Down
1 change: 1 addition & 0 deletions common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export * from './src/Model';
export * from './src/Message';
export * from './src/ExtensionSettings';
export * from './src/SubtitleCollection';
export { default as AutoPauseContext } from './src/AutoPauseContext';
33 changes: 33 additions & 0 deletions common/src/AutoPauseContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { SubtitleModel } from './Model';

export default class AutoPauseContext {
private lastStartedShowing?: SubtitleModel;
private lastWillStopShowing?: SubtitleModel;

onStartedShowing?: () => void;
onWillStopShowing?: () => void;
onNextToShow?: (subtitle: SubtitleModel) => void;

willStopShowing(subtitle: SubtitleModel) {
if (subtitle.end === this.lastWillStopShowing?.end) {
return;
}

this.onWillStopShowing?.();
this.lastWillStopShowing = subtitle;
}

startedShowing(subtitle: SubtitleModel) {
if (subtitle.start === this.lastStartedShowing?.start) {
return;
}

this.onStartedShowing?.();
this.lastStartedShowing = subtitle;
}

clear() {
this.lastStartedShowing = undefined;
this.lastWillStopShowing = undefined;
}
}
10 changes: 6 additions & 4 deletions extension/src/services/Binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ export default class Binding {
set playMode(newPlayMode: PlayMode) {
switch (newPlayMode) {
case PlayMode.autoPause:
this.subtitleContainer.onStartedShowing = () => {
this.subtitleContainer.autoPauseContext.onStartedShowing = () => {
if (this.recordingMedia || this.autoPausePreference !== AutoPausePreference.atStart) {
return;
}

this.pause();
};
this.subtitleContainer.onWillStopShowing = () => {
this.subtitleContainer.autoPauseContext.onWillStopShowing = () => {
if (this.recordingMedia || this.autoPausePreference !== AutoPausePreference.atEnd) {
return;
}
Expand Down Expand Up @@ -170,8 +170,8 @@ export default class Binding {
break;
case PlayMode.normal:
if (this._playMode === PlayMode.autoPause) {
this.subtitleContainer.onStartedShowing = undefined;
this.subtitleContainer.onWillStopShowing = undefined;
this.subtitleContainer.autoPauseContext.onStartedShowing = undefined;
this.subtitleContainer.autoPauseContext.onWillStopShowing = undefined;
this.subtitleContainer.notification('Auto-pause: Off');
} else if (this._playMode === PlayMode.condensed) {
this.subtitleContainer.onNextToShow = undefined;
Expand Down Expand Up @@ -285,6 +285,8 @@ export default class Binding {
};

chrome.runtime.sendMessage(command);

this.subtitleContainer.autoPauseContext.clear();
};

this.playbackRateListener = (event) => {
Expand Down
Loading

0 comments on commit 3e71795

Please sign in to comment.