mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 17:15:48 +00:00
Merge pull request #1115 from Stremio/feat/player-remember-selected-tracks
Some checks are pending
Build / build (push) Waiting to run
Some checks are pending
Build / build (push) Waiting to run
Player: Remember selected tracks
This commit is contained in:
commit
cd111942a5
3 changed files with 79 additions and 19 deletions
|
|
@ -29,6 +29,9 @@ const styles = require('./styles');
|
||||||
const Video = require('./Video');
|
const Video = require('./Video');
|
||||||
const { default: Indicator } = require('./Indicator/Indicator');
|
const { default: Indicator } = require('./Indicator/Indicator');
|
||||||
|
|
||||||
|
const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang);
|
||||||
|
const findTrackById = (tracks, id) => tracks.find((track) => track.id === id);
|
||||||
|
|
||||||
const Player = ({ urlParams, queryParams }) => {
|
const Player = ({ urlParams, queryParams }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const services = useServices();
|
const services = useServices();
|
||||||
|
|
@ -37,7 +40,7 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
return queryParams.has('forceTranscoding');
|
return queryParams.has('forceTranscoding');
|
||||||
}, [queryParams]);
|
}, [queryParams]);
|
||||||
const profile = useProfile();
|
const profile = useProfile();
|
||||||
const [player, videoParamsChanged, timeChanged, seek, pausedChanged, ended, nextVideo] = usePlayer(urlParams);
|
const [player, videoParamsChanged, streamStateChanged, timeChanged, seek, pausedChanged, ended, nextVideo] = usePlayer(urlParams);
|
||||||
const [settings, updateSettings] = useSettings();
|
const [settings, updateSettings] = useSettings();
|
||||||
const streamingServer = useStreamingServer();
|
const streamingServer = useStreamingServer();
|
||||||
const statistics = useStatistics(player, streamingServer);
|
const statistics = useStatistics(player, streamingServer);
|
||||||
|
|
@ -224,15 +227,32 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
|
|
||||||
const onSubtitlesTrackSelected = React.useCallback((id) => {
|
const onSubtitlesTrackSelected = React.useCallback((id) => {
|
||||||
video.setSubtitlesTrack(id);
|
video.setSubtitlesTrack(id);
|
||||||
}, []);
|
streamStateChanged({
|
||||||
|
subtitleTrack: {
|
||||||
|
id,
|
||||||
|
embedded: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [streamStateChanged]);
|
||||||
|
|
||||||
const onExtraSubtitlesTrackSelected = React.useCallback((id) => {
|
const onExtraSubtitlesTrackSelected = React.useCallback((id) => {
|
||||||
video.setExtraSubtitlesTrack(id);
|
video.setExtraSubtitlesTrack(id);
|
||||||
}, []);
|
streamStateChanged({
|
||||||
|
subtitleTrack: {
|
||||||
|
id,
|
||||||
|
embedded: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [streamStateChanged]);
|
||||||
|
|
||||||
const onAudioTrackSelected = React.useCallback((id) => {
|
const onAudioTrackSelected = React.useCallback((id) => {
|
||||||
video.setProp('selectedAudioTrackId', id);
|
video.setProp('selectedAudioTrackId', id);
|
||||||
}, []);
|
streamStateChanged({
|
||||||
|
audioTrack: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [streamStateChanged]);
|
||||||
|
|
||||||
const onExtraSubtitlesDelayChanged = React.useCallback((delay) => {
|
const onExtraSubtitlesDelayChanged = React.useCallback((delay) => {
|
||||||
video.setProp('extraSubtitlesDelay', delay);
|
video.setProp('extraSubtitlesDelay', delay);
|
||||||
|
|
@ -444,41 +464,49 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
}
|
}
|
||||||
}, [player.nextVideo, video.state.time, video.state.duration]);
|
}, [player.nextVideo, video.state.time, video.state.duration]);
|
||||||
|
|
||||||
|
// Auto subtitles track selection
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!defaultSubtitlesSelected.current) {
|
if (!defaultSubtitlesSelected.current) {
|
||||||
const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang);
|
|
||||||
|
|
||||||
if (settings.subtitlesLanguage === null) {
|
if (settings.subtitlesLanguage === null) {
|
||||||
onSubtitlesTrackSelected(null);
|
video.setSubtitlesTrack(null);
|
||||||
onExtraSubtitlesTrackSelected(null);
|
video.setExtraSubtitlesTrack(null);
|
||||||
defaultSubtitlesSelected.current = true;
|
defaultSubtitlesSelected.current = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const subtitlesTrack = findTrackByLang(video.state.subtitlesTracks, settings.subtitlesLanguage);
|
const savedTrackId = player.streamState?.subtitleTrack?.id;
|
||||||
const extraSubtitlesTrack = findTrackByLang(video.state.extraSubtitlesTracks, settings.subtitlesLanguage);
|
const subtitlesTrack = savedTrackId ?
|
||||||
|
findTrackById(video.state.subtitlesTracks, savedTrackId) :
|
||||||
|
findTrackByLang(video.state.subtitlesTracks, settings.subtitlesLanguage);
|
||||||
|
|
||||||
|
const extraSubtitlesTrack = savedTrackId ?
|
||||||
|
findTrackById(video.state.extraSubtitlesTracks, savedTrackId) :
|
||||||
|
findTrackByLang(video.state.extraSubtitlesTracks, settings.subtitlesLanguage);
|
||||||
|
|
||||||
if (subtitlesTrack && subtitlesTrack.id) {
|
if (subtitlesTrack && subtitlesTrack.id) {
|
||||||
onSubtitlesTrackSelected(subtitlesTrack.id);
|
video.setSubtitlesTrack(subtitlesTrack.id);
|
||||||
defaultSubtitlesSelected.current = true;
|
defaultSubtitlesSelected.current = true;
|
||||||
} else if (extraSubtitlesTrack && extraSubtitlesTrack.id) {
|
} else if (extraSubtitlesTrack && extraSubtitlesTrack.id) {
|
||||||
onExtraSubtitlesTrackSelected(extraSubtitlesTrack.id);
|
video.setExtraSubtitlesTrack(extraSubtitlesTrack.id);
|
||||||
defaultSubtitlesSelected.current = true;
|
defaultSubtitlesSelected.current = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [video.state.subtitlesTracks, video.state.extraSubtitlesTracks]);
|
}, [video.state.subtitlesTracks, video.state.extraSubtitlesTracks, player.streamState]);
|
||||||
|
|
||||||
|
// Auto audio track selection
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!defaultAudioTrackSelected.current) {
|
if (!defaultAudioTrackSelected.current) {
|
||||||
const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang);
|
const savedTrackId = player.streamState?.audioTrack?.id;
|
||||||
const audioTrack = findTrackByLang(video.state.audioTracks, settings.audioLanguage);
|
const audioTrack = savedTrackId ?
|
||||||
|
findTrackById(video.state.audioTracks, savedTrackId) :
|
||||||
|
findTrackByLang(video.state.audioTracks, settings.audioLanguage);
|
||||||
|
|
||||||
if (audioTrack && audioTrack.id) {
|
if (audioTrack && audioTrack.id) {
|
||||||
onAudioTrackSelected(audioTrack.id);
|
video.setProp('selectedAudioTrackId', audioTrack.id);
|
||||||
defaultAudioTrackSelected.current = true;
|
defaultAudioTrackSelected.current = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [video.state.audioTracks]);
|
}, [video.state.audioTracks, player.streamState]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
defaultSubtitlesSelected.current = false;
|
defaultSubtitlesSelected.current = false;
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,9 @@ const usePlayer = (urlParams) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [urlParams]);
|
}, [urlParams]);
|
||||||
|
|
||||||
|
const player = useModelState({ model: 'player', action, map });
|
||||||
|
|
||||||
const videoParamsChanged = React.useCallback((videoParams) => {
|
const videoParamsChanged = React.useCallback((videoParams) => {
|
||||||
core.transport.dispatch({
|
core.transport.dispatch({
|
||||||
action: 'Player',
|
action: 'Player',
|
||||||
|
|
@ -153,8 +156,22 @@ const usePlayer = (urlParams) => {
|
||||||
}, 'player');
|
}, 'player');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const player = useModelState({ model: 'player', action, map });
|
const streamStateChanged = React.useCallback((partialStreamState) => {
|
||||||
return [player, videoParamsChanged, timeChanged, seek, pausedChanged, ended, nextVideo];
|
return core.transport.dispatch({
|
||||||
|
action: 'Player',
|
||||||
|
args: {
|
||||||
|
action: 'StreamStateChanged',
|
||||||
|
args: {
|
||||||
|
state: {
|
||||||
|
...player.streamState,
|
||||||
|
...partialStreamState,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, 'player');
|
||||||
|
}, [player.streamState]);
|
||||||
|
|
||||||
|
return [player, videoParamsChanged, streamStateChanged, timeChanged, seek, pausedChanged, ended, nextVideo];
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = usePlayer;
|
module.exports = usePlayer;
|
||||||
|
|
|
||||||
15
src/types/models/Player.d.ts
vendored
15
src/types/models/Player.d.ts
vendored
|
|
@ -30,6 +30,20 @@ type SeriesInfo = {
|
||||||
season: number,
|
season: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type SubtitlesTrackState = {
|
||||||
|
id: string,
|
||||||
|
embedded: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
type AudioTrackState = {
|
||||||
|
id: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type StreamState = {
|
||||||
|
subtitleTrack?: SubtitlesTrackState,
|
||||||
|
audioTrack?: AudioTrackState,
|
||||||
|
};
|
||||||
|
|
||||||
type Player = {
|
type Player = {
|
||||||
addon: Addon | null,
|
addon: Addon | null,
|
||||||
libraryItem: LibraryItemPlayer | null,
|
libraryItem: LibraryItemPlayer | null,
|
||||||
|
|
@ -42,6 +56,7 @@ type Player = {
|
||||||
subtitlesPath: ResourceRequestPath,
|
subtitlesPath: ResourceRequestPath,
|
||||||
} | null,
|
} | null,
|
||||||
seriesInfo: SeriesInfo | null,
|
seriesInfo: SeriesInfo | null,
|
||||||
|
streamState: StreamState | null,
|
||||||
subtitles: Subtitle[],
|
subtitles: Subtitle[],
|
||||||
title: string | null,
|
title: string | null,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue