向浏览器回报歌曲元数据
This commit is contained in:
parent
d89dd55a51
commit
d63e18f0c7
|
@ -2,7 +2,7 @@
|
|||
import { usePlayQueueStore } from '../stores/usePlayQueueStore'
|
||||
import { usePlayState } from '../stores/usePlayState'
|
||||
import { debugPlayer } from '../utils/debug'
|
||||
import { watch, ref, onMounted, onUnmounted } from 'vue'
|
||||
import { watch, ref, onMounted } from 'vue'
|
||||
import artistsOrganize from '../utils/artistsOrganize'
|
||||
|
||||
const playQueue = usePlayQueueStore()
|
||||
|
@ -82,11 +82,11 @@ class WebAudioPlayer {
|
|||
if ('mediaSession' in navigator) {
|
||||
navigator.mediaSession.setActionHandler('play', () => {
|
||||
console.log('Media session: play requested')
|
||||
this.play()
|
||||
playState.togglePlay(true)
|
||||
})
|
||||
navigator.mediaSession.setActionHandler('pause', () => {
|
||||
console.log('Media session: pause requested')
|
||||
this.pause()
|
||||
playState.togglePlay(false)
|
||||
})
|
||||
navigator.mediaSession.setActionHandler('stop', () => {
|
||||
console.log('Media session: stop requested')
|
||||
|
@ -148,6 +148,7 @@ class WebAudioPlayer {
|
|||
if (!playState.actualPlaying) {
|
||||
// 如果实际正在播放,那么跳过音轨初始化阶段
|
||||
debugPlayer("开始播放")
|
||||
navigator.mediaSession.playbackState = 'playing'
|
||||
if (playState.playProgress !== 0) debugPlayer(`已经有所进度!${playState.playProgress}`)
|
||||
this.currentSource = this.context.createBufferSource()
|
||||
this.currentSource.buffer = this.audioBuffer[playQueue.currentTrack.song.cid]
|
||||
|
@ -201,6 +202,19 @@ class WebAudioPlayer {
|
|||
const progress = this.context.currentTime - this.currentTrackStartTime
|
||||
playState.reportPlayProgress(progress)
|
||||
playState.reportCurrentTrackDuration(this.audioBuffer[playQueue.currentTrack.song.cid].duration)
|
||||
|
||||
// 向浏览器回报
|
||||
if (('mediaSession' in navigator) && ('setPositionState' in navigator.mediaSession)) {
|
||||
try {
|
||||
navigator.mediaSession.setPositionState({
|
||||
duration: this.audioBuffer[playQueue.currentTrack.song.cid].duration || 0,
|
||||
playbackRate: 1.0,
|
||||
position: progress,
|
||||
})
|
||||
} catch (error) {
|
||||
debugPlayer('媒体会话位置更新失败:', error)
|
||||
}
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
|
@ -212,6 +226,7 @@ class WebAudioPlayer {
|
|||
}
|
||||
|
||||
pause() {
|
||||
navigator.mediaSession.playbackState = 'paused'
|
||||
debugPlayer("尝试暂停播放")
|
||||
debugPlayer(this.currentSource)
|
||||
this.currentSource?.stop()
|
||||
|
@ -263,6 +278,15 @@ onMounted(() => {
|
|||
|
||||
watch(() => playQueue.currentTrack, () => {
|
||||
debugPlayer(`检测到当前播放曲目更新`)
|
||||
navigator.mediaSession.playbackState = playState.isPlaying ? 'playing' : 'paused'
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: playQueue.currentTrack.song.name,
|
||||
artist: artistsOrganize(playQueue.currentTrack.song.artistes ?? []),
|
||||
album: playQueue.currentTrack.album?.name,
|
||||
artwork: [
|
||||
{ src: playQueue.currentTrack.album?.coverUrl ?? "", sizes: '500x500', type: 'image/png' },
|
||||
]
|
||||
})
|
||||
playerInstance.value?.loadResourceAndPlay()
|
||||
})
|
||||
|
||||
|
|
|
@ -68,119 +68,6 @@ export const usePlayState = defineStore('playState', () => {
|
|||
actualPlaying.value = playing
|
||||
}
|
||||
|
||||
/***********
|
||||
* 媒体会话管理
|
||||
**********/
|
||||
// 设置当前播放曲目
|
||||
const setCurrentTrack = (track: QueueItem | null) => {
|
||||
debugStore('设置当前曲目:', track?.song.name || 'null')
|
||||
currentTrack.value = track
|
||||
if (track) {
|
||||
updateMediaSession(track)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化媒体会话处理器
|
||||
const setupMediaSessionHandlers = () => {
|
||||
if (!('mediaSession' in navigator) || mediaSessionInitialized.value) return
|
||||
|
||||
debugStore('设置媒体会话处理器')
|
||||
|
||||
navigator.mediaSession.setActionHandler('play', () => {
|
||||
debugStore('媒体会话: 播放')
|
||||
togglePlay(true)
|
||||
})
|
||||
|
||||
navigator.mediaSession.setActionHandler('pause', () => {
|
||||
debugStore('媒体会话: 暂停')
|
||||
togglePlay(false)
|
||||
})
|
||||
|
||||
// 上一首和下一首需要从外部传入回调
|
||||
mediaSessionInitialized.value = true
|
||||
}
|
||||
|
||||
// 设置上一首/下一首处理器
|
||||
const setTrackNavigationHandlers = (
|
||||
previousHandler: () => void,
|
||||
nextHandler: () => void,
|
||||
) => {
|
||||
if (!('mediaSession' in navigator)) return
|
||||
|
||||
navigator.mediaSession.setActionHandler('previoustrack', () => {
|
||||
debugStore('媒体会话: 上一首')
|
||||
previousHandler()
|
||||
})
|
||||
|
||||
navigator.mediaSession.setActionHandler('nexttrack', () => {
|
||||
debugStore('媒体会话: 下一首')
|
||||
nextHandler()
|
||||
})
|
||||
}
|
||||
|
||||
// 更新媒体会话信息
|
||||
const updateMediaSession = (track: QueueItem) => {
|
||||
if (!('mediaSession' in navigator)) return
|
||||
|
||||
debugStore('更新媒体会话:', track.song.name)
|
||||
|
||||
try {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: track.song.name,
|
||||
artist: artistsOrganize(track.song.artists ?? []),
|
||||
album: track.album?.name,
|
||||
artwork: [
|
||||
{
|
||||
src: track.album?.coverUrl ?? '',
|
||||
sizes: '500x500',
|
||||
type: 'image/png',
|
||||
},
|
||||
],
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('更新媒体会话元数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 更新媒体会话播放状态
|
||||
const updateMediaSessionPlaybackState = () => {
|
||||
if (!('mediaSession' in navigator)) return
|
||||
|
||||
navigator.mediaSession.playbackState = isPlaying.value
|
||||
? 'playing'
|
||||
: 'paused'
|
||||
debugStore('媒体会话状态更新:', navigator.mediaSession.playbackState)
|
||||
}
|
||||
|
||||
// 更新媒体会话位置信息
|
||||
const updateMediaSessionPosition = () => {
|
||||
if (
|
||||
!('mediaSession' in navigator) ||
|
||||
!('setPositionState' in navigator.mediaSession)
|
||||
)
|
||||
return
|
||||
|
||||
try {
|
||||
navigator.mediaSession.setPositionState({
|
||||
duration: currentTrackDuration.value || 0,
|
||||
playbackRate: 1.0,
|
||||
position: playProgress.value,
|
||||
})
|
||||
} catch (error) {
|
||||
debugStore('媒体会话位置更新失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 监听播放状态变化,自动更新媒体会话
|
||||
watch(isPlaying, () => {
|
||||
updateMediaSessionPlaybackState()
|
||||
})
|
||||
|
||||
// 监听播放进度变化,定期更新位置信息
|
||||
watch(playProgress, () => {
|
||||
updateMediaSessionPosition()
|
||||
})
|
||||
|
||||
return {
|
||||
// 状态读取
|
||||
isPlaying: playingState,
|
||||
|
@ -198,13 +85,5 @@ export const usePlayState = defineStore('playState', () => {
|
|||
resetProgress,
|
||||
seekTo,
|
||||
reportActualPlaying,
|
||||
|
||||
// 媒体会话方法
|
||||
setCurrentTrack,
|
||||
setupMediaSessionHandlers,
|
||||
setTrackNavigationHandlers,
|
||||
updateMediaSession,
|
||||
updateMediaSessionPlaybackState,
|
||||
updateMediaSessionPosition,
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user