+
+ {description}
+
{
streamLink &&
}
diff --git a/src/routes/MetaDetails/StreamsList/Stream/styles.less b/src/routes/MetaDetails/StreamsList/Stream/styles.less
index 0461c77ee..06720a879 100644
--- a/src/routes/MetaDetails/StreamsList/Stream/styles.less
+++ b/src/routes/MetaDetails/StreamsList/Stream/styles.less
@@ -111,12 +111,29 @@
background-color: var(--secondary-accent-color);
}
+ .menu-icon {
+ flex: none;
+ width: 1.7rem;
+ height: 1.7rem;
+ margin-right: 1rem;
+ color: var(--color-placeholder);
+ }
+
.context-menu-container {
max-width: calc(90% - 1.5rem);
z-index: 2;
.context-menu-content {
--spatial-navigation-contain: contain;
+
+ .context-menu-title {
+ font-size: 0.9rem;
+ padding: 1rem 1.5rem;
+ font-weight: 100;
+ border-bottom: 1px solid var(--color-placeholder);
+ color: var(--primary-foreground-color);
+ white-space: break-spaces;
+ }
.context-menu-option-container {
display: flex;
@@ -131,8 +148,9 @@
.context-menu-option-label {
font-size: 1rem;
- font-weight: 500;
- color:var(--primary-foreground-color);
+ font-weight: 300;
+ color: var(--primary-foreground-color);
+ text-transform: capitalize;
}
}
}
diff --git a/src/routes/MetaDetails/styles.less b/src/routes/MetaDetails/styles.less
index 3e2fb1602..82740275b 100644
--- a/src/routes/MetaDetails/styles.less
+++ b/src/routes/MetaDetails/styles.less
@@ -52,7 +52,7 @@
flex-direction: row;
margin-top: calc(var(--top-overlay-size) * -1);
padding-top: var(--top-overlay-size);
- padding-bottom: var(--calculated-bottom-safe-inset, 0rem);
+ padding-bottom: var(--safe-area-inset-bottom, 0rem);
.vertical-nav-bar {
flex: none;
}
diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js
index 0fa6de1a4..745e2bd49 100644
--- a/src/routes/Player/ControlBar/ControlBar.js
+++ b/src/routes/Player/ControlBar/ControlBar.js
@@ -138,6 +138,7 @@ const ControlBar = ({
diff --git a/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js b/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js
index 420f4ba41..a65ebfe9c 100644
--- a/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js
+++ b/src/routes/Player/ControlBar/VolumeSlider/VolumeSlider.js
@@ -8,7 +8,7 @@ const { useRouteFocused } = require('stremio-router');
const { Slider } = require('stremio/components');
const styles = require('./styles');
-const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
+const VolumeSlider = ({ className, volume, onVolumeChangeRequested, muted }) => {
const disabled = volume === null || isNaN(volume);
const routeFocused = useRouteFocused();
const [slidingVolume, setSlidingVolume] = React.useState(null);
@@ -45,7 +45,9 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
className={classnames(className, styles['volume-slider'], { 'active': slidingVolume !== null })}
value={
!disabled ?
- slidingVolume !== null ? slidingVolume : volume
+ !muted ?
+ slidingVolume !== null ? slidingVolume : volume
+ : 0
:
100
}
@@ -61,7 +63,8 @@ const VolumeSlider = ({ className, volume, onVolumeChangeRequested }) => {
VolumeSlider.propTypes = {
className: PropTypes.string,
volume: PropTypes.number,
- onVolumeChangeRequested: PropTypes.func
+ onVolumeChangeRequested: PropTypes.func,
+ muted: PropTypes.bool,
};
module.exports = VolumeSlider;
diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js
index c76a8dcae..5ad3aa40b 100644
--- a/src/routes/Player/Player.js
+++ b/src/routes/Player/Player.js
@@ -8,7 +8,7 @@ const langs = require('langs');
const { useTranslation } = require('react-i18next');
const { useRouteFocused } = require('stremio-router');
const { useServices } = require('stremio/services');
-const { useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender } = require('stremio/common');
+const { onFileDrop, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, CONSTANTS } = require('stremio/common');
const { HorizontalNavBar, Transition } = require('stremio/components');
const BufferingLoader = require('./BufferingLoader');
const VolumeChangeIndicator = require('./VolumeChangeIndicator');
@@ -133,11 +133,20 @@ const Player = ({ urlParams, queryParams }) => {
toast.show({
type: 'success',
title: t('PLAYER_SUBTITLES_LOADED'),
- message: track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') : t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }),
+ message:
+ track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') :
+ track.local ? t('PLAYER_SUBTITLES_LOADED_LOCAL') :
+ t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }),
timeout: 3000
});
}, []);
+ const onExtraSubtitlesTrackAdded = React.useCallback((track) => {
+ if (track.local) {
+ video.setExtraSubtitlesTrack(track.id);
+ }
+ }, []);
+
const onPlayRequested = React.useCallback(() => {
video.setProp('paused', false);
setSeeking(false);
@@ -172,13 +181,11 @@ const Player = ({ urlParams, queryParams }) => {
}, []);
const onSubtitlesTrackSelected = React.useCallback((id) => {
- video.setProp('selectedSubtitlesTrackId', id);
- video.setProp('selectedExtraSubtitlesTrackId', null);
+ video.setSubtitlesTrack(id);
}, []);
const onExtraSubtitlesTrackSelected = React.useCallback((id) => {
- video.setProp('selectedSubtitlesTrackId', null);
- video.setProp('selectedExtraSubtitlesTrackId', id);
+ video.setExtraSubtitlesTrack(id);
}, []);
const onAudioTrackSelected = React.useCallback((id) => {
@@ -270,6 +277,10 @@ const Player = ({ urlParams, queryParams }) => {
event.nativeEvent.immersePrevented = true;
}, []);
+ onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (filename, buffer) => {
+ video.addLocalSubtitles(filename, buffer);
+ });
+
React.useEffect(() => {
setError(null);
video.unload();
@@ -296,6 +307,7 @@ const Player = ({ urlParams, queryParams }) => {
0,
forceTranscoding: forceTranscoding || casting,
maxAudioChannels: settings.surroundSound ? 32 : 2,
+ hardwareDecoding: settings.hardwareDecoding,
streamingServerURL: streamingServer.baseUrl ?
casting ?
streamingServer.baseUrl
@@ -303,7 +315,7 @@ const Player = ({ urlParams, queryParams }) => {
streamingServer.selected.transportUrl
:
null,
- seriesInfo: player.seriesInfo
+ seriesInfo: player.seriesInfo,
}, {
chromecastTransport: chromecast.active ? chromecast.transport : null,
shellTransport: shell.active ? shell.transport : null,
@@ -586,6 +598,7 @@ const Player = ({ urlParams, queryParams }) => {
video.events.on('ended', onEnded);
video.events.on('subtitlesTrackLoaded', onSubtitlesTrackLoaded);
video.events.on('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded);
+ video.events.on('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded);
video.events.on('implementationChanged', onImplementationChanged);
return () => {
@@ -593,6 +606,7 @@ const Player = ({ urlParams, queryParams }) => {
video.events.off('ended', onEnded);
video.events.off('subtitlesTrackLoaded', onSubtitlesTrackLoaded);
video.events.off('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded);
+ video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded);
video.events.off('implementationChanged', onImplementationChanged);
};
}, []);
diff --git a/src/routes/Player/SideDrawer/SideDrawer.less b/src/routes/Player/SideDrawer/SideDrawer.less
index be3d0af09..2d2178c3e 100644
--- a/src/routes/Player/SideDrawer/SideDrawer.less
+++ b/src/routes/Player/SideDrawer/SideDrawer.less
@@ -84,7 +84,7 @@
}
}
-@media (orientation: portrait) and (max-width: @xsmall) {
+@media @phone-portrait {
.side-drawer {
max-width: 100dvw;
@@ -94,12 +94,12 @@
}
}
-@media (orientation: landscape) and (max-width: @xsmall) {
+@media @phone-landscape {
.side-drawer {
max-width: 50dvw;
.info {
- max-height: 30dvh;
+ flex: 1;
}
}
}
diff --git a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js
index 44cd20864..b1e15a52f 100644
--- a/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js
+++ b/src/routes/Player/SubtitlesMenu/SubtitlesMenu.js
@@ -10,11 +10,13 @@ const styles = require('./styles');
const { t } = require('i18next');
const ORIGIN_PRIORITIES = {
+ 'LOCAL': 3,
'EMBEDDED': 2,
- 'EXCLUSIVE': 1
+ 'EXCLUSIVE': 1,
};
const LANGUAGE_PRIORITIES = {
- 'eng': 1
+ 'local': 2,
+ 'eng': 1,
};
const SubtitlesMenu = React.memo((props) => {
@@ -161,7 +163,11 @@ const SubtitlesMenu = React.memo((props) => {
{subtitlesLanguages.map((lang, index) => (