1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-01 04:43:29 +03:00

Add call upgrade support

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner
2021-09-18 12:32:13 +02:00
parent f24840d09c
commit a4cacbc73a

View File

@@ -391,6 +391,19 @@ export class MatrixCall extends EventEmitter {
}); });
} }
public get hasLocalUserMediaAudioTrack(): boolean {
return this.localUsermediaStream?.getAudioTracks().length > 0;
}
public get hasRemoteUserMediaAudioTrack(): boolean {
return this.getRemoteFeeds().some((feed) => {
return (
feed.purpose === SDPStreamMetadataPurpose.Usermedia &&
feed.stream.getAudioTracks().length > 0
);
});
}
public get localUsermediaFeed(): CallFeed { public get localUsermediaFeed(): CallFeed {
return this.getLocalFeeds().find((feed) => feed.purpose === SDPStreamMetadataPurpose.Usermedia); return this.getLocalFeeds().find((feed) => feed.purpose === SDPStreamMetadataPurpose.Usermedia);
} }
@@ -774,6 +787,49 @@ export class MatrixCall extends EventEmitter {
this.sendVoipEvent(EventType.CallReject, {}); this.sendVoipEvent(EventType.CallReject, {});
} }
/**
* Adds a video track to a voice call
* @returns new mute state
*/
private async upgradeCall(
audio: boolean, video: boolean,
): Promise<void> {
// We don't do call downgrades
if (!audio && !video) return;
if (!this.opponentSupportsSDPStreamMetadata()) return;
try {
const upgradeAudio = audio && !this.hasLocalUserMediaAudioTrack;
const upgradeVideo = video && !this.hasLocalUserMediaVideoTrack;
logger.debug(`Upgrading call audio=${upgradeAudio} video=${upgradeVideo}`);
const stream = await this.client.getMediaHandler().getUserMediaStream(upgradeAudio, upgradeVideo);
if (upgradeAudio && upgradeVideo) {
if (this.hasLocalUserMediaAudioTrack) return;
if (this.hasLocalUserMediaVideoTrack) return;
this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Usermedia);
} else if (upgradeAudio) {
if (this.hasLocalUserMediaAudioTrack) return;
const audioTrack = stream.getAudioTracks()[0];
this.localUsermediaStream.addTrack(audioTrack);
this.peerConn.addTrack(audioTrack, this.localUsermediaStream);
} else if (upgradeVideo) {
if (this.hasLocalUserMediaVideoTrack) return;
const videoTrack = stream.getVideoTracks()[0];
this.localUsermediaStream.addTrack(videoTrack);
this.peerConn.addTrack(videoTrack, this.localUsermediaStream);
}
} catch (error) {
logger.error("Failed to upgrade the call", error);
this.emit(CallEvent.Error,
new CallError(CallErrorCode.NoUserMedia, "Failed to get camera access: ", error),
);
}
}
/** /**
* Returns true if this.remoteSDPStreamMetadata is defined, otherwise returns false * Returns true if this.remoteSDPStreamMetadata is defined, otherwise returns false
* @returns {boolean} can screenshare * @returns {boolean} can screenshare
@@ -888,10 +944,16 @@ export class MatrixCall extends EventEmitter {
/** /**
* Set whether our outbound video should be muted or not. * Set whether our outbound video should be muted or not.
* @param {boolean} muted True to mute the outbound video. * @param {boolean} muted True to mute the outbound video.
* @returns the new mute state
*/ */
public setLocalVideoMuted(muted: boolean): void { public async setLocalVideoMuted(muted: boolean): Promise<boolean> {
if (!this.hasLocalUserMediaVideoTrack && !muted) {
await this.upgradeCall(false, true);
return this.isLocalVideoMuted();
}
this.localUsermediaFeed?.setVideoMuted(muted); this.localUsermediaFeed?.setVideoMuted(muted);
this.updateMuteStatus(); this.updateMuteStatus();
return this.isLocalVideoMuted();
} }
/** /**
@@ -910,8 +972,13 @@ export class MatrixCall extends EventEmitter {
/** /**
* Set whether the microphone should be muted or not. * Set whether the microphone should be muted or not.
* @param {boolean} muted True to mute the mic. * @param {boolean} muted True to mute the mic.
* @returns the new mute state
*/ */
public setMicrophoneMuted(muted: boolean): void { public async setMicrophoneMuted(muted: boolean): Promise<boolean> {
if (!this.hasLocalUserMediaAudioTrack && !muted) {
await this.upgradeCall(false, true);
return this.isMicrophoneMuted();
}
this.localUsermediaFeed?.setAudioMuted(muted); this.localUsermediaFeed?.setAudioMuted(muted);
this.updateMuteStatus(); this.updateMuteStatus();
} }