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
Use MediaHandler
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
@@ -144,6 +144,7 @@ import { IHierarchyRoom, ISpaceSummaryEvent, ISpaceSummaryRoom } from "./@types/
|
||||
import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules";
|
||||
import { IThreepid } from "./@types/threepids";
|
||||
import { CryptoStore } from "./crypto/store/base";
|
||||
import { MediaHandler } from "./webrtc/mediaHandler";
|
||||
|
||||
export type Store = IStore;
|
||||
export type SessionStore = WebStorageSessionStore;
|
||||
@@ -733,6 +734,7 @@ export class MatrixClient extends EventEmitter {
|
||||
protected checkTurnServersIntervalID: number;
|
||||
protected exportedOlmDeviceToImport: IOlmDevice;
|
||||
protected txnCtr = 0;
|
||||
protected mediaHandler = new MediaHandler();
|
||||
|
||||
constructor(opts: IMatrixClientCreateOpts) {
|
||||
super();
|
||||
@@ -1240,6 +1242,13 @@ export class MatrixClient extends EventEmitter {
|
||||
return this.canSupportVoip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {MediaHandler}
|
||||
*/
|
||||
public getMediaHandler(): MediaHandler {
|
||||
return this.mediaHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether VoIP calls are forced to use only TURN
|
||||
* candidates. This is the same as the forceTURN option
|
||||
|
||||
@@ -49,8 +49,6 @@ export * from "./content-repo";
|
||||
export * as ContentHelpers from "./content-helpers";
|
||||
export {
|
||||
createNewMatrixCall,
|
||||
setAudioInput as setMatrixCallAudioInput,
|
||||
setVideoInput as setMatrixCallVideoInput,
|
||||
} from "./webrtc/call";
|
||||
|
||||
// expose the underlying request object so different environments can use
|
||||
|
||||
@@ -212,11 +212,6 @@ export enum CallErrorCode {
|
||||
Transfered = 'transferred',
|
||||
}
|
||||
|
||||
enum ConstraintsType {
|
||||
Audio = "audio",
|
||||
Video = "video",
|
||||
}
|
||||
|
||||
/**
|
||||
* The version field that we set in m.call.* events
|
||||
*/
|
||||
@@ -337,11 +332,7 @@ export class MatrixCall extends EventEmitter {
|
||||
* @throws If you have not specified a listener for 'error' events.
|
||||
*/
|
||||
public async placeVoiceCall(): Promise<void> {
|
||||
logger.debug("placeVoiceCall");
|
||||
this.checkForErrorListener();
|
||||
const constraints = getUserMediaContraints(ConstraintsType.Audio);
|
||||
this.type = CallType.Voice;
|
||||
await this.placeCallWithConstraints(constraints);
|
||||
await this.placeCall(true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,11 +340,7 @@ export class MatrixCall extends EventEmitter {
|
||||
* @throws If you have not specified a listener for 'error' events.
|
||||
*/
|
||||
public async placeVideoCall(): Promise<void> {
|
||||
logger.debug("placeVideoCall");
|
||||
this.checkForErrorListener();
|
||||
const constraints = getUserMediaContraints(ConstraintsType.Video);
|
||||
this.type = CallType.Video;
|
||||
await this.placeCallWithConstraints(constraints);
|
||||
await this.placeCall(true, true);
|
||||
}
|
||||
|
||||
public getOpponentMember(): RoomMember {
|
||||
@@ -672,17 +659,14 @@ export class MatrixCall extends EventEmitter {
|
||||
logger.debug(`Answering call ${this.callId} of type ${this.type}`);
|
||||
|
||||
if (!this.localUsermediaStream && !this.waitForLocalAVStream) {
|
||||
const constraints = getUserMediaContraints(
|
||||
this.type == CallType.Video ?
|
||||
ConstraintsType.Video:
|
||||
ConstraintsType.Audio,
|
||||
);
|
||||
logger.log("Getting user media with constraints", constraints);
|
||||
this.setState(CallState.WaitLocalMedia);
|
||||
this.waitForLocalAVStream = true;
|
||||
|
||||
try {
|
||||
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||
const mediaStream = await this.client.getMediaHandler().getUserMediaStream(
|
||||
true,
|
||||
this.type === CallType.Video,
|
||||
);
|
||||
this.waitForLocalAVStream = false;
|
||||
this.gotUserMediaForAnswer(mediaStream);
|
||||
} catch (e) {
|
||||
@@ -797,7 +781,7 @@ export class MatrixCall extends EventEmitter {
|
||||
logger.debug(`Set screensharing enabled? ${enabled}`);
|
||||
if (enabled) {
|
||||
try {
|
||||
const stream = await getScreensharingStream(desktopCapturerSourceId);
|
||||
const stream = await this.client.getMediaHandler().getScreensharingStream(desktopCapturerSourceId);
|
||||
if (!stream) return false;
|
||||
this.pushLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare);
|
||||
return true;
|
||||
@@ -832,7 +816,7 @@ export class MatrixCall extends EventEmitter {
|
||||
logger.debug(`Set screensharing enabled? ${enabled} using replaceTrack()`);
|
||||
if (enabled) {
|
||||
try {
|
||||
const stream = await getScreensharingStream(desktopCapturerSourceId);
|
||||
const stream = await this.client.getMediaHandler().getScreensharingStream(desktopCapturerSourceId);
|
||||
if (!stream) return false;
|
||||
|
||||
const track = stream.getTracks().find((track) => {
|
||||
@@ -1809,8 +1793,18 @@ export class MatrixCall extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
private async placeCallWithConstraints(constraints: MediaStreamConstraints): Promise<void> {
|
||||
logger.log("Getting user media with constraints", constraints);
|
||||
/**
|
||||
* Place a call to this room.
|
||||
* @throws if you have not specified a listener for 'error' events.
|
||||
* @throws if have passed audio=false.
|
||||
*/
|
||||
public async placeCall(audio: boolean, video: boolean): Promise<void> {
|
||||
logger.debug(`placeCall audio=${audio} video=${video}`);
|
||||
if (!audio) {
|
||||
throw new Error("You CANNOT start a call without audio");
|
||||
}
|
||||
this.type = video ? CallType.Video : CallType.Voice;
|
||||
this.checkForErrorListener();
|
||||
// XXX Find a better way to do this
|
||||
this.client.callEventHandler.calls.set(this.callId, this);
|
||||
this.setState(CallState.WaitLocalMedia);
|
||||
@@ -1828,7 +1822,7 @@ export class MatrixCall extends EventEmitter {
|
||||
this.peerConn = this.createPeerConnection();
|
||||
|
||||
try {
|
||||
const mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||
const mediaStream = await this.client.getMediaHandler().getUserMediaStream(audio, video);
|
||||
this.gotUserMediaForInvite(mediaStream);
|
||||
} catch (e) {
|
||||
this.getUserMediaFailed(e);
|
||||
@@ -1922,96 +1916,12 @@ export class MatrixCall extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
async function getScreensharingStream(desktopCapturerSourceId: string): Promise<MediaStream> {
|
||||
const screenshareConstraints = getScreenshareContraints(desktopCapturerSourceId);
|
||||
if (!screenshareConstraints) return null;
|
||||
|
||||
if (desktopCapturerSourceId) {
|
||||
// We are using Electron
|
||||
logger.debug("Getting screen stream using getUserMedia()...");
|
||||
return await navigator.mediaDevices.getUserMedia(screenshareConstraints);
|
||||
} else {
|
||||
// We are not using Electron
|
||||
logger.debug("Getting screen stream using getDisplayMedia()...");
|
||||
return await navigator.mediaDevices.getDisplayMedia(screenshareConstraints);
|
||||
}
|
||||
}
|
||||
|
||||
function setTracksEnabled(tracks: Array<MediaStreamTrack>, enabled: boolean): void {
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
tracks[i].enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
function getUserMediaContraints(type: ConstraintsType): MediaStreamConstraints {
|
||||
const isWebkit = !!navigator.webkitGetUserMedia;
|
||||
|
||||
switch (type) {
|
||||
case ConstraintsType.Audio: {
|
||||
return {
|
||||
audio: {
|
||||
deviceId: audioInput ? { ideal: audioInput } : undefined,
|
||||
},
|
||||
video: false,
|
||||
};
|
||||
}
|
||||
case ConstraintsType.Video: {
|
||||
return {
|
||||
audio: {
|
||||
deviceId: audioInput ? { ideal: audioInput } : undefined,
|
||||
}, video: {
|
||||
deviceId: videoInput ? { ideal: videoInput } : undefined,
|
||||
/* We want 640x360. Chrome will give it only if we ask exactly,
|
||||
FF refuses entirely if we ask exactly, so have to ask for ideal
|
||||
instead
|
||||
XXX: Is this still true?
|
||||
*/
|
||||
width: isWebkit ? { exact: 640 } : { ideal: 640 },
|
||||
height: isWebkit ? { exact: 360 } : { ideal: 360 },
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getScreenshareContraints(desktopCapturerSourceId?: string): DesktopCapturerConstraints {
|
||||
if (desktopCapturerSourceId) {
|
||||
logger.debug("Using desktop capturer source", desktopCapturerSourceId);
|
||||
return {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: {
|
||||
chromeMediaSource: "desktop",
|
||||
chromeMediaSourceId: desktopCapturerSourceId,
|
||||
},
|
||||
},
|
||||
};
|
||||
} else {
|
||||
logger.debug("Not using desktop capturer source");
|
||||
return {
|
||||
audio: false,
|
||||
video: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let audioInput: string;
|
||||
let videoInput: string;
|
||||
/**
|
||||
* Set an audio input device to use for MatrixCalls
|
||||
* @function
|
||||
* @param {string=} deviceId the identifier for the device
|
||||
* undefined treated as unset
|
||||
*/
|
||||
export function setAudioInput(deviceId: string): void { audioInput = deviceId; }
|
||||
/**
|
||||
* Set a video input device to use for MatrixCalls
|
||||
* @function
|
||||
* @param {string=} deviceId the identifier for the device
|
||||
* undefined treated as unset
|
||||
*/
|
||||
export function setVideoInput(deviceId: string): void { videoInput = deviceId; }
|
||||
|
||||
/**
|
||||
* DEPRECATED
|
||||
* Use client.createCall()
|
||||
|
||||
Reference in New Issue
Block a user