You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-25 05:23:13 +03:00
Basic implementation of MSC3291
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
@@ -36,6 +36,7 @@ import {
|
|||||||
SDPStreamMetadataPurpose,
|
SDPStreamMetadataPurpose,
|
||||||
SDPStreamMetadata,
|
SDPStreamMetadata,
|
||||||
SDPStreamMetadataKey,
|
SDPStreamMetadataKey,
|
||||||
|
MCallSDPStreamMetadataChanged,
|
||||||
} from './callEventTypes';
|
} from './callEventTypes';
|
||||||
import { CallFeed } from './callFeed';
|
import { CallFeed } from './callFeed';
|
||||||
|
|
||||||
@@ -353,8 +354,6 @@ export class MatrixCall extends EventEmitter {
|
|||||||
this.makingOffer = false;
|
this.makingOffer = false;
|
||||||
|
|
||||||
this.remoteOnHold = false;
|
this.remoteOnHold = false;
|
||||||
this.micMuted = false;
|
|
||||||
this.vidMuted = false;
|
|
||||||
|
|
||||||
this.feeds = [];
|
this.feeds = [];
|
||||||
|
|
||||||
@@ -398,6 +397,14 @@ export class MatrixCall extends EventEmitter {
|
|||||||
return this.remoteAssertedIdentity;
|
return this.remoteAssertedIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get localUsermediaFeed(): CallFeed {
|
||||||
|
return this.getLocalFeeds().find((feed) => feed.purpose === SDPStreamMetadataPurpose.Usermedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFeedByStreamId(streamId: string): CallFeed {
|
||||||
|
return this.getFeeds().find((feed) => feed.stream.id === streamId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of all CallFeeds
|
* Returns an array of all CallFeeds
|
||||||
* @returns {Array<CallFeed>} CallFeeds
|
* @returns {Array<CallFeed>} CallFeeds
|
||||||
@@ -427,10 +434,12 @@ export class MatrixCall extends EventEmitter {
|
|||||||
* @returns {SDPStreamMetadata} localSDPStreamMetadata
|
* @returns {SDPStreamMetadata} localSDPStreamMetadata
|
||||||
*/
|
*/
|
||||||
private getLocalSDPStreamMetadata(): SDPStreamMetadata {
|
private getLocalSDPStreamMetadata(): SDPStreamMetadata {
|
||||||
const metadata = {};
|
const metadata: SDPStreamMetadata = {};
|
||||||
for (const localFeed of this.getLocalFeeds()) {
|
for (const localFeed of this.getLocalFeeds()) {
|
||||||
metadata[localFeed.stream.id] = {
|
metadata[localFeed.stream.id] = {
|
||||||
purpose: localFeed.purpose,
|
purpose: localFeed.purpose,
|
||||||
|
audio_muted: localFeed.isAudioMuted(),
|
||||||
|
video_muted: localFeed.isVideoMuted(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
logger.debug("Got local SDPStreamMetadata", metadata);
|
logger.debug("Got local SDPStreamMetadata", metadata);
|
||||||
@@ -455,6 +464,8 @@ export class MatrixCall extends EventEmitter {
|
|||||||
|
|
||||||
const userId = this.getOpponentMember().userId;
|
const userId = this.getOpponentMember().userId;
|
||||||
const purpose = this.remoteSDPStreamMetadata[stream.id].purpose;
|
const purpose = this.remoteSDPStreamMetadata[stream.id].purpose;
|
||||||
|
const audioMuted = this.remoteSDPStreamMetadata[stream.id].audio_muted;
|
||||||
|
const videoMuted = this.remoteSDPStreamMetadata[stream.id].video_muted;
|
||||||
|
|
||||||
if (!purpose) {
|
if (!purpose) {
|
||||||
logger.warn(`Ignoring stream with id ${stream.id} because we didn't get any metadata about it`);
|
logger.warn(`Ignoring stream with id ${stream.id} because we didn't get any metadata about it`);
|
||||||
@@ -467,7 +478,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
if (existingFeed) {
|
if (existingFeed) {
|
||||||
existingFeed.setNewStream(stream);
|
existingFeed.setNewStream(stream);
|
||||||
} else {
|
} else {
|
||||||
this.feeds.push(new CallFeed(stream, userId, purpose, this.client, this.roomId));
|
this.feeds.push(new CallFeed(stream, userId, purpose, this.client, this.roomId, audioMuted, videoMuted));
|
||||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -494,7 +505,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
|
|
||||||
// Try to find a feed with the same stream id as the new stream,
|
// Try to find a feed with the same stream id as the new stream,
|
||||||
// if we find it replace the old stream with the new one
|
// if we find it replace the old stream with the new one
|
||||||
const feed = this.feeds.find((feed) => feed.stream.id === stream.id);
|
const feed = this.getFeedByStreamId(stream.id);
|
||||||
if (feed) {
|
if (feed) {
|
||||||
feed.setNewStream(stream);
|
feed.setNewStream(stream);
|
||||||
} else {
|
} else {
|
||||||
@@ -513,7 +524,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
if (existingFeed) {
|
if (existingFeed) {
|
||||||
existingFeed.setNewStream(stream);
|
existingFeed.setNewStream(stream);
|
||||||
} else {
|
} else {
|
||||||
this.feeds.push(new CallFeed(stream, userId, purpose, this.client, this.roomId));
|
this.feeds.push(new CallFeed(stream, userId, purpose, this.client, this.roomId, true, true));
|
||||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,7 +562,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
private deleteFeedByStream(stream: MediaStream) {
|
private deleteFeedByStream(stream: MediaStream) {
|
||||||
logger.debug(`Removing feed with stream id ${stream.id}`);
|
logger.debug(`Removing feed with stream id ${stream.id}`);
|
||||||
|
|
||||||
const feed = this.feeds.find((feed) => feed.stream.id === stream.id);
|
const feed = this.getFeedByStreamId(stream.id);
|
||||||
if (!feed) {
|
if (!feed) {
|
||||||
logger.warn(`Didn't find the feed with stream id ${stream.id} to delete`);
|
logger.warn(`Didn't find the feed with stream id ${stream.id} to delete`);
|
||||||
return;
|
return;
|
||||||
@@ -887,7 +898,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
* @param {boolean} muted True to mute the outbound video.
|
* @param {boolean} muted True to mute the outbound video.
|
||||||
*/
|
*/
|
||||||
setLocalVideoMuted(muted: boolean) {
|
setLocalVideoMuted(muted: boolean) {
|
||||||
this.vidMuted = muted;
|
this.localUsermediaFeed?.setVideoMuted(muted);
|
||||||
this.updateMuteStatus();
|
this.updateMuteStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,8 +912,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
* (including if the call is not set up yet).
|
* (including if the call is not set up yet).
|
||||||
*/
|
*/
|
||||||
isLocalVideoMuted(): boolean {
|
isLocalVideoMuted(): boolean {
|
||||||
if (this.type === CallType.Voice) return true;
|
return this.localUsermediaFeed?.isVideoMuted();
|
||||||
return this.vidMuted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -910,7 +920,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
* @param {boolean} muted True to mute the mic.
|
* @param {boolean} muted True to mute the mic.
|
||||||
*/
|
*/
|
||||||
setMicrophoneMuted(muted: boolean) {
|
setMicrophoneMuted(muted: boolean) {
|
||||||
this.micMuted = muted;
|
this.localUsermediaFeed?.setAudioMuted(muted);
|
||||||
this.updateMuteStatus();
|
this.updateMuteStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +934,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
* is not set up yet).
|
* is not set up yet).
|
||||||
*/
|
*/
|
||||||
isMicrophoneMuted(): boolean {
|
isMicrophoneMuted(): boolean {
|
||||||
return this.micMuted;
|
return this.localUsermediaFeed?.isAudioMuted();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -987,14 +997,14 @@ export class MatrixCall extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateMuteStatus() {
|
private updateMuteStatus() {
|
||||||
if (!this.localAVStream) {
|
this.sendVoipEvent(EventType.CallSDPStreamMetadataChanged, {
|
||||||
return;
|
[SDPStreamMetadataKey]: this.getLocalSDPStreamMetadata(),
|
||||||
}
|
});
|
||||||
|
|
||||||
|
const micShouldBeMuted = this.localUsermediaFeed?.isAudioMuted() || this.remoteOnHold;
|
||||||
|
const vidShouldBeMuted = this.localUsermediaFeed?.isVideoMuted() || this.remoteOnHold;
|
||||||
|
|
||||||
const micShouldBeMuted = this.micMuted || this.remoteOnHold;
|
|
||||||
setTracksEnabled(this.localAVStream.getAudioTracks(), !micShouldBeMuted);
|
setTracksEnabled(this.localAVStream.getAudioTracks(), !micShouldBeMuted);
|
||||||
|
|
||||||
const vidShouldBeMuted = this.vidMuted || this.remoteOnHold;
|
|
||||||
setTracksEnabled(this.localAVStream.getVideoTracks(), !vidShouldBeMuted);
|
setTracksEnabled(this.localAVStream.getVideoTracks(), !vidShouldBeMuted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,6 +1328,19 @@ export class MatrixCall extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onSDPStreamMetadataChangedReceived(event: MatrixEvent): void {
|
||||||
|
// TODO: What if the values is missing
|
||||||
|
// TODO: Handle purpose changes
|
||||||
|
const content = event.getContent<MCallSDPStreamMetadataChanged>();
|
||||||
|
const metadata = content[SDPStreamMetadataKey];
|
||||||
|
this.remoteSDPStreamMetadata = metadata;
|
||||||
|
for (const feed of this.getRemoteFeeds()) {
|
||||||
|
const streamId = feed.stream.id;
|
||||||
|
feed.setAudioMuted(metadata[streamId].audio_muted);
|
||||||
|
feed.setVideoMuted(metadata[streamId].video_muted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async onAssertedIdentityReceived(event: MatrixEvent) {
|
async onAssertedIdentityReceived(event: MatrixEvent) {
|
||||||
if (!event.getContent().asserted_identity) return;
|
if (!event.getContent().asserted_identity) return;
|
||||||
|
|
||||||
|
|||||||
@@ -297,6 +297,15 @@ export class CallEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
call.onAssertedIdentityReceived(event);
|
call.onAssertedIdentityReceived(event);
|
||||||
|
} else if (event.getType() === EventType.CallSDPStreamMetadataChanged) {
|
||||||
|
if (!call) return;
|
||||||
|
|
||||||
|
if (event.getContent().party_id === call.ourPartyId) {
|
||||||
|
// Ignore remote echo
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
call.onSDPStreamMetadataChangedReceived(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user