Handle local events for voice broadcasts (#9561)
This commit is contained in:
parent
848adfdc10
commit
7fbdd8bb5d
4 changed files with 51 additions and 8 deletions
|
@ -129,12 +129,8 @@ export class VoiceBroadcastPlayback
|
||||||
}
|
}
|
||||||
|
|
||||||
private addChunkEvent = async (event: MatrixEvent): Promise<boolean> => {
|
private addChunkEvent = async (event: MatrixEvent): Promise<boolean> => {
|
||||||
const eventId = event.getId();
|
if (event.getContent()?.msgtype !== MsgType.Audio) {
|
||||||
|
// skip non-audio event
|
||||||
if (!eventId
|
|
||||||
|| eventId.startsWith("~!") // don't add local events
|
|
||||||
|| event.getContent()?.msgtype !== MsgType.Audio // don't add non-audio event
|
|
||||||
) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,12 @@ export class VoiceBroadcastChunkEvents {
|
||||||
}
|
}
|
||||||
|
|
||||||
public includes(event: MatrixEvent): boolean {
|
public includes(event: MatrixEvent): boolean {
|
||||||
return !!this.events.find(e => e.getId() === event.getId());
|
return !!this.events.find(e => this.equalByTxnIdOrId(event, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {number} Length in milliseconds
|
||||||
|
*/
|
||||||
public getLength(): number {
|
public getLength(): number {
|
||||||
return this.events.reduce((length: number, event: MatrixEvent) => {
|
return this.events.reduce((length: number, event: MatrixEvent) => {
|
||||||
return length + this.calculateChunkLength(event);
|
return length + this.calculateChunkLength(event);
|
||||||
|
@ -93,11 +96,16 @@ export class VoiceBroadcastChunkEvents {
|
||||||
}
|
}
|
||||||
|
|
||||||
private addOrReplaceEvent = (event: MatrixEvent): boolean => {
|
private addOrReplaceEvent = (event: MatrixEvent): boolean => {
|
||||||
this.events = this.events.filter(e => e.getId() !== event.getId());
|
this.events = this.events.filter(e => !this.equalByTxnIdOrId(event, e));
|
||||||
this.events.push(event);
|
this.events.push(event);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private equalByTxnIdOrId(eventA: MatrixEvent, eventB: MatrixEvent): boolean {
|
||||||
|
return eventA.getTxnId() && eventB.getTxnId() && eventA.getTxnId() === eventB.getTxnId()
|
||||||
|
|| eventA.getId() === eventB.getId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort by sequence, if available for all events.
|
* Sort by sequence, if available for all events.
|
||||||
* Else fall back to timestamp.
|
* Else fall back to timestamp.
|
||||||
|
|
|
@ -49,6 +49,7 @@ describe("VoiceBroadcastPlayback", () => {
|
||||||
let onStateChanged: (state: VoiceBroadcastPlaybackState) => void;
|
let onStateChanged: (state: VoiceBroadcastPlaybackState) => void;
|
||||||
let chunk1Event: MatrixEvent;
|
let chunk1Event: MatrixEvent;
|
||||||
let chunk2Event: MatrixEvent;
|
let chunk2Event: MatrixEvent;
|
||||||
|
let chunk2BEvent: MatrixEvent;
|
||||||
let chunk3Event: MatrixEvent;
|
let chunk3Event: MatrixEvent;
|
||||||
const chunk1Length = 2300;
|
const chunk1Length = 2300;
|
||||||
const chunk2Length = 4200;
|
const chunk2Length = 4200;
|
||||||
|
@ -135,6 +136,9 @@ describe("VoiceBroadcastPlayback", () => {
|
||||||
|
|
||||||
chunk1Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk1Length, 1);
|
chunk1Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk1Length, 1);
|
||||||
chunk2Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk2Length, 2);
|
chunk2Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk2Length, 2);
|
||||||
|
chunk2Event.setTxnId("tx-id-1");
|
||||||
|
chunk2BEvent = mkVoiceBroadcastChunkEvent(userId, roomId, chunk2Length, 2);
|
||||||
|
chunk2BEvent.setTxnId("tx-id-1");
|
||||||
chunk3Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk3Length, 3);
|
chunk3Event = mkVoiceBroadcastChunkEvent(userId, roomId, chunk3Length, 3);
|
||||||
|
|
||||||
chunk1Helper = mkChunkHelper(chunk1Data);
|
chunk1Helper = mkChunkHelper(chunk1Data);
|
||||||
|
@ -240,6 +244,21 @@ describe("VoiceBroadcastPlayback", () => {
|
||||||
playback = await mkPlayback();
|
playback = await mkPlayback();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("durationSeconds should have the length of the known chunks", () => {
|
||||||
|
expect(playback.durationSeconds).toEqual(6.5);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("and an event with the same transaction Id occurs", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
playback.chunkRelationHelper.emit(RelationsHelperEvent.Add, chunk2BEvent);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("durationSeconds should not change", () => {
|
||||||
|
expect(playback.durationSeconds).toEqual(6.5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("and calling start", () => {
|
describe("and calling start", () => {
|
||||||
startPlayback();
|
startPlayback();
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,11 @@ import { mkVoiceBroadcastChunkEvent } from "./test-utils";
|
||||||
describe("VoiceBroadcastChunkEvents", () => {
|
describe("VoiceBroadcastChunkEvents", () => {
|
||||||
const userId = "@user:example.com";
|
const userId = "@user:example.com";
|
||||||
const roomId = "!room:example.com";
|
const roomId = "!room:example.com";
|
||||||
|
const txnId = "txn-id";
|
||||||
let eventSeq1Time1: MatrixEvent;
|
let eventSeq1Time1: MatrixEvent;
|
||||||
let eventSeq2Time4: MatrixEvent;
|
let eventSeq2Time4: MatrixEvent;
|
||||||
let eventSeq3Time2: MatrixEvent;
|
let eventSeq3Time2: MatrixEvent;
|
||||||
|
let eventSeq3Time2T: MatrixEvent;
|
||||||
let eventSeq4Time1: MatrixEvent;
|
let eventSeq4Time1: MatrixEvent;
|
||||||
let eventSeqUTime3: MatrixEvent;
|
let eventSeqUTime3: MatrixEvent;
|
||||||
let eventSeq2Time4Dup: MatrixEvent;
|
let eventSeq2Time4Dup: MatrixEvent;
|
||||||
|
@ -36,6 +38,9 @@ describe("VoiceBroadcastChunkEvents", () => {
|
||||||
eventSeq2Time4Dup = mkVoiceBroadcastChunkEvent(userId, roomId, 3141, 2, 4);
|
eventSeq2Time4Dup = mkVoiceBroadcastChunkEvent(userId, roomId, 3141, 2, 4);
|
||||||
jest.spyOn(eventSeq2Time4Dup, "getId").mockReturnValue(eventSeq2Time4.getId());
|
jest.spyOn(eventSeq2Time4Dup, "getId").mockReturnValue(eventSeq2Time4.getId());
|
||||||
eventSeq3Time2 = mkVoiceBroadcastChunkEvent(userId, roomId, 42, 3, 2);
|
eventSeq3Time2 = mkVoiceBroadcastChunkEvent(userId, roomId, 42, 3, 2);
|
||||||
|
eventSeq3Time2.setTxnId(txnId);
|
||||||
|
eventSeq3Time2T = mkVoiceBroadcastChunkEvent(userId, roomId, 42, 3, 2);
|
||||||
|
eventSeq3Time2T.setTxnId(txnId);
|
||||||
eventSeq4Time1 = mkVoiceBroadcastChunkEvent(userId, roomId, 69, 4, 1);
|
eventSeq4Time1 = mkVoiceBroadcastChunkEvent(userId, roomId, 69, 4, 1);
|
||||||
eventSeqUTime3 = mkVoiceBroadcastChunkEvent(userId, roomId, 314, undefined, 3);
|
eventSeqUTime3 = mkVoiceBroadcastChunkEvent(userId, roomId, 314, undefined, 3);
|
||||||
chunkEvents = new VoiceBroadcastChunkEvents();
|
chunkEvents = new VoiceBroadcastChunkEvents();
|
||||||
|
@ -96,6 +101,21 @@ describe("VoiceBroadcastChunkEvents", () => {
|
||||||
it("findByTime(entire duration) should return the last chunk", () => {
|
it("findByTime(entire duration) should return the last chunk", () => {
|
||||||
expect(chunkEvents.findByTime(7 + 3141 + 42 + 69)).toBe(eventSeq4Time1);
|
expect(chunkEvents.findByTime(7 + 3141 + 42 + 69)).toBe(eventSeq4Time1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("and adding an event with a known transaction Id", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
chunkEvents.addEvent(eventSeq3Time2T);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should replace the previous event", () => {
|
||||||
|
expect(chunkEvents.getEvents()).toEqual([
|
||||||
|
eventSeq1Time1,
|
||||||
|
eventSeq2Time4Dup,
|
||||||
|
eventSeq3Time2T,
|
||||||
|
eventSeq4Time1,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when adding events where at least one does not have a sequence", () => {
|
describe("when adding events where at least one does not have a sequence", () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue