diff --git a/src/routes/Player/Buffering/Buffering.less b/src/routes/Player/Buffering/Buffering.less new file mode 100644 index 000000000..1c778635b --- /dev/null +++ b/src/routes/Player/Buffering/Buffering.less @@ -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); + } +} diff --git a/src/routes/Player/Buffering/Buffering.tsx b/src/routes/Player/Buffering/Buffering.tsx new file mode 100644 index 000000000..6c957156f --- /dev/null +++ b/src/routes/Player/Buffering/Buffering.tsx @@ -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(({ className, logo, progress }, ref) => { + const style = useMemo(() => { + return { + clipPath: `inset(0 ${100 - progress}% 0 0)`, + }; + }, [progress]); + + return ( +
+ {' + {' +
+ ); +}); + +export default Buffering; diff --git a/src/routes/Player/Buffering/index.ts b/src/routes/Player/Buffering/index.ts new file mode 100644 index 000000000..4c015e6ba --- /dev/null +++ b/src/routes/Player/Buffering/index.ts @@ -0,0 +1,2 @@ +import Buffering from './Buffering'; +export default Buffering; diff --git a/src/routes/Player/BufferingLoader/BufferingLoader.js b/src/routes/Player/BufferingLoader/BufferingLoader.js deleted file mode 100644 index a762506f4..000000000 --- a/src/routes/Player/BufferingLoader/BufferingLoader.js +++ /dev/null @@ -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 ( -
- {' -
- ); -}); - -BufferingLoader.propTypes = { - className: PropTypes.string, - logo: PropTypes.string, -}; - -module.exports = BufferingLoader; diff --git a/src/routes/Player/BufferingLoader/index.js b/src/routes/Player/BufferingLoader/index.js deleted file mode 100644 index a2371d763..000000000 --- a/src/routes/Player/BufferingLoader/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (C) 2017-2023 Smart code 203358507 - -const BufferingLoader = require('./BufferingLoader'); - -module.exports = BufferingLoader; diff --git a/src/routes/Player/BufferingLoader/styles.less b/src/routes/Player/BufferingLoader/styles.less deleted file mode 100644 index 68bc83ff3..000000000 --- a/src/routes/Player/BufferingLoader/styles.less +++ /dev/null @@ -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; } -} diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 20b5f0ce8..67baeceb2 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -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 ? - : null diff --git a/src/routes/Player/useStatistics.js b/src/routes/Player/useStatistics.js index 682969181..5327b90ae 100644 --- a/src/routes/Player/useStatistics.js +++ b/src/routes/Player/useStatistics.js @@ -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, }; };