mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 06:52:09 +08:00
添加缓存进度条
This commit is contained in:
parent
27e82baed0
commit
5b682305c1
@ -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>
|
||||
)
|
||||
|
@ -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
|
||||
? (
|
||||
|
@ -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
|
||||
? (
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -65,4 +65,5 @@ export {
|
||||
updateMetaData,
|
||||
onStateChange,
|
||||
isEmpty,
|
||||
useBufferProgress,
|
||||
} from './utils'
|
||||
|
@ -228,7 +228,7 @@ const debounceUpdateMetaInfoTools = {
|
||||
if (!musicInfo) return
|
||||
// isDelayRun = false
|
||||
void fn(musicInfo)
|
||||
}, 1500)
|
||||
}, 1000)
|
||||
} else {
|
||||
isDelayRun = true
|
||||
void fn(musicInfo)
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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} >
|
||||
|
@ -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'
|
||||
|
@ -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,
|
||||
// }
|
||||
// }
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user