155 lines
5.1 KiB
TypeScript
155 lines
5.1 KiB
TypeScript
import { onBeforeUnmount } from '@common/utils/vueTools'
|
|
import { getDuration, getPlaybackRate, getCurrentTime } from '@renderer/plugins/player'
|
|
import { isPlay, musicInfo, playMusicInfo } from '@renderer/store/player/state'
|
|
import { playProgress } from '@renderer/store/player/playProgress'
|
|
import { pause, play, playNext, playPrev, stop } from '@renderer/core/player'
|
|
|
|
export default () => {
|
|
// 创建一个空白音频以保持对 Media Session 的注册
|
|
const emptyAudio = new Audio()
|
|
emptyAudio.autoplay = false
|
|
emptyAudio.src = require('@renderer/assets/medias/Silence02s.mp3')
|
|
emptyAudio.controls = false
|
|
emptyAudio.preload = 'auto'
|
|
emptyAudio.onplaying = () => {
|
|
emptyAudio.pause()
|
|
}
|
|
void emptyAudio.play()
|
|
let prevPicUrl = ''
|
|
|
|
const updateMediaSessionInfo = () => {
|
|
if (musicInfo.id == null) {
|
|
navigator.mediaSession.metadata = null
|
|
return
|
|
}
|
|
const mediaMetadata: MediaMetadata = {
|
|
title: musicInfo.name,
|
|
artist: musicInfo.singer,
|
|
album: musicInfo.album,
|
|
artwork: [],
|
|
}
|
|
if (musicInfo.pic) {
|
|
const pic = new Image()
|
|
pic.src = prevPicUrl = musicInfo.pic
|
|
pic.onload = () => {
|
|
if (prevPicUrl == pic.src) {
|
|
mediaMetadata.artwork = [{ src: pic.src }]
|
|
// @ts-expect-error
|
|
navigator.mediaSession.metadata = new window.MediaMetadata(mediaMetadata)
|
|
}
|
|
}
|
|
} else prevPicUrl = ''
|
|
|
|
// @ts-expect-error
|
|
navigator.mediaSession.metadata = new window.MediaMetadata(mediaMetadata)
|
|
}
|
|
|
|
const updatePositionState = (state: {
|
|
duration?: number
|
|
position?: number
|
|
playbackRate?: number
|
|
} = {}) => {
|
|
navigator.mediaSession.setPositionState({
|
|
duration: state.duration ?? getDuration(),
|
|
playbackRate: state.playbackRate ?? getPlaybackRate(),
|
|
position: state.position ?? getCurrentTime(),
|
|
})
|
|
}
|
|
|
|
const setProgress = (time: number) => {
|
|
window.app_event.setProgress(time)
|
|
}
|
|
|
|
const setStop = () => {
|
|
stop()
|
|
}
|
|
const handlePlay = () => {
|
|
navigator.mediaSession.playbackState = 'playing'
|
|
}
|
|
const handlePause = () => {
|
|
navigator.mediaSession.playbackState = 'paused'
|
|
}
|
|
const handleStop = () => {
|
|
navigator.mediaSession.playbackState = 'none'
|
|
}
|
|
const handleSetPlayInfo = () => {
|
|
emptyAudio.play().finally(() => {
|
|
updateMediaSessionInfo()
|
|
updatePositionState({
|
|
position: playProgress.nowPlayTime,
|
|
duration: playProgress.maxPlayTime,
|
|
})
|
|
handlePause()
|
|
})
|
|
}
|
|
|
|
// const registerMediaSessionHandler = () => {
|
|
navigator.mediaSession.setActionHandler('play', () => {
|
|
if (isPlay.value || !playMusicInfo) return
|
|
console.log('play')
|
|
play()
|
|
})
|
|
navigator.mediaSession.setActionHandler('pause', () => {
|
|
if (!isPlay.value || !playMusicInfo) return
|
|
console.log('pause')
|
|
pause()
|
|
})
|
|
navigator.mediaSession.setActionHandler('stop', () => {
|
|
console.log('stop')
|
|
setStop()
|
|
})
|
|
navigator.mediaSession.setActionHandler('seekbackward', details => {
|
|
console.log('seekbackward')
|
|
const seekOffset = details.seekOffset == null ? 5 : details.seekOffset
|
|
setProgress(Math.max(getCurrentTime() - seekOffset, 0))
|
|
})
|
|
navigator.mediaSession.setActionHandler('seekforward', details => {
|
|
console.log('seekforward')
|
|
const seekOffset = details.seekOffset == null ? 5 : details.seekOffset
|
|
setProgress(Math.min(getCurrentTime() + seekOffset, getDuration()))
|
|
})
|
|
navigator.mediaSession.setActionHandler('seekto', details => {
|
|
console.log('seekto', details.seekTime)
|
|
if (details.seekTime == null) return
|
|
let time = Math.min(details.seekTime, getDuration())
|
|
time = Math.max(time, 0)
|
|
setProgress(time)
|
|
})
|
|
navigator.mediaSession.setActionHandler('previoustrack', () => {
|
|
console.log('previoustrack')
|
|
void playPrev()
|
|
})
|
|
navigator.mediaSession.setActionHandler('nexttrack', () => {
|
|
console.log('nexttrack')
|
|
void playNext()
|
|
})
|
|
// navigator.mediaSession.setActionHandler('skipad', () => {
|
|
// console.log('')
|
|
// })
|
|
// }
|
|
|
|
window.app_event.on('playerLoadeddata', updatePositionState)
|
|
window.app_event.on('playerCanplay', updatePositionState)
|
|
window.app_event.on('play', handlePlay)
|
|
window.app_event.on('pause', handlePause)
|
|
window.app_event.on('stop', handleStop)
|
|
window.app_event.on('error', handlePause)
|
|
window.app_event.on('playerEmptied', handleSetPlayInfo)
|
|
// window.app_event.on('playerLoadstart', handleSetPlayInfo)
|
|
window.app_event.on('musicToggled', handleSetPlayInfo)
|
|
window.app_event.on('picUpdated', updateMediaSessionInfo)
|
|
|
|
onBeforeUnmount(() => {
|
|
window.app_event.off('playerLoadeddata', updatePositionState)
|
|
window.app_event.off('playerCanplay', updatePositionState)
|
|
window.app_event.off('play', handlePlay)
|
|
window.app_event.off('pause', handlePause)
|
|
window.app_event.off('stop', handleStop)
|
|
window.app_event.off('error', handlePause)
|
|
window.app_event.off('playerEmptied', handleSetPlayInfo)
|
|
// window.app_event.off('playerLoadstart', handleSetPlayInfo)
|
|
window.app_event.off('musicToggled', handleSetPlayInfo)
|
|
window.app_event.off('picUpdated', updateMediaSessionInfo)
|
|
})
|
|
}
|