diff --git a/package.json b/package.json
index 87886609b..1cd112fea 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"@stremio/stremio-colors": "5.2.0",
"@stremio/stremio-core-web": "0.56.4",
"@stremio/stremio-icons": "5.10.0",
- "@stremio/stremio-video": "0.0.76",
+ "@stremio/stremio-video": "0.0.77",
"a-color-picker": "1.2.1",
"bowser": "2.11.0",
"buffer": "6.0.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c55322654..4ff70efdc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -24,8 +24,8 @@ importers:
specifier: 5.10.0
version: 5.10.0
'@stremio/stremio-video':
- specifier: 0.0.76
- version: 0.0.76
+ specifier: 0.0.77
+ version: 0.0.77
a-color-picker:
specifier: 1.2.1
version: 1.2.1
@@ -1126,8 +1126,8 @@ packages:
'@stremio/stremio-icons@5.10.0':
resolution: {integrity: sha512-Zw/vGC3D2yeQfk8xv/tfMJTDvbCPOI91tBg4XpR2+EgbZSX8Xvm7Vz457PIhFPhTAwdOPHp0VX0M3gzjbt0zOg==}
- '@stremio/stremio-video@0.0.76':
- resolution: {integrity: sha512-q/mCnp4mBReWbtreyeYAf0wD8z+jL4wA5GdkOLPY8o5OPZPUv9Qa9p3FNkK3CMVWf3TP1FzeNj3KYKqUVf5/2Q==}
+ '@stremio/stremio-video@0.0.77':
+ resolution: {integrity: sha512-bnKBS5a9R3+M0zx95YpDUiPs1gXcKCsybgdxfZmpWuQaN0RE9bTBAUlIfBSrcEjVhufMOvg+cfXScT+0fBzTTw==}
'@stylistic/eslint-plugin-jsx@4.4.1':
resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==}
@@ -5876,7 +5876,7 @@ snapshots:
'@stremio/stremio-icons@5.10.0': {}
- '@stremio/stremio-video@0.0.76':
+ '@stremio/stremio-video@0.0.77':
dependencies:
buffer: 6.0.3
color: 4.2.3
diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js
index e00f66d00..c9ba5cd7e 100644
--- a/src/routes/Player/ControlBar/ControlBar.js
+++ b/src/routes/Player/ControlBar/ControlBar.js
@@ -39,6 +39,9 @@ const ControlBar = React.forwardRef(({
onToggleSpeedMenu,
onToggleSideDrawer,
onToggleOptionsMenu,
+ videoScale,
+ videoScaleLabel,
+ onVideoScaleChanged,
onToggleStatisticsMenu,
onTouchEnd,
...props
@@ -176,6 +179,9 @@ const ControlBar = React.forwardRef(({
:
null
}
+
@@ -194,6 +200,9 @@ ControlBar.propTypes = {
volume: PropTypes.number,
muted: PropTypes.bool,
playbackSpeed: PropTypes.number,
+ videoScale: PropTypes.string,
+ videoScaleLabel: PropTypes.string,
+ onVideoScaleChanged: PropTypes.func,
subtitlesTracks: PropTypes.array,
audioTracks: PropTypes.array,
metaItem: PropTypes.object,
diff --git a/src/routes/Player/Indicator/Indicator.tsx b/src/routes/Player/Indicator/Indicator.tsx
index 7525fe1cd..b9290ad64 100644
--- a/src/routes/Player/Indicator/Indicator.tsx
+++ b/src/routes/Player/Indicator/Indicator.tsx
@@ -7,7 +7,13 @@ import styles from './Indicator.less';
type Property = {
label: string,
- format: (value: number) => string,
+ format: (value: number | string) => string,
+};
+
+const VIDEO_SCALE_LABELS: Record = {
+ 'contain': 'Fit',
+ 'cover': 'Crop',
+ 'fill': 'Stretch',
};
const PROPERTIES: Record = {
@@ -15,9 +21,13 @@ const PROPERTIES: Record = {
label: 'SUBTITLES_DELAY',
format: (value) => `${(value / 1000).toFixed(2)}s`,
},
+ 'videoScale': {
+ label: 'VIDEO_SCALE',
+ format: (value) => VIDEO_SCALE_LABELS[String(value)] || String(value),
+ },
};
-type VideoState = Record;
+type VideoState = Record;
type Props = {
className: string,
diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js
index c31272398..2ef6db67a 100644
--- a/src/routes/Player/Player.js
+++ b/src/routes/Player/Player.js
@@ -98,6 +98,9 @@ const Player = ({ urlParams, queryParams }) => {
const isNavigating = React.useRef(false);
+ const VIDEO_SCALES = ['contain', 'cover', 'fill'];
+ const VIDEO_SCALE_LABELS = { contain: 'Fit', cover: 'Crop', fill: 'Stretch' };
+
const playbackSpeed = React.useRef(video.state.playbackSpeed || 1);
const pressTimer = React.useRef(null);
const longPress = React.useRef(false);
@@ -236,6 +239,13 @@ const Player = ({ urlParams, queryParams }) => {
}, []);
+ const onVideoScaleChanged = React.useCallback(() => {
+ const currentScale = video.state.videoScale || 'contain';
+ const currentIndex = VIDEO_SCALES.indexOf(currentScale);
+ const nextScale = VIDEO_SCALES[(currentIndex + 1) % VIDEO_SCALES.length];
+ video.setVideoScale(nextScale);
+ }, [video.state.videoScale]);
+
const onSubtitlesTrackSelected = React.useCallback((track) => {
video.setSubtitlesTrack(track?.id ?? null);
streamStateChanged({
@@ -956,6 +966,9 @@ const Player = ({ urlParams, queryParams }) => {
onToggleSubtitlesMenu={toggleSubtitlesMenu}
onToggleAudioMenu={toggleAudioMenu}
onToggleSpeedMenu={toggleSpeedMenu}
+ videoScale={video.state.videoScale}
+ videoScaleLabel={VIDEO_SCALE_LABELS[video.state.videoScale || 'contain']}
+ onVideoScaleChanged={onVideoScaleChanged}
onToggleStatisticsMenu={toggleStatisticsMenu}
onToggleSideDrawer={toggleSideDrawer}
onMouseMove={onBarMouseMove}
diff --git a/src/routes/Player/useVideo.js b/src/routes/Player/useVideo.js
index bfa8ddf94..241a5af00 100644
--- a/src/routes/Player/useVideo.js
+++ b/src/routes/Player/useVideo.js
@@ -143,6 +143,10 @@ const useVideo = () => {
setProp('extraSubtitlesOffset', offset);
};
+ const setVideoScale = (scale) => {
+ setProp('videoScale', scale);
+ };
+
const setSubtitlesTextColor = (color) => {
setProp('subtitlesTextColor', color);
setProp('extraSubtitlesTextColor', color);
@@ -239,6 +243,7 @@ const useVideo = () => {
setSubtitlesBackgroundColor,
setSubtitlesOutlineColor,
setExtraSubtitlesTrack,
+ setVideoScale,
};
};