Fix ongoing broadcast recording after connection error (#9974)

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
Michael Weimann 2023-01-24 11:36:31 +01:00 committed by GitHub
parent 533b250bb6
commit 7df973d569
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 5 deletions

View file

@ -65,14 +65,18 @@ export class VoiceBroadcastRecorder
this.voiceRecording.liveData.onUpdate((data: IRecordingUpdate) => { this.voiceRecording.liveData.onUpdate((data: IRecordingUpdate) => {
this.setCurrentChunkLength(data.timeSeconds - this.previousChunkEndTimePosition); this.setCurrentChunkLength(data.timeSeconds - this.previousChunkEndTimePosition);
}); });
return;
} }
/** /**
* Stops the recording and returns the remaining chunk (if any). * Stops the recording and returns the remaining chunk (if any).
*/ */
public async stop(): Promise<Optional<ChunkRecordedPayload>> { public async stop(): Promise<Optional<ChunkRecordedPayload>> {
try {
await this.voiceRecording.stop(); await this.voiceRecording.stop();
} catch {
// Ignore if the recording raises any error.
}
// forget about that call, so that we can stop it again later // forget about that call, so that we can stop it again later
Singleflight.forgetAllFor(this.voiceRecording); Singleflight.forgetAllFor(this.voiceRecording);
const chunk = this.extractChunk(); const chunk = this.extractChunk();

View file

@ -333,7 +333,7 @@ export class VoiceBroadcastRecording
* It sets the connection error state and stops the recorder. * It sets the connection error state and stops the recorder.
*/ */
private async onConnectionError(): Promise<void> { private async onConnectionError(): Promise<void> {
await this.stopRecorder(); await this.stopRecorder(false);
this.setState("connection_error"); this.setState("connection_error");
} }
@ -418,14 +418,14 @@ export class VoiceBroadcastRecording
} }
} }
private async stopRecorder(): Promise<void> { private async stopRecorder(emit = true): Promise<void> {
if (!this.recorder) { if (!this.recorder) {
return; return;
} }
try { try {
const lastChunk = await this.recorder.stop(); const lastChunk = await this.recorder.stop();
if (lastChunk) { if (lastChunk && emit) {
await this.onChunkRecorded(lastChunk); await this.onChunkRecorded(lastChunk);
} }
} catch (err) { } catch (err) {

View file

@ -205,6 +205,22 @@ describe("VoiceBroadcastRecorder", () => {
}); });
}); });
}); });
describe("and calling stop() with recording.stop error)", () => {
let stopPayload: ChunkRecordedPayload;
beforeEach(async () => {
mocked(voiceRecording.stop).mockRejectedValue("Error");
stopPayload = await voiceBroadcastRecorder.stop();
});
it("should return the remaining chunk", () => {
expect(stopPayload).toEqual({
buffer: concat(headers1, headers2, chunk1),
length: 23,
});
});
});
}); });
describe("when some chunks have been received", () => { describe("when some chunks have been received", () => {