mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-24 04:22:12 +00:00
feat(player): add buffering indicator for torrents
This commit is contained in:
parent
01384cbc83
commit
b74e6e94c4
8 changed files with 100 additions and 59 deletions
36
src/routes/Player/Buffering/Buffering.less
Normal file
36
src/routes/Player/Buffering/Buffering.less
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
.buffering {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.logo {
|
||||
position: absolute;
|
||||
display: block;
|
||||
max-width: 15rem;
|
||||
max-height: 15rem;
|
||||
width: auto;
|
||||
height: auto;
|
||||
animation: pulse 2s infinite;
|
||||
transition: clip-path 0.1s ease-in-out;
|
||||
|
||||
&.background {
|
||||
opacity: 0.2 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
opacity: 0.4;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.4;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
38
src/routes/Player/Buffering/Buffering.tsx
Normal file
38
src/routes/Player/Buffering/Buffering.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import React, { forwardRef, useMemo } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Image } from 'stremio/components';
|
||||
import styles from './Buffering.less';
|
||||
|
||||
type Props = {
|
||||
className: string,
|
||||
logo: string,
|
||||
progress: number,
|
||||
};
|
||||
|
||||
const Buffering = forwardRef<HTMLDivElement, Props>(({ className, logo, progress }, ref) => {
|
||||
const style = useMemo(() => {
|
||||
return {
|
||||
clipPath: `inset(0 ${100 - progress}% 0 0)`,
|
||||
};
|
||||
}, [progress]);
|
||||
|
||||
return (
|
||||
<div ref={ref} className={classNames(className, styles['buffering'])}>
|
||||
<Image
|
||||
className={styles['logo']}
|
||||
style={style}
|
||||
src={logo}
|
||||
alt={' '}
|
||||
fallbackSrc={require('/assets/images/stremio_symbol.png')}
|
||||
/>
|
||||
<Image
|
||||
className={classNames(styles['logo'], styles['background'])}
|
||||
src={logo}
|
||||
alt={' '}
|
||||
fallbackSrc={require('/assets/images/stremio_symbol.png')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Buffering;
|
||||
2
src/routes/Player/Buffering/index.ts
Normal file
2
src/routes/Player/Buffering/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import Buffering from './Buffering';
|
||||
export default Buffering;
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const { Image } = require('stremio/components');
|
||||
const styles = require('./styles');
|
||||
|
||||
const BufferingLoader = React.forwardRef(({ className, logo }, ref) => {
|
||||
return (
|
||||
<div ref={ref} className={classnames(className, styles['buffering-loader-container'])}>
|
||||
<Image
|
||||
className={styles['buffering-loader']}
|
||||
src={logo}
|
||||
alt={' '}
|
||||
fallbackSrc={require('/assets/images/stremio_symbol.png')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
BufferingLoader.propTypes = {
|
||||
className: PropTypes.string,
|
||||
logo: PropTypes.string,
|
||||
};
|
||||
|
||||
module.exports = BufferingLoader;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
const BufferingLoader = require('./BufferingLoader');
|
||||
|
||||
module.exports = BufferingLoader;
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright (C) 2017-2023 Smart code 203358507
|
||||
|
||||
.buffering-loader-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.buffering-loader {
|
||||
flex: none;
|
||||
max-width: 15rem;
|
||||
max-height: 15rem;
|
||||
animation: fadeInOut 2s infinite;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0% { opacity: 0.2; }
|
||||
50% { opacity: 1; }
|
||||
100% { opacity: 0.2; }
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ const { useServices, useGamepad } = require('stremio/services');
|
|||
const { useContentGamepadNavigation } = require('stremio/services/GamepadNavigation');
|
||||
const { useSettings, useProfile, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, usePlatform, onShortcut } = require('stremio/common');
|
||||
const { HorizontalNavBar, Transition, ContextMenu } = require('stremio/components');
|
||||
const BufferingLoader = require('./BufferingLoader');
|
||||
const { default: Buffering } = require('./Buffering');
|
||||
const VolumeChangeIndicator = require('./VolumeChangeIndicator');
|
||||
const Error = require('./Error');
|
||||
const ControlBar = require('./ControlBar');
|
||||
|
|
@ -792,10 +792,11 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
}
|
||||
{
|
||||
(video.state.buffering || !video.state.loaded) && !error ?
|
||||
<BufferingLoader
|
||||
<Buffering
|
||||
ref={bufferingRef}
|
||||
className={classnames(styles['layer'], styles['buffering-layer'])}
|
||||
logo={player?.metaItem?.content?.logo}
|
||||
progress={statistics.progress}
|
||||
/>
|
||||
:
|
||||
null
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ const { useCore } = require('stremio/core');
|
|||
const useStatistics = (player, streamingServer) => {
|
||||
const core = useCore();
|
||||
|
||||
const [progress, setProgress] = React.useState(0);
|
||||
|
||||
const stream = React.useMemo(() => {
|
||||
if (player.stream?.type === 'Ready') {
|
||||
return player.stream.content;
|
||||
|
|
@ -49,6 +51,20 @@ const useStatistics = (player, streamingServer) => {
|
|||
0;
|
||||
}, [statistics]);
|
||||
|
||||
React.useEffect(() => {
|
||||
statistics && setProgress(() => {
|
||||
const MB = 1024 * 1024;
|
||||
const peerScore = Math.min(1, statistics.peers / 8) * 20;
|
||||
|
||||
const minDownload = Math.min(8 * MB, Math.max(2 * MB, statistics.streamLen * 0.008));
|
||||
const downloadedScore = Math.min(1, statistics.downloaded / minDownload) * 70;
|
||||
|
||||
const speedCore = Math.min(1, statistics.downloadSpeed / (1 * MB)) * 10;
|
||||
|
||||
return Math.min(99, peerScore + downloadedScore + speedCore);
|
||||
});
|
||||
}, [statistics]);
|
||||
|
||||
const getStatistics = React.useCallback(() => {
|
||||
if (stream) {
|
||||
const { infoHash, fileIdx } = stream;
|
||||
|
|
@ -73,11 +89,16 @@ const useStatistics = (player, streamingServer) => {
|
|||
return () => clearInterval(interval);
|
||||
}, [getStatistics]);
|
||||
|
||||
React.useEffect(() => {
|
||||
setProgress(infoHash ? 0 : 100);
|
||||
}, [infoHash]);
|
||||
|
||||
return {
|
||||
infoHash,
|
||||
peers,
|
||||
speed,
|
||||
completed,
|
||||
progress,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue