The source of the local participant is the createLocalMembership$ and

not the MatrixLivekitMembers!

Co-authored-by: Valere <bill.carson@valrsoft.com>
This commit is contained in:
Timo K
2025-11-12 12:09:31 +01:00
parent 8671d3fd67
commit 9f4d954cfa
7 changed files with 130 additions and 45 deletions

View File

@@ -389,15 +389,17 @@ describe("Publishing participants observations", () => {
const bobIsAPublisher = Promise.withResolvers<void>();
const danIsAPublisher = Promise.withResolvers<void>();
const observedPublishers: PublishingParticipant[][] = [];
const s = connection.participants$.subscribe((publishers) => {
observedPublishers.push(publishers);
if (publishers.some((p) => p.identity === "@bob:example.org:DEV111")) {
bobIsAPublisher.resolve();
}
if (publishers.some((p) => p.identity === "@dan:example.org:DEV333")) {
danIsAPublisher.resolve();
}
});
const s = connection.remoteParticipantsWithTracks$.subscribe(
(publishers) => {
observedPublishers.push(publishers);
if (publishers.some((p) => p.identity === "@bob:example.org:DEV111")) {
bobIsAPublisher.resolve();
}
if (publishers.some((p) => p.identity === "@dan:example.org:DEV333")) {
danIsAPublisher.resolve();
}
},
);
onTestFinished(() => s.unsubscribe());
// The publishingParticipants$ observable is derived from the current members of the
// livekitRoom and the rtc membership in order to publish the members that are publishing
@@ -513,9 +515,11 @@ describe("Publishing participants observations", () => {
const connection = setupRemoteConnection();
let observedPublishers: PublishingParticipant[][] = [];
const s = connection.participants$.subscribe((publishers) => {
observedPublishers.push(publishers);
});
const s = connection.remoteParticipantsWithTracks$.subscribe(
(publishers) => {
observedPublishers.push(publishers);
},
);
onTestFinished(() => s.unsubscribe());
let participants: RemoteParticipant[] = [

View File

@@ -179,12 +179,13 @@ export class Connection {
}
/**
* An observable of the participants that are publishing on this connection.
* An observable of the participants that are publishing on this connection. (Excluding our local participant)
* This is derived from `participantsIncludingSubscribers$` and `remoteTransports$`.
* It filters the participants to only those that are associated with a membership that claims to publish on this connection.
*/
public readonly participants$: Behavior<PublishingParticipant[]>;
public readonly remoteParticipantsWithTracks$: Behavior<
PublishingParticipant[]
>;
/**
* The media transport to connect to.
@@ -211,7 +212,9 @@ export class Connection {
this.transport = transport;
this.client = client;
this.participants$ = scope.behavior(
// REMOTE participants with track!!!
// this.remoteParticipantsWithTracks$
this.remoteParticipantsWithTracks$ = scope.behavior(
// only tracks remote participants
connectedParticipantsObserver(this.livekitRoom, {
additionalRoomEvents: [
@@ -219,10 +222,11 @@ export class Connection {
RoomEvent.TrackUnpublished,
],
}).pipe(
map((participants) => [
this.livekitRoom.localParticipant,
...participants,
]),
map((participants) => {
return participants.filter(
(participant) => participant.getTrackPublications().length > 0,
);
}),
),
[],
);

View File

@@ -55,8 +55,8 @@ export class ConnectionManagerData {
public getConnectionForTransport(
transport: LivekitTransport,
): Connection | undefined {
return this.store.get(this.getKey(transport))?.[0];
): Connection | null {
return this.store.get(this.getKey(transport))?.[0] ?? null;
}
public getParticipantForTransport(
@@ -181,7 +181,7 @@ export function createConnectionManager$({
// Map the connections to list of {connection, participants}[]
const listOfConnectionsWithPublishingParticipants =
connections.value.map((connection) => {
return connection.participants$.pipe(
return connection.remoteParticipantsWithTracks$.pipe(
map((participants) => ({
connection,
participants,

View File

@@ -30,13 +30,14 @@ const logger = rootLogger.getChild("MatrixLivekitMembers");
* or if it has no livekit transport at all.
*/
export interface MatrixLivekitMember {
participantId: string;
userId: string;
membership$: Behavior<CallMembership>;
participant$: Behavior<
LocalLivekitParticipant | RemoteLivekitParticipant | null
>;
connection$: Behavior<Connection | undefined>;
connection$: Behavior<Connection | null>;
// participantId: string; We do not want a participantId here since it will be generated by the jwt
// TODO decide if we can also drop the userId. Its in the matrix membership anyways.
userId: string;
}
interface Props {
@@ -96,7 +97,7 @@ export function createMatrixLivekitMembers$({
participants.find((p) => p.identity == participantId) ?? null;
const connection = transport
? managerData.getConnectionForTransport(transport)
: undefined;
: null;
yield {
keys: [participantId, membership.userId],