添加缓存进度条

This commit is contained in:
lyswhut 2023-12-20 11:49:59 +08:00
parent 27e82baed0
commit 5b682305c1
12 changed files with 125 additions and 40 deletions

View File

@ -10,6 +10,7 @@ import Text from '@/components/common/Text'
import { COMPONENT_IDS } from '@/config/constant'
import { usePageVisible } from '@/store/common/hook'
import { scaleSizeH, scaleSizeW, scaleSizeWR } from '@/utils/pixelRatio'
import { useBufferProgress } from '@/plugins/player'
const FONT_SIZE = 13
const PADDING_TOP_RAW = 1.8
@ -32,6 +33,7 @@ export default ({ isHome }: { isHome: boolean }) => {
const theme = useTheme()
const [autoUpdate, setAutoUpdate] = useState(true)
const { maxPlayTimeStr, nowPlayTimeStr, progress, maxPlayTime } = useProgress(autoUpdate)
const buffered = useBufferProgress()
usePageVisible([COMPONENT_IDS.home], useCallback((visible) => {
if (isHome) setAutoUpdate(visible)
}, [isHome]))
@ -48,7 +50,7 @@ export default ({ isHome }: { isHome: boolean }) => {
<PlayTimeMax timeStr={maxPlayTimeStr} />
</View>
<View style={[StyleSheet.absoluteFill, stylesRaw.progress]}>
<Progress progress={progress} duration={maxPlayTime} paddingTop={PADDING_TOP_PROGRESS} />
<Progress progress={progress} duration={maxPlayTime} buffered={buffered} paddingTop={PADDING_TOP_PROGRESS} />
</View>
</View>
)

View File

@ -20,11 +20,11 @@ const DefaultBar = memo(() => {
}}></View>
})
// const BufferedBar = memo(({ bufferedProgress }) => {
// // console.log(bufferedProgress)
// const theme = useTheme()
// return <View style={{ ...styles.progressBar, backgroundColor: theme.secondary45, position: 'absolute', width: bufferedProgress + '%', left: 0, top: 0 }}></View>
// })
const BufferedBar = memo(({ progress }: { progress: number }) => {
// console.log(bufferedProgress)
const theme = useTheme()
return <View style={{ ...styles.progressBar, backgroundColor: theme['c-primary-light-600-alpha-900'], position: 'absolute', width: `${progress * 100}%`, left: 0, top: 0 }}></View>
})
const PreassBar = memo(({ onDragState, setDragProgress, onSetProgress }: {
onDragState: (drag: boolean) => void
@ -67,9 +67,10 @@ const PreassBar = memo(({ onDragState, setDragProgress, onSetProgress }: {
})
const Progress = ({ progress, duration, paddingTop }: {
const Progress = ({ progress, duration, buffered, paddingTop }: {
progress: number
duration: number
buffered: number
paddingTop?: number
}) => {
// const { progress } = usePlayTimeBuffer()
@ -91,7 +92,7 @@ const Progress = ({ progress, duration, paddingTop }: {
<View style={{ ...styles.progress, paddingTop }}>
<View style={{ flex: 1 }}>
<DefaultBar />
{/* <BufferedBar bufferedProgress={bufferedProgress} /> */}
<BufferedBar progress={buffered} />
{
draging
? (

View File

@ -11,14 +11,14 @@ import { Icon } from '@/components/common/Icon'
const DefaultBar = memo(() => {
const theme = useTheme()
return <View style={{ ...styles.progressBar, backgroundColor: theme['c-primary-light-100-alpha-800'], position: 'absolute', width: '100%', left: 0, top: 0 }}></View>
return <View style={{ ...styles.progressBar, backgroundColor: theme['c-primary-light-300-alpha-800'], position: 'absolute', width: '100%', left: 0, top: 0 }}></View>
})
// const BufferedBar = memo(({ bufferedProgress }) => {
// // console.log(bufferedProgress)
// const theme = useTheme()
// return <View style={{ ...styles.progressBar, backgroundColor: theme.secondary45, position: 'absolute', width: bufferedProgress + '%', left: 0, top: 0 }}></View>
// })
const BufferedBar = memo(({ progress }: { progress: number }) => {
// console.log(bufferedProgress)
const theme = useTheme()
return <View style={{ ...styles.progressBar, backgroundColor: theme['c-primary-light-400-alpha-700'], position: 'absolute', width: `${progress * 100}%`, left: 0, top: 0 }}></View>
})
const PreassBar = memo(({ onDragState, setDragProgress, onSetProgress }: {
@ -62,11 +62,12 @@ const PreassBar = memo(({ onDragState, setDragProgress, onSetProgress }: {
})
const Progress = ({ progress, duration }: {
const Progress = ({ progress, duration, buffered }: {
progress: number
duration: number
buffered: number
}) => {
// const { progress } = usePlayTimeBuffer()
// const { progress: bufferProgress } = usePlayTimeBuffer()
const theme = useTheme()
const [draging, setDraging] = useState(false)
const [dragProgress, setDragProgress] = useState(0)
@ -94,7 +95,7 @@ const Progress = ({ progress, duration }: {
<View style={styles.progress}>
<View>
<DefaultBar />
{/* <BufferedBar bufferedProgress={bufferedProgress} /> */}
<BufferedBar progress={buffered} />
{
draging
? (

View File

@ -111,3 +111,78 @@ export function useProgress(updateInterval: number) {
return state
}
export function useBufferProgress() {
const [progress, setProgress] = useState(0)
useEffect(() => {
let isUnmounted = false
let preBuffered = 0
let duration = 0
let interval: NodeJS.Timer | null = null
const clearItv = () => {
if (!interval) return
clearInterval(interval)
interval = null
}
const updateBuffer = async() => {
const buffered = await (duration ? TrackPlayer.getBufferedPosition() : Promise.all([TrackPlayer.getBufferedPosition(), TrackPlayer.getDuration()]).then(([buffered, _duration]) => {
duration = _duration
return buffered
}))
// console.log('updateBuffer', buffered, duration, buffered > 0, buffered == duration)
// After the asynchronous code is executed, if the component has been uninstalled, do not update the status
if (buffered > 0 && buffered == duration) clearItv()
if (buffered == preBuffered || isUnmounted) return
preBuffered = buffered
setProgress(duration ? (buffered / duration) : 0)
}
const sub = TrackPlayer.addEventListener(Event.PlaybackState, data => {
switch (data.state) {
case State.None:
// console.log('state', 'None')
setProgress(0)
break
// case State.Ready:
// console.log('state', 'Ready')
// break
// case State.Stopped:
// console.log('state', 'Stopped')
// break
// case State.Paused:
// console.log('state', 'Paused')
// break
// case State.Playing:
// console.log('state', 'Playing')
// break
case State.Buffering:
// console.log('state', 'Buffering')
clearItv()
duration = 0
interval = setInterval(updateBuffer, 1000)
void updateBuffer()
break
// case State.Connecting:
// console.log('state', 'Connecting')
// break
// default:
// console.log('playback-state', data)
// break
}
})
void updateBuffer()
void TrackPlayer.getState().then((state) => {
if (state == State.Buffering) interval = setInterval(updateBuffer, 1000)
})
return () => {
isUnmounted = true
sub.remove()
clearItv()
}
}, [])
return progress
}

View File

@ -65,4 +65,5 @@ export {
updateMetaData,
onStateChange,
isEmpty,
useBufferProgress,
} from './utils'

View File

@ -228,7 +228,7 @@ const debounceUpdateMetaInfoTools = {
if (!musicInfo) return
// isDelayRun = false
void fn(musicInfo)
}, 1500)
}, 1000)
} else {
isDelayRun = true
void fn(musicInfo)

View File

@ -4,12 +4,12 @@ import { playMusic as handlePlayMusic } from './playList'
// import { PlayerMusicInfo } from '@/store/modules/player/playInfo'
export { useProgress } from './hook'
export { useBufferProgress } from './hook'
const emptyIdRxp = /\/\/default$/
const tempIdRxp = /\/\/default$|\/\/default\/\/restorePlay$/
export const isEmpty = (trackId = global.lx.playerTrackId) => {
console.log(trackId)
// console.log(trackId)
return !trackId || emptyIdRxp.test(trackId)
}
export const isTempId = (trackId = global.lx.playerTrackId) => !trackId || tempIdRxp.test(trackId)

View File

@ -7,6 +7,7 @@ import { useProgress } from '@/store/player/hook'
import { useTheme } from '@/store/theme/hook'
import { createStyle } from '@/utils/tools'
import Text from '@/components/common/Text'
import { useBufferProgress } from '@/plugins/player'
// const FONT_SIZE = 13
@ -24,6 +25,7 @@ const PlayTimeMax = memo(({ timeStr }: { timeStr: string }) => {
export default () => {
const theme = useTheme()
const { maxPlayTimeStr, nowPlayTimeStr, progress, maxPlayTime } = useProgress()
const buffered = useBufferProgress()
// console.log('render playInfo')
return (
@ -36,7 +38,7 @@ export default () => {
<Text color={theme['c-500']}> / </Text>
<PlayTimeMax timeStr={maxPlayTimeStr} />
</View>
<View style={[StyleSheet.absoluteFill, styles.progress]}><Progress progress={progress} duration={maxPlayTime} /></View>
<View style={[StyleSheet.absoluteFill, styles.progress]}><Progress progress={progress} duration={maxPlayTime} buffered={buffered} /></View>
</View>
)
}

View File

@ -7,6 +7,7 @@ import { useProgress } from '@/store/player/hook'
import { useTheme } from '@/store/theme/hook'
import { createStyle } from '@/utils/tools'
import Text from '@/components/common/Text'
import { useBufferProgress } from '@/plugins/player'
// const FONT_SIZE = 13
@ -23,11 +24,13 @@ const PlayTimeMax = memo(({ timeStr }: { timeStr: string }) => {
export default () => {
const { maxPlayTimeStr, nowPlayTimeStr, progress, maxPlayTime } = useProgress()
const buffered = useBufferProgress()
// console.log('render playInfo')
return (
<>
<View style={styles.progress}><Progress progress={progress} duration={maxPlayTime} /></View>
<View style={styles.progress}><Progress progress={progress} duration={maxPlayTime} buffered={buffered} /></View>
<View style={styles.info}>
<PlayTimeCurrent timeStr={nowPlayTimeStr} />
<View style={styles.status} >

View File

@ -4,7 +4,7 @@ export { default as useWindowSize } from './useWindowSize'
export { default as useHorizontalMode } from './useHorizontalMode'
export { default as useDeviceOrientation } from './useDeviceOrientation'
export { default as usePlayTime } from './usePlayTime'
// export { default as usePlayTime } from './usePlayTime'
export { default as useAssertApiSupport } from './useAssertApiSupport'
export { useDrag } from './useDrag'
export { useUnmounted } from './useUnmounted'

View File

@ -1,19 +1,19 @@
// import { useMemo } from 'react'
import { useProgress } from '@/plugins/player/utils'
import { formatPlayTime2 } from '@/utils'
// import { useGetter } from '@/store'
// import { STATE_PLAYING, STATE_BUFFERING } from 'react-native-track-player'
// import { useProgress } from '@/plugins/player/utils'
// import { formatPlayTime2 } from '@/utils'
// // import { useGetter } from '@/store'
// // import { STATE_PLAYING, STATE_BUFFERING } from 'react-native-track-player'
export default () => {
const { position, buffered, duration } = useProgress(250)
// const isGettingUrl = useGetter('player', 'isGettingUrl')
// export default () => {
// const { position, buffered, duration } = useProgress(250)
// // const isGettingUrl = useGetter('player', 'isGettingUrl')
return {
curTimeStr: formatPlayTime2(position),
maxTimeStr: formatPlayTime2(duration),
time: position,
duration,
bufferedProgress: duration ? buffered / duration * 100 : 100,
progress: duration ? position / duration * 100 : 0,
}
}
// return {
// curTimeStr: formatPlayTime2(position),
// maxTimeStr: formatPlayTime2(duration),
// time: position,
// duration,
// bufferedProgress: duration ? buffered / duration * 100 : 100,
// progress: duration ? position / duration * 100 : 0,
// }
// }

View File

@ -13,7 +13,7 @@ const logTools = {
async initLogFile() {
try {
let isExists = await existsFile(logPath)
console.log(isExists)
// console.log(isExists)
if (!isExists) await writeFile(logPath, '')
if (this.tempLog?.length) this.writeLog(this.tempLog.map(m => `${m.time} ${m.type} ${m.text}`).join('\n----lx log----\n'))
this.tempLog = null