From 97137c7213ef92e808a0cdccdbd98b64597078e4 Mon Sep 17 00:00:00 2001 From: Nikola Novakovic Date: Tue, 2 Nov 2021 17:35:30 -0400 Subject: [PATCH] Add optional encoding params to publish * Allow specifing encoding params when publishing media stream --- src/client.ts | 4 +-- src/stream.ts | 81 +++++++++++++++++++++++++-------------------------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/client.ts b/src/client.ts index 5430bf30..2673c96c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -170,11 +170,11 @@ export default class Client { return this.transports[Role.sub].pc.getStats(selector); } - publish(stream: LocalStream) { + publish(stream: LocalStream, encodingParams?: RTCRtpEncodingParameters[]) { if (!this.transports) { throw Error(ERR_NO_SESSION); } - stream.publish(this.transports[Role.pub]); + stream.publish(this.transports[Role.pub], encodingParams); } createDataChannel(label: string) { diff --git a/src/stream.ts b/src/stream.ts index 9d40110c..35819fb6 100644 --- a/src/stream.ts +++ b/src/stream.ts @@ -159,6 +159,7 @@ export class LocalStream extends MediaStream { constraints: Constraints; pc?: RTCPeerConnection; api?: RTCDataChannel; + encodingParams?: RTCRtpEncodingParameters[]; constructor(stream: MediaStream, constraints: Constraints) { super(stream); @@ -203,50 +204,47 @@ export class LocalStream extends MediaStream { private publishTrack(track: MediaStreamTrack) { if (this.pc) { - if (track.kind === 'video' && this.constraints.simulcast) { - const idx = resolutions.indexOf(this.constraints.resolution); - const encodings: RTCRtpEncodingParameters[] = [ - { - rid: 'f', - maxBitrate: VideoConstraints[resolutions[idx]].encodings.maxBitrate, - maxFramerate: VideoConstraints[resolutions[idx]].encodings.maxFramerate, - }, - ]; - - if (idx - 1 >= 0) { - encodings.push({ - rid: 'h', - scaleResolutionDownBy: 2.0, - maxBitrate: VideoConstraints[resolutions[idx - 1]].encodings.maxBitrate, - maxFramerate: VideoConstraints[resolutions[idx - 1]].encodings.maxFramerate, - }); - } + const init: RTCRtpTransceiverInit = { + streams: [this], + direction: 'sendonly', + }; + if (track.kind === 'video') { + if (this.encodingParams) { + init.sendEncodings = this.encodingParams + } else if (this.constraints.simulcast) { + const idx = resolutions.indexOf(this.constraints.resolution); + const encodings: RTCRtpEncodingParameters[] = [ + { + rid: 'f', + maxBitrate: VideoConstraints[resolutions[idx]].encodings.maxBitrate, + maxFramerate: VideoConstraints[resolutions[idx]].encodings.maxFramerate, + }, + ]; + + if (idx - 1 >= 0) { + encodings.push({ + rid: 'h', + scaleResolutionDownBy: 2.0, + maxBitrate: VideoConstraints[resolutions[idx - 1]].encodings.maxBitrate, + maxFramerate: VideoConstraints[resolutions[idx - 1]].encodings.maxFramerate, + }); + } - if (idx - 2 >= 0) { - encodings.push({ - rid: 'q', - scaleResolutionDownBy: 4.0, - maxBitrate: VideoConstraints[resolutions[idx - 2]].encodings.maxBitrate, - maxFramerate: VideoConstraints[resolutions[idx - 2]].encodings.maxFramerate, - }); - } - const transceiver = this.pc.addTransceiver(track, { - streams: [this], - direction: 'sendonly', - sendEncodings: encodings, - }); - this.setPreferredCodec(transceiver, track.kind); - } else { - const init: RTCRtpTransceiverInit = { - streams: [this], - direction: 'sendonly', - }; - if (track.kind === 'video') { + if (idx - 2 >= 0) { + encodings.push({ + rid: 'q', + scaleResolutionDownBy: 4.0, + maxBitrate: VideoConstraints[resolutions[idx - 2]].encodings.maxBitrate, + maxFramerate: VideoConstraints[resolutions[idx - 2]].encodings.maxFramerate, + }); + } + init.sendEncodings = encodings + } else { init.sendEncodings = [VideoConstraints[this.constraints.resolution].encodings]; } - const transceiver = this.pc.addTransceiver(track, init); - this.setPreferredCodec(transceiver, track.kind); } + const transceiver = this.pc.addTransceiver(track, init); + this.setPreferredCodec(transceiver, track.kind); } } @@ -327,9 +325,10 @@ export class LocalStream extends MediaStream { return stream.getVideoTracks()[0]; } - publish(transport: Transport) { + publish(transport: Transport, encodingParams?: RTCRtpEncodingParameters[]) { this.pc = transport.pc; this.api = transport.api; + this.encodingParams = encodingParams; this.getTracks().forEach(this.publishTrack.bind(this)); }