更好的加载器
This commit is contained in:
parent
0e4d68fa89
commit
4f57a19ef6
@ -2,6 +2,7 @@
|
||||
webrtc 实现的 p2p 信道
|
||||
|
||||
- [x] P2P通信
|
||||
- [ ] 分离出主要功能, 作为库或桁架使用
|
||||
- [x] 音乐播放
|
||||
- [x] 请求到单个目标防止接收到重复分片数据
|
||||
- [x] 主机记录各自曲目列表以供查询
|
||||
@ -14,6 +15,7 @@ webrtc 实现的 p2p 信道
|
||||
- [ ] 上锁防止连续重复加载同一个造成分片混乱
|
||||
- [x] 使用单独的状态标识音乐是否缓存
|
||||
- [x] 取消本地存储时不直接移除列表
|
||||
- [x] 分片下载过程与播放控制分离
|
||||
- [ ] 取消本地存储时检查是否移除(其它成员可能有同一曲)
|
||||
- [ ] 成员列表刷新时播放被重置BUG
|
||||
- [ ] 集群分发
|
||||
|
@ -109,40 +109,39 @@
|
||||
onerror: error => {
|
||||
console.log('音乐列表错误', error)
|
||||
},
|
||||
onload: async (item, sourceBuffer) => {
|
||||
onload: async item => {
|
||||
console.log('加载音乐', item)
|
||||
return await new Promise((resolve) => {
|
||||
var buffer = new ArrayBuffer(0) // 接收音乐数据
|
||||
var count = 0 // 接收分片计数
|
||||
var bufferCursor = 0 // 加载进度
|
||||
var partlength = 1024 * 64 // 每次加载1MB
|
||||
|
||||
// 指针达到音乐数据大小则结束加载
|
||||
const mediaLoader = async () => {
|
||||
while (bufferCursor !== item.size) {
|
||||
if (musicList.audio.paused && musicList.audio.currentTime !== 0) {
|
||||
console.log('音乐暂停')
|
||||
break
|
||||
}
|
||||
console.log('当前播放进度', musicList.audio.currentTime)
|
||||
const 当前播放进度 = musicList.audio.currentTime
|
||||
const 当前结束时间 = sourceBuffer.buffered.length && sourceBuffer.buffered.end(0)
|
||||
const 剩余数据长度 = buffer.byteLength - bufferCursor
|
||||
const 本次加载长度 = Math.min(partlength, 剩余数据长度)
|
||||
const 缓冲时间 = 当前结束时间 - 当前播放进度
|
||||
if (buffer.byteLength > bufferCursor && !sourceBuffer.updating && 缓冲时间 < 60) {
|
||||
sourceBuffer.appendBuffer(buffer.slice(bufferCursor, bufferCursor + 本次加载长度))
|
||||
bufferCursor += 本次加载长度
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
}
|
||||
mediaLoader()
|
||||
|
||||
//var bufferCursor = 0 // 加载进度
|
||||
//var partlength = 1024 * 64 // 每次加载1MB
|
||||
//// 指针达到音乐数据大小则结束加载
|
||||
//const mediaLoader = async () => {
|
||||
// while (bufferCursor !== item.size) {
|
||||
// if (musicList.audio.paused && musicList.audio.currentTime !== 0) {
|
||||
// console.log('音乐暂停')
|
||||
// break
|
||||
// }
|
||||
// console.log('当前播放进度', musicList.audio.currentTime)
|
||||
// const 当前播放进度 = musicList.audio.currentTime
|
||||
// const 当前结束时间 = sourceBuffer.buffered.length && sourceBuffer.buffered.end(0)
|
||||
// const 剩余数据长度 = buffer.byteLength - bufferCursor
|
||||
// const 本次加载长度 = Math.min(partlength, 剩余数据长度)
|
||||
// const 缓冲时间 = 当前结束时间 - 当前播放进度
|
||||
// if (buffer.byteLength > bufferCursor && !sourceBuffer.updating && 缓冲时间 < 60) {
|
||||
// sourceBuffer.appendBuffer(buffer.slice(bufferCursor, bufferCursor + 本次加载长度))
|
||||
// bufferCursor += 本次加载长度
|
||||
// }
|
||||
// await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
// }
|
||||
//}
|
||||
//mediaLoader()
|
||||
clientList.setChannel(`music-data-${item.id}`, {
|
||||
onmessage: async (event, client) => {
|
||||
console.log('收到音乐数据 chunk', count, buffer.byteLength)
|
||||
buffer = appendBuffer(buffer, event.data)
|
||||
buffer = appendBuffer(buffer, event.data) // 合并分片准备存储
|
||||
item.arrayBufferChunks.push(event.data) // 保存分片给边下边播
|
||||
count++
|
||||
if (buffer.byteLength >= item.size) {
|
||||
console.log('音乐数据接收完毕')
|
||||
|
@ -139,14 +139,53 @@ export default class MusicList {
|
||||
await this.event.onload(item)
|
||||
}
|
||||
async play(item) {
|
||||
if (!item.save) {
|
||||
if (!item.arrayBuffer) {
|
||||
// 边加载边播放
|
||||
const mediaSource = new MediaSource()
|
||||
this.audio.src = URL.createObjectURL(mediaSource)
|
||||
if (!item.arrayBufferChunks) item.arrayBufferChunks = []
|
||||
mediaSource.addEventListener('sourceopen', async () => {
|
||||
const sourceBuffer = mediaSource.addSourceBuffer(item.type)
|
||||
this.event.onload(item, sourceBuffer)
|
||||
const arrayBufferLoader = async (index = 0) => {
|
||||
|
||||
// 等待 item.arrayBufferChunks 不为空
|
||||
while (item.arrayBufferChunks.length === 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
}
|
||||
|
||||
console.log('开始加载====================================')
|
||||
// 按照数据长度计算出分片应有数量, 如果数量不到且没有停止加载则一直读取
|
||||
const chunkNumber = Math.ceil(item.size / 1024 / 64) // 64KB每片
|
||||
console.log({ index, chunkNumber, paused: this.audio.paused })
|
||||
while (index < chunkNumber && !this.audio.paused) {
|
||||
console.log('加载中------------------------------------', index)
|
||||
const 播放状态 = !this.audio.paused && this.playing === item
|
||||
const 加载状态 = item.arrayBufferChunks.length < chunkNumber
|
||||
const 播放进度 = this.audio.currentTime / this.audio.duration
|
||||
const 加载进度 = index / chunkNumber
|
||||
const 结束时间 = sourceBuffer.buffered.length && sourceBuffer.buffered.end(0)
|
||||
const 缓冲时间 = 结束时间 - this.audio.currentTime
|
||||
console.log({ 播放状态, 加载状态, 播放进度, 加载进度, 缓冲时间 })
|
||||
if (!播放状态 && !加载状态) break // 播放停止且加载完毕则退出
|
||||
if (缓冲时间 > 60) await new Promise(resolve => setTimeout(resolve, 30000)) // 缓冲超过60秒则等待30秒
|
||||
if (播放进度 - 加载进度 > 0.5) await new Promise(resolve => setTimeout(resolve, 1000)) // 播放进度超过加载进度0.5则等待1秒
|
||||
if (sourceBuffer.updating) {
|
||||
await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve))
|
||||
} else {
|
||||
while (item.arrayBufferChunks.length <= index) {
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
}
|
||||
const chunk = item.arrayBufferChunks[index] // 顺序取出一个arrayBuffer分片
|
||||
sourceBuffer.appendBuffer(chunk) // 添加到sourceBuffer
|
||||
index++
|
||||
}
|
||||
}
|
||||
console.log('加载完毕====================================')
|
||||
item.arrayBufferChunks = null // 加载完毕释放分片内存
|
||||
}
|
||||
this.event.onload(item)
|
||||
this.audio.play()
|
||||
arrayBufferLoader()
|
||||
})
|
||||
} else {
|
||||
// 本地缓存直接播放
|
||||
|
Loading…
Reference in New Issue
Block a user