diff --git a/README.md b/README.md
index baff37f..68566c2 100644
--- a/README.md
+++ b/README.md
@@ -19,3 +19,210 @@ webrtc 实现的 p2p 信道
[a2, b2, c2, d2, e2]
[a3, b3, c3, d3, e3]
```
+
+
+备用代码片段
+```html
+
+
+```
\ No newline at end of file
diff --git a/public/client.js b/public/client.js
index 2ad10bb..38347e1 100644
--- a/public/client.js
+++ b/public/client.js
@@ -20,8 +20,7 @@ export default class ClientList {
iceServers: [{
urls: 'turn:satori.love:3478',
username: 'x-username',
- credential: 'x-password', //await crypto.subtle.digest('SHA-1', new TextEncoder().encode('your-password')),
- //credentialType: 'password'
+ credential: 'x-password'
}]
})
webrtc.onicecandidate = event => {
@@ -152,6 +151,22 @@ export default class ClientList {
this.EventListeners[name](...args)
}
}
+ // 通过指定通道发送数据(单播)
+ sendto(id, name, data) {
+ //console.log('发送数据:', data, '到通道:', name, '到客户端:', id)
+ const client = this.clientlist.find(client => client.id === id)
+ if (!client) {
+ console.log('客户端不存在:', id)
+ return
+ }
+ client.channels.filter(ch => ch.label === name).forEach(async ch => {
+ // 等待 datachannel 打开(临时解决方案)
+ while (ch.readyState !== 'open') {
+ await new Promise(resolve => setTimeout(resolve, 100))
+ }
+ ch.send(data)
+ })
+ }
// 通过指定通道发送数据(广播)
send(name, data) {
//console.log('广播数据:', data, '到通道:', name, '到所有客户端')
diff --git a/public/index.html b/public/index.html
index 5838104..a1a6b11 100644
--- a/public/index.html
+++ b/public/index.html
@@ -17,63 +17,81 @@
import ClientList from './client.js'
// 读取本地音乐列表(本地缓存)
- const store = new IndexedDB('musicDatabase', 1, 'musicObjectStore')
- await store.open()
- const list = await store.getAll()
- //console.log('本地音乐列表:', list)
+ const database = new IndexedDB('musicDatabase', 1, 'musicObjectStore')
+ await database.open()
+ const list = await database.getAll()
// 读取本地用户名(本地缓存)
- const name = localStorage.getItem('username')
- if (!name) {
- localStorage.setItem('username', `user-${Math.random().toString(36).substr(2)}`)
- }
-
- // 初始化音乐列表(加入本地缓存)
- const musicList = new MusicList({ list })
- musicList.on('remove', item => {
- //console.log('移除音乐', item)
- store.delete(item.id)
- })
- musicList.on('play', item => {
- //console.log('播放音乐', item)
- })
- musicList.on('load', async item => {
- await new Promise((resolve) => {
- //console.log('加载音乐', item)
- // 建立一个专用信道, 用于接收音乐数据(接收方已经准备好摘要信息)
- var buffer = new ArrayBuffer(0)
- var count = 0
- clientList.setChannel(`music-data-${item.id}`, {
- onmessage: async (event, client) => {
- buffer = appendBuffer(buffer, event.data)
- console.log('收到音乐数据 chunk', count, buffer.byteLength)
- count++
- if (buffer.byteLength >= item.size) {
- console.log('音乐数据接收完毕')
- item.arrayBuffer = buffer
- event.target.close() // 关闭信道
- resolve()
- }
- }
- })
- // 要求对方从指定信道发送音乐数据
- clientList.send('base', JSON.stringify({ type: 'get_music_data', id: item.id, channel: `music-data-${item.id}` }))
- //store.put(item) // 只有在like时才保存到本地
- })
- })
- musicList.on('add', item => {
- //console.log('添加音乐', item)
- if (item.arrayBuffer) {
- store.add(item)
- // 告知对方音乐列表有更新
- clientList.send('base', JSON.stringify({ type: 'set_music_list', list: musicList.list.map(({ id, name, size, type }) => ({ id, name, size, type })) }))
- }
- })
+ const name = localStorage.getItem('username') ?? '游客'
// 初始化客户端列表
- console.log('初始化客户端列表', 'name:', name)
const clientList = new ClientList({ name })
+ // 初始化音乐列表(加入本地缓存)
+ const musicList = new MusicList({
+ list,
+ onplay: item => {
+ console.log('播放音乐', item.name)
+ },
+ onstop: item => {
+ console.log('停止音乐', item.name)
+ },
+ onlike: item => {
+ console.log('喜欢音乐', item)
+ if (item.arrayBuffer) {
+ database.add(item)
+ // clientList.send('base', JSON.stringify({
+ // type: 'set_music_list',
+ // list: list.map(({ id, name, size, type }) => ({ id, name, size, type }))
+ // }))
+ }
+ },
+ onunlike: item => {
+ console.log('取消喜欢', item)
+ },
+ onban: item => {
+ console.log('禁止音乐', item)
+ },
+ onunban: item => {
+ console.log('解禁音乐', item)
+ },
+ onremove: item => {
+ console.log('移除音乐', item)
+ database.delete(item.id)
+ },
+ onadd: (item, list) => {
+ console.log('添加音乐', item.name)
+ },
+ onupdate: item => {
+ console.log('更新音乐', item)
+ database.put(item)
+ },
+ onerror: error => {
+ console.log('音乐列表错误', error)
+ },
+ onload: async item => {
+ console.log('加载音乐', item)
+ return await new Promise((resolve) => {
+ var buffer = new ArrayBuffer(0)
+ var count = 0
+ clientList.setChannel(`music-data-${item.id}`, {
+ onmessage: async (event, client) => {
+ buffer = appendBuffer(buffer, event.data)
+ console.log('收到音乐数据 chunk', count, buffer.byteLength)
+ count++
+ if (buffer.byteLength >= item.size) {
+ console.log('音乐数据接收完毕')
+ item.arrayBuffer = buffer
+ event.target.close() // 关闭信道
+ resolve(item)
+ }
+ }
+ })
+ clientList.send('base', JSON.stringify({ type: 'get_music_data', id: item.id, channel: `music-data-${item.id}` }))
+ })
+ }
+ })
+
// 缓冲分片发送
const CHUNK_SIZE = 1024 * 128 // 每个块的大小为128KB
const THRESHOLD = 1024 * 1024 // 缓冲区的阈值为1MB
@@ -107,10 +125,11 @@
if (type === 'set_music_list') {
console.log(client.name, '发来音乐列表:', `x${JSON.parse(event.data).list.length}`)
// 将音乐列表添加到本地
- const ids = musicList.list.map(item => item.id)
- list.filter(item => !ids.includes(item.id)).forEach(item => {
- musicList.add(item)
- })
+ list.forEach(item => musicList.add(item))
+ //const ids = musicList.list.map(item => item.id)
+ //list.filter(item => !ids.includes(item.id)).forEach(item => {
+ // musicList.add(item)
+ //})
return
}
if (type === 'get_music_data') {
@@ -143,9 +162,6 @@
console.log('未知类型:', type)
}
})
- // like对方的条目时亮起(双方高亮)(本地缓存)(可由对比缓存实现)
- // ban对方的条目时灰掉(也禁止对方播放)(并保持ban表)(由插件实现)
- // 只需要在注册时拉取列表, 播放时才需要拉取音乐数据
// 延迟1500ms
//await new Promise((resolve) => setTimeout(resolve, 100))
@@ -161,209 +177,6 @@
}
document.body.appendChild(nameInput)
-
-
-