Merge pull request #1928 from matrix-org/robertlong/clone-streams

Clone and stop local media streams from mediaHandler
This commit is contained in:
Robert Long
2021-09-15 14:25:00 -07:00
committed by GitHub
2 changed files with 95 additions and 21 deletions
+10 -8
View File
@@ -816,9 +816,7 @@ export class MatrixCall extends EventEmitter {
for (const sender of this.screensharingSenders) {
this.peerConn.removeTrack(sender);
}
for (const track of this.localScreensharingStream.getTracks()) {
track.stop();
}
this.client.getMediaHandler().stopScreensharingStream(this.localScreensharingStream);
this.deleteFeedByStream(this.localScreensharingStream);
return false;
}
@@ -866,9 +864,7 @@ export class MatrixCall extends EventEmitter {
});
sender.replaceTrack(track);
for (const track of this.localScreensharingStream.getTracks()) {
track.stop();
}
this.client.getMediaHandler().stopScreensharingStream(this.localScreensharingStream);
this.deleteFeedByStream(this.localScreensharingStream);
return false;
@@ -1751,8 +1747,14 @@ export class MatrixCall extends EventEmitter {
logger.debug(`stopAllMedia (stream=${this.localUsermediaStream})`);
for (const feed of this.feeds) {
for (const track of feed.stream.getTracks()) {
track.stop();
if (feed.isLocal() && feed.purpose === SDPStreamMetadataPurpose.Usermedia) {
this.client.getMediaHandler().stopUserMediaStream(feed.stream);
} else if (feed.isLocal() && feed.purpose === SDPStreamMetadataPurpose.Screenshare) {
this.client.getMediaHandler().stopScreensharingStream(feed.stream);
} else {
for (const track of feed.stream.getTracks()) {
track.stop();
}
}
}
}
+85 -13
View File
@@ -22,6 +22,8 @@ import { logger } from "../logger";
export class MediaHandler {
private audioInput: string;
private videoInput: string;
private userMediaStreams: MediaStream[] = [];
private screensharingStreams: MediaStream[] = [];
/**
* Set an audio input device to use for MatrixCalls
@@ -45,27 +47,97 @@ export class MediaHandler {
* @returns {MediaStream} based on passed parameters
*/
public async getUserMediaStream(audio: boolean, video: boolean): Promise<MediaStream> {
const constraints = this.getUserMediaContraints(audio, video);
logger.log("Getting user media with constraints", constraints);
return await navigator.mediaDevices.getUserMedia(constraints);
let stream: MediaStream;
if (this.userMediaStreams.length === 0) {
const constraints = this.getUserMediaContraints(audio, video);
logger.log("Getting user media with constraints", constraints);
stream = await navigator.mediaDevices.getUserMedia(constraints);
} else {
stream = this.userMediaStreams[this.userMediaStreams.length - 1].clone();
}
this.userMediaStreams.push(stream);
return stream;
}
/**
* Stops all tracks on the provided usermedia stream
*/
public stopUserMediaStream(mediaStream: MediaStream) {
for (const track of mediaStream.getTracks()) {
track.stop();
}
const index = this.userMediaStreams.indexOf(mediaStream);
if (index !== -1) {
this.userMediaStreams.splice(index, 0);
}
}
/**
* @returns {MediaStream} based on passed parameters
*/
public async getScreensharingStream(desktopCapturerSourceId: string): Promise<MediaStream> {
const screenshareConstraints = this.getScreenshareContraints(desktopCapturerSourceId);
if (!screenshareConstraints) return null;
public async getScreensharingStream(desktopCapturerSourceId: string): Promise<MediaStream | null> {
let stream: MediaStream;
if (desktopCapturerSourceId) {
// We are using Electron
logger.debug("Getting screen stream using getUserMedia()...");
return await navigator.mediaDevices.getUserMedia(screenshareConstraints);
if (this.screensharingStreams.length === 0) {
const screenshareConstraints = this.getScreenshareContraints(desktopCapturerSourceId);
if (!screenshareConstraints) return null;
if (desktopCapturerSourceId) {
// We are using Electron
logger.debug("Getting screen stream using getUserMedia()...");
stream = await navigator.mediaDevices.getUserMedia(screenshareConstraints);
} else {
// We are not using Electron
logger.debug("Getting screen stream using getDisplayMedia()...");
stream = await navigator.mediaDevices.getDisplayMedia(screenshareConstraints);
}
} else {
// We are not using Electron
logger.debug("Getting screen stream using getDisplayMedia()...");
return await navigator.mediaDevices.getDisplayMedia(screenshareConstraints);
stream = this.screensharingStreams[this.screensharingStreams.length - 1].clone();
}
this.screensharingStreams.push(stream);
return stream;
}
/**
* Stops all tracks on the provided screensharing stream
*/
public stopScreensharingStream(mediaStream: MediaStream) {
for (const track of mediaStream.getTracks()) {
track.stop();
}
const index = this.userMediaStreams.indexOf(mediaStream);
if (index !== -1) {
this.userMediaStreams.splice(index, 0);
}
}
/**
* Stops all local media tracks
*/
public stopAllStreams() {
for (const stream of this.userMediaStreams) {
for (const track of stream.getTracks()) {
track.stop();
}
}
for (const stream of this.screensharingStreams) {
for (const track of stream.getTracks()) {
track.stop();
}
}
this.userMediaStreams = [];
this.screensharingStreams = [];
}
private getUserMediaContraints(audio: boolean, video: boolean): MediaStreamConstraints {