@@ -31,6 +31,7 @@ import { IDestroyable } from "../../utils/IDestroyable";
31
31
import { VoiceBroadcastChunkEventType , VoiceBroadcastInfoEventType , VoiceBroadcastInfoState } from ".." ;
32
32
import { RelationsHelper , RelationsHelperEvent } from "../../events/RelationsHelper" ;
33
33
import { getReferenceRelationsForEvent } from "../../events" ;
34
+ import { VoiceBroadcastChunkEvents } from "../utils/VoiceBroadcastChunkEvents" ;
34
35
35
36
export enum VoiceBroadcastPlaybackState {
36
37
Paused ,
@@ -59,9 +60,9 @@ export class VoiceBroadcastPlayback
59
60
implements IDestroyable {
60
61
private state = VoiceBroadcastPlaybackState . Stopped ;
61
62
private infoState : VoiceBroadcastInfoState ;
62
- private chunkEvents = new Map < string , MatrixEvent > ( ) ;
63
- private queue : Playback [ ] = [ ] ;
64
- private currentlyPlaying : Playback ;
63
+ private chunkEvents = new VoiceBroadcastChunkEvents ( ) ;
64
+ private playbacks = new Map < string , Playback > ( ) ;
65
+ private currentlyPlaying : MatrixEvent ;
65
66
private lastInfoEvent : MatrixEvent ;
66
67
private chunkRelationHelper : RelationsHelper ;
67
68
private infoRelationHelper : RelationsHelper ;
@@ -101,11 +102,12 @@ export class VoiceBroadcastPlayback
101
102
if ( ! eventId
102
103
|| eventId . startsWith ( "~!" ) // don't add local events
103
104
|| event . getContent ( ) ?. msgtype !== MsgType . Audio // don't add non-audio event
104
- || this . chunkEvents . has ( eventId ) ) {
105
+ ) {
105
106
return false ;
106
107
}
107
108
108
- this . chunkEvents . set ( eventId , event ) ;
109
+ this . chunkEvents . addEvent ( event ) ;
110
+ this . emit ( VoiceBroadcastPlaybackEvent . LengthChanged , this . chunkEvents . getLength ( ) ) ;
109
111
110
112
if ( this . getState ( ) !== VoiceBroadcastPlaybackState . Stopped ) {
111
113
await this . enqueueChunk ( event ) ;
@@ -143,6 +145,8 @@ export class VoiceBroadcastPlayback
143
145
return ;
144
146
}
145
147
148
+ this . chunkEvents . addEvents ( chunkEvents ) ;
149
+
146
150
for ( const chunkEvent of chunkEvents ) {
147
151
await this . enqueueChunk ( chunkEvent ) ;
148
152
}
@@ -158,7 +162,7 @@ export class VoiceBroadcastPlayback
158
162
const playback = PlaybackManager . instance . createPlaybackInstance ( buffer ) ;
159
163
await playback . prepare ( ) ;
160
164
playback . clockInfo . populatePlaceholdersFrom ( chunkEvent ) ;
161
- this . queue [ sequenceNumber - 1 ] = playback ; // -1 because the sequence number starts at 1
165
+ this . playbacks . set ( chunkEvent . getId ( ) , playback ) ;
162
166
playback . on ( UPDATE_EVENT , ( state ) => this . onPlaybackStateChange ( playback , state ) ) ;
163
167
}
164
168
@@ -167,16 +171,18 @@ export class VoiceBroadcastPlayback
167
171
return ;
168
172
}
169
173
170
- await this . playNext ( playback ) ;
174
+ await this . playNext ( ) ;
171
175
}
172
176
173
- private async playNext ( current : Playback ) : Promise < void > {
174
- const next = this . queue [ this . queue . indexOf ( current ) + 1 ] ;
177
+ private async playNext ( ) : Promise < void > {
178
+ if ( ! this . currentlyPlaying ) return ;
179
+
180
+ const next = this . chunkEvents . getNext ( this . currentlyPlaying ) ;
175
181
176
182
if ( next ) {
177
183
this . setState ( VoiceBroadcastPlaybackState . Playing ) ;
178
184
this . currentlyPlaying = next ;
179
- await next . play ( ) ;
185
+ await this . playbacks . get ( next . getId ( ) ) ? .play ( ) ;
180
186
return ;
181
187
}
182
188
@@ -188,34 +194,40 @@ export class VoiceBroadcastPlayback
188
194
}
189
195
}
190
196
197
+ public getLength ( ) : number {
198
+ return this . chunkEvents . getLength ( ) ;
199
+ }
200
+
191
201
public async start ( ) : Promise < void > {
192
- if ( this . queue . length === 0 ) {
202
+ if ( this . playbacks . size === 0 ) {
193
203
await this . loadChunks ( ) ;
194
204
}
195
205
196
- const toPlayIndex = this . getInfoState ( ) === VoiceBroadcastInfoState . Stopped
197
- ? 0 // start at the beginning for an ended voice broadcast
198
- : this . queue . length - 1 ; // start at the current chunk for an ongoing voice broadcast
206
+ const chunkEvents = this . chunkEvents . getEvents ( ) ;
199
207
200
- if ( this . queue [ toPlayIndex ] ) {
208
+ const toPlay = this . getInfoState ( ) === VoiceBroadcastInfoState . Stopped
209
+ ? chunkEvents [ 0 ] // start at the beginning for an ended voice broadcast
210
+ : chunkEvents [ chunkEvents . length - 1 ] ; // start at the current chunk for an ongoing voice broadcast
211
+
212
+ if ( this . playbacks . has ( toPlay ?. getId ( ) ) ) {
201
213
this . setState ( VoiceBroadcastPlaybackState . Playing ) ;
202
- this . currentlyPlaying = this . queue [ toPlayIndex ] ;
203
- await this . currentlyPlaying . play ( ) ;
214
+ this . currentlyPlaying = toPlay ;
215
+ await this . playbacks . get ( toPlay . getId ( ) ) . play ( ) ;
204
216
return ;
205
217
}
206
218
207
219
this . setState ( VoiceBroadcastPlaybackState . Buffering ) ;
208
220
}
209
221
210
222
public get length ( ) : number {
211
- return this . chunkEvents . size ;
223
+ return this . chunkEvents . getLength ( ) ;
212
224
}
213
225
214
226
public stop ( ) : void {
215
227
this . setState ( VoiceBroadcastPlaybackState . Stopped ) ;
216
228
217
229
if ( this . currentlyPlaying ) {
218
- this . currentlyPlaying . stop ( ) ;
230
+ this . playbacks . get ( this . currentlyPlaying . getId ( ) ) . stop ( ) ;
219
231
}
220
232
}
221
233
@@ -225,7 +237,7 @@ export class VoiceBroadcastPlayback
225
237
226
238
this . setState ( VoiceBroadcastPlaybackState . Paused ) ;
227
239
if ( ! this . currentlyPlaying ) return ;
228
- this . currentlyPlaying . pause ( ) ;
240
+ this . playbacks . get ( this . currentlyPlaying . getId ( ) ) . pause ( ) ;
229
241
}
230
242
231
243
public resume ( ) : void {
@@ -236,7 +248,7 @@ export class VoiceBroadcastPlayback
236
248
}
237
249
238
250
this . setState ( VoiceBroadcastPlaybackState . Playing ) ;
239
- this . currentlyPlaying . play ( ) ;
251
+ this . playbacks . get ( this . currentlyPlaying . getId ( ) ) . play ( ) ;
240
252
}
241
253
242
254
/**
@@ -285,15 +297,13 @@ export class VoiceBroadcastPlayback
285
297
this . emit ( VoiceBroadcastPlaybackEvent . InfoStateChanged , state ) ;
286
298
}
287
299
288
- private destroyQueue ( ) : void {
289
- this . queue . forEach ( p => p . destroy ( ) ) ;
290
- this . queue = [ ] ;
291
- }
292
-
293
300
public destroy ( ) : void {
294
301
this . chunkRelationHelper . destroy ( ) ;
295
302
this . infoRelationHelper . destroy ( ) ;
296
303
this . removeAllListeners ( ) ;
297
- this . destroyQueue ( ) ;
304
+
305
+ this . chunkEvents = new VoiceBroadcastChunkEvents ( ) ;
306
+ this . playbacks . forEach ( p => p . destroy ( ) ) ;
307
+ this . playbacks = new Map < string , Playback > ( ) ;
298
308
}
299
309
}
0 commit comments