Fix ongoing broadcast recording after connection error (#9974)
Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
parent
533b250bb6
commit
7df973d569
3 changed files with 25 additions and 5 deletions
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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", () => {
|
||||||
|
|
Loading…
Reference in a new issue