mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-17 10:03:17 +00:00
Merge pull request #1220 from Stremio/feat/player-add-video-scale-property
Player: Add video scale property
This commit is contained in:
commit
67ddc6228b
6 changed files with 45 additions and 8 deletions
|
|
@ -19,7 +19,7 @@
|
||||||
"@stremio/stremio-colors": "5.2.0",
|
"@stremio/stremio-colors": "5.2.0",
|
||||||
"@stremio/stremio-core-web": "0.56.4",
|
"@stremio/stremio-core-web": "0.56.4",
|
||||||
"@stremio/stremio-icons": "5.10.0",
|
"@stremio/stremio-icons": "5.10.0",
|
||||||
"@stremio/stremio-video": "0.0.76",
|
"@stremio/stremio-video": "0.0.77",
|
||||||
"a-color-picker": "1.2.1",
|
"a-color-picker": "1.2.1",
|
||||||
"bowser": "2.11.0",
|
"bowser": "2.11.0",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ importers:
|
||||||
specifier: 5.10.0
|
specifier: 5.10.0
|
||||||
version: 5.10.0
|
version: 5.10.0
|
||||||
'@stremio/stremio-video':
|
'@stremio/stremio-video':
|
||||||
specifier: 0.0.76
|
specifier: 0.0.77
|
||||||
version: 0.0.76
|
version: 0.0.77
|
||||||
a-color-picker:
|
a-color-picker:
|
||||||
specifier: 1.2.1
|
specifier: 1.2.1
|
||||||
version: 1.2.1
|
version: 1.2.1
|
||||||
|
|
@ -1126,8 +1126,8 @@ packages:
|
||||||
'@stremio/stremio-icons@5.10.0':
|
'@stremio/stremio-icons@5.10.0':
|
||||||
resolution: {integrity: sha512-Zw/vGC3D2yeQfk8xv/tfMJTDvbCPOI91tBg4XpR2+EgbZSX8Xvm7Vz457PIhFPhTAwdOPHp0VX0M3gzjbt0zOg==}
|
resolution: {integrity: sha512-Zw/vGC3D2yeQfk8xv/tfMJTDvbCPOI91tBg4XpR2+EgbZSX8Xvm7Vz457PIhFPhTAwdOPHp0VX0M3gzjbt0zOg==}
|
||||||
|
|
||||||
'@stremio/stremio-video@0.0.76':
|
'@stremio/stremio-video@0.0.77':
|
||||||
resolution: {integrity: sha512-q/mCnp4mBReWbtreyeYAf0wD8z+jL4wA5GdkOLPY8o5OPZPUv9Qa9p3FNkK3CMVWf3TP1FzeNj3KYKqUVf5/2Q==}
|
resolution: {integrity: sha512-bnKBS5a9R3+M0zx95YpDUiPs1gXcKCsybgdxfZmpWuQaN0RE9bTBAUlIfBSrcEjVhufMOvg+cfXScT+0fBzTTw==}
|
||||||
|
|
||||||
'@stylistic/eslint-plugin-jsx@4.4.1':
|
'@stylistic/eslint-plugin-jsx@4.4.1':
|
||||||
resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==}
|
resolution: {integrity: sha512-83SInq4u7z71vWwGG+6ViOtlOmZ6tSrDkMPhrvdBBTGMLA0gs22WSdhQ4vZP3oJ5Xg4ythvqeUiFSedvVxzhyA==}
|
||||||
|
|
@ -5876,7 +5876,7 @@ snapshots:
|
||||||
|
|
||||||
'@stremio/stremio-icons@5.10.0': {}
|
'@stremio/stremio-icons@5.10.0': {}
|
||||||
|
|
||||||
'@stremio/stremio-video@0.0.76':
|
'@stremio/stremio-video@0.0.77':
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer: 6.0.3
|
buffer: 6.0.3
|
||||||
color: 4.2.3
|
color: 4.2.3
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ const ControlBar = React.forwardRef(({
|
||||||
onToggleSpeedMenu,
|
onToggleSpeedMenu,
|
||||||
onToggleSideDrawer,
|
onToggleSideDrawer,
|
||||||
onToggleOptionsMenu,
|
onToggleOptionsMenu,
|
||||||
|
videoScale,
|
||||||
|
videoScaleLabel,
|
||||||
|
onVideoScaleChanged,
|
||||||
onToggleStatisticsMenu,
|
onToggleStatisticsMenu,
|
||||||
onTouchEnd,
|
onTouchEnd,
|
||||||
...props
|
...props
|
||||||
|
|
@ -176,6 +179,9 @@ const ControlBar = React.forwardRef(({
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
<Button className={classnames(styles['control-bar-button'], { 'disabled': videoScale === null })} title={videoScaleLabel} tabIndex={-1} onClick={onVideoScaleChanged}>
|
||||||
|
<Icon className={styles['icon']} name={'scale'} />
|
||||||
|
</Button>
|
||||||
<Button className={classnames(styles['control-bar-button'], { 'disabled': !stream })} tabIndex={-1} onMouseDown={onOptionsButtonMouseDown} onClick={onToggleOptionsMenu}>
|
<Button className={classnames(styles['control-bar-button'], { 'disabled': !stream })} tabIndex={-1} onMouseDown={onOptionsButtonMouseDown} onClick={onToggleOptionsMenu}>
|
||||||
<Icon className={styles['icon']} name={'more-horizontal'} />
|
<Icon className={styles['icon']} name={'more-horizontal'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -194,6 +200,9 @@ ControlBar.propTypes = {
|
||||||
volume: PropTypes.number,
|
volume: PropTypes.number,
|
||||||
muted: PropTypes.bool,
|
muted: PropTypes.bool,
|
||||||
playbackSpeed: PropTypes.number,
|
playbackSpeed: PropTypes.number,
|
||||||
|
videoScale: PropTypes.string,
|
||||||
|
videoScaleLabel: PropTypes.string,
|
||||||
|
onVideoScaleChanged: PropTypes.func,
|
||||||
subtitlesTracks: PropTypes.array,
|
subtitlesTracks: PropTypes.array,
|
||||||
audioTracks: PropTypes.array,
|
audioTracks: PropTypes.array,
|
||||||
metaItem: PropTypes.object,
|
metaItem: PropTypes.object,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,13 @@ import styles from './Indicator.less';
|
||||||
|
|
||||||
type Property = {
|
type Property = {
|
||||||
label: string,
|
label: string,
|
||||||
format: (value: number) => string,
|
format: (value: number | string) => string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const VIDEO_SCALE_LABELS: Record<string, string> = {
|
||||||
|
'contain': 'Fit',
|
||||||
|
'cover': 'Crop',
|
||||||
|
'fill': 'Stretch',
|
||||||
};
|
};
|
||||||
|
|
||||||
const PROPERTIES: Record<string, Property> = {
|
const PROPERTIES: Record<string, Property> = {
|
||||||
|
|
@ -15,9 +21,13 @@ const PROPERTIES: Record<string, Property> = {
|
||||||
label: 'SUBTITLES_DELAY',
|
label: 'SUBTITLES_DELAY',
|
||||||
format: (value) => `${(value / 1000).toFixed(2)}s`,
|
format: (value) => `${(value / 1000).toFixed(2)}s`,
|
||||||
},
|
},
|
||||||
|
'videoScale': {
|
||||||
|
label: 'VIDEO_SCALE',
|
||||||
|
format: (value) => VIDEO_SCALE_LABELS[String(value)] || String(value),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type VideoState = Record<string, number>;
|
type VideoState = Record<string, number | string>;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
className: string,
|
className: string,
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
|
|
||||||
const isNavigating = React.useRef(false);
|
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 playbackSpeed = React.useRef(video.state.playbackSpeed || 1);
|
||||||
const pressTimer = React.useRef(null);
|
const pressTimer = React.useRef(null);
|
||||||
const longPress = React.useRef(false);
|
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) => {
|
const onSubtitlesTrackSelected = React.useCallback((track) => {
|
||||||
video.setSubtitlesTrack(track?.id ?? null);
|
video.setSubtitlesTrack(track?.id ?? null);
|
||||||
streamStateChanged({
|
streamStateChanged({
|
||||||
|
|
@ -956,6 +966,9 @@ const Player = ({ urlParams, queryParams }) => {
|
||||||
onToggleSubtitlesMenu={toggleSubtitlesMenu}
|
onToggleSubtitlesMenu={toggleSubtitlesMenu}
|
||||||
onToggleAudioMenu={toggleAudioMenu}
|
onToggleAudioMenu={toggleAudioMenu}
|
||||||
onToggleSpeedMenu={toggleSpeedMenu}
|
onToggleSpeedMenu={toggleSpeedMenu}
|
||||||
|
videoScale={video.state.videoScale}
|
||||||
|
videoScaleLabel={VIDEO_SCALE_LABELS[video.state.videoScale || 'contain']}
|
||||||
|
onVideoScaleChanged={onVideoScaleChanged}
|
||||||
onToggleStatisticsMenu={toggleStatisticsMenu}
|
onToggleStatisticsMenu={toggleStatisticsMenu}
|
||||||
onToggleSideDrawer={toggleSideDrawer}
|
onToggleSideDrawer={toggleSideDrawer}
|
||||||
onMouseMove={onBarMouseMove}
|
onMouseMove={onBarMouseMove}
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,10 @@ const useVideo = () => {
|
||||||
setProp('extraSubtitlesOffset', offset);
|
setProp('extraSubtitlesOffset', offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setVideoScale = (scale) => {
|
||||||
|
setProp('videoScale', scale);
|
||||||
|
};
|
||||||
|
|
||||||
const setSubtitlesTextColor = (color) => {
|
const setSubtitlesTextColor = (color) => {
|
||||||
setProp('subtitlesTextColor', color);
|
setProp('subtitlesTextColor', color);
|
||||||
setProp('extraSubtitlesTextColor', color);
|
setProp('extraSubtitlesTextColor', color);
|
||||||
|
|
@ -239,6 +243,7 @@ const useVideo = () => {
|
||||||
setSubtitlesBackgroundColor,
|
setSubtitlesBackgroundColor,
|
||||||
setSubtitlesOutlineColor,
|
setSubtitlesOutlineColor,
|
||||||
setExtraSubtitlesTrack,
|
setExtraSubtitlesTrack,
|
||||||
|
setVideoScale,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue