feat: 先重新手撸了一个无缝播放

如果用户调整了播放进度,需要重新调度音乐播放;同时,上一首下一首等也要看怎么办
在网页上搞这种东西真的很大脑发光……
This commit is contained in:
Astrian Zheng 2025-08-22 11:40:59 +10:00
parent 488854f46b
commit dae6210239
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA

View File

@ -13,10 +13,16 @@ class WebAudioPlayer {
context: AudioContext
audioBuffer: { [key: string]: AudioBuffer}
dummyAudio: HTMLAudioElement
currentTrackStartTime: number
currentSource: AudioBufferSourceNode | null
nextSource: AudioBufferSourceNode | null
constructor() {
this.context = new window.AudioContext()
this.audioBuffer = {}
this.currentTrackStartTime = 0
this.currentSource = null
this.nextSource = null
// HTML Audio
this.dummyAudio = new Audio()
@ -87,6 +93,7 @@ class WebAudioPlayer {
}
}
//
async loadResourceAndPlay() {
try {
debugPlayer("从播放器实例内部获取播放项目:")
@ -107,13 +114,17 @@ class WebAudioPlayer {
this.audioBuffer[track.song.cid] = audioBuffer
}
if (playQueue.currentTrack){
if (playQueue.currentTrack) {
await loadBuffer(playQueue.currentTrack)
this.play()
}
if (playQueue.nextTrack)
if (playQueue.nextTrack) {
await loadBuffer(playQueue.nextTrack)
this.preloadNextTrack()
} else {
this.nextSource = null
}
if (playQueue.previousTrack)
await loadBuffer(playQueue.previousTrack)
@ -125,12 +136,29 @@ class WebAudioPlayer {
}
//
async play() {
play() {
debugPlayer("开始播放")
const source = this.context.createBufferSource()
source.buffer = this.audioBuffer[playQueue.currentTrack.song.cid]
source.connect(this.context.destination)
source.start()
this.currentSource = this.context.createBufferSource()
this.currentSource.buffer = this.audioBuffer[playQueue.currentTrack.song.cid]
this.currentSource.connect(this.context.destination)
this.currentSource.start()
if (!playQueue.nextTrack) return
//
//
this.currentTrackStartTime = this.context.currentTime
}
//
preloadNextTrack() {
this.nextSource = null
const nextTrackStartTime = this.currentTrackStartTime + this.audioBuffer[playQueue.currentTrack.song.cid].duration
debugPlayer(`下一首歌将在 ${nextTrackStartTime} 时间点接入`)
this.nextSource = this.context.createBufferSource()
this.nextSource.buffer = this.audioBuffer[playQueue.nextTrack.song.cid]
this.nextSource.connect(this.context.destination)
this.nextSource.start(nextTrackStartTime)
}
pause() {}