You've already forked matrix-js-sdk
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:
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user