Handle voice broadcast last_chunk_sequence (#9812)
This commit is contained in:
parent
539a50ae30
commit
2b7d106481
5 changed files with 118 additions and 18 deletions
|
@ -31,7 +31,12 @@ import { PlaybackManager } from "../../audio/PlaybackManager";
|
|||
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
||||
import { MediaEventHelper } from "../../utils/MediaEventHelper";
|
||||
import { IDestroyable } from "../../utils/IDestroyable";
|
||||
import { VoiceBroadcastLiveness, VoiceBroadcastInfoEventType, VoiceBroadcastInfoState } from "..";
|
||||
import {
|
||||
VoiceBroadcastLiveness,
|
||||
VoiceBroadcastInfoEventType,
|
||||
VoiceBroadcastInfoState,
|
||||
VoiceBroadcastInfoEventContent,
|
||||
} from "..";
|
||||
import { RelationsHelper, RelationsHelperEvent } from "../../events/RelationsHelper";
|
||||
import { VoiceBroadcastChunkEvents } from "../utils/VoiceBroadcastChunkEvents";
|
||||
import { determineVoiceBroadcastLiveness } from "../utils/determineVoiceBroadcastLiveness";
|
||||
|
@ -151,12 +156,20 @@ export class VoiceBroadcastPlayback
|
|||
this.setDuration(this.chunkEvents.getLength());
|
||||
|
||||
if (this.getState() === VoiceBroadcastPlaybackState.Buffering) {
|
||||
await this.start();
|
||||
await this.startOrPlayNext();
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
private startOrPlayNext = async (): Promise<void> => {
|
||||
if (this.currentlyPlaying) {
|
||||
return this.playNext();
|
||||
}
|
||||
|
||||
return await this.start();
|
||||
};
|
||||
|
||||
private addInfoEvent = (event: MatrixEvent): void => {
|
||||
if (this.lastInfoEvent && this.lastInfoEvent.getTs() >= event.getTs()) {
|
||||
// Only handle newer events
|
||||
|
@ -263,7 +276,10 @@ export class VoiceBroadcastPlayback
|
|||
return this.playEvent(next);
|
||||
}
|
||||
|
||||
if (this.getInfoState() === VoiceBroadcastInfoState.Stopped) {
|
||||
if (
|
||||
this.getInfoState() === VoiceBroadcastInfoState.Stopped &&
|
||||
this.chunkEvents.getSequenceForEvent(this.currentlyPlaying) === this.lastChunkSequence
|
||||
) {
|
||||
this.stop();
|
||||
} else {
|
||||
// No more chunks available, although the broadcast is not finished → enter buffering state.
|
||||
|
@ -271,6 +287,17 @@ export class VoiceBroadcastPlayback
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number} The last chunk sequence from the latest info event.
|
||||
* Falls back to the length of received chunks if the info event does not provide the number.
|
||||
*/
|
||||
private get lastChunkSequence(): number {
|
||||
return (
|
||||
this.lastInfoEvent.getContent<VoiceBroadcastInfoEventContent>()?.last_chunk_sequence ||
|
||||
this.chunkEvents.getNumberOfEvents()
|
||||
);
|
||||
}
|
||||
|
||||
private async playEvent(event: MatrixEvent): Promise<void> {
|
||||
this.setState(VoiceBroadcastPlaybackState.Playing);
|
||||
this.currentlyPlaying = event;
|
||||
|
|
|
@ -97,6 +97,19 @@ export class VoiceBroadcastChunkEvents {
|
|||
return this.events.indexOf(event) >= this.events.length - 1;
|
||||
}
|
||||
|
||||
public getSequenceForEvent(event: MatrixEvent): number | null {
|
||||
const sequence = parseInt(event.getContent()?.[VoiceBroadcastChunkEventType]?.sequence, 10);
|
||||
if (!isNaN(sequence)) return sequence;
|
||||
|
||||
if (this.events.includes(event)) return this.events.indexOf(event) + 1;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public getNumberOfEvents(): number {
|
||||
return this.events.length;
|
||||
}
|
||||
|
||||
private calculateChunkLength(event: MatrixEvent): number {
|
||||
return event.getContent()?.["org.matrix.msc1767.audio"]?.duration || event.getContent()?.info?.duration || 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue