mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: simulcast configuration
parent
3d978e1c46
commit
ffcb56cc0d
|
@ -927,7 +927,7 @@ export class Stream {
|
||||||
audio: this.hasAudio,
|
audio: this.hasAudio,
|
||||||
video: this.hasVideo,
|
video: this.hasVideo,
|
||||||
},
|
},
|
||||||
simulcast: false,
|
simulcast: this.session.openvidu.advancedConfiguration.enableSimulcastExperimental || false,
|
||||||
onIceCandidate: this.connection.sendIceCandidate.bind(this.connection),
|
onIceCandidate: this.connection.sendIceCandidate.bind(this.connection),
|
||||||
onIceConnectionStateException: (exceptionName: ExceptionEventName, message: string, data?: any) => { this.session.emitEvent('exception', [new ExceptionEvent(this.session, exceptionName, this, message, data)]) },
|
onIceConnectionStateException: (exceptionName: ExceptionEventName, message: string, data?: any) => { this.session.emitEvent('exception', [new ExceptionEvent(this.session, exceptionName, this, message, data)]) },
|
||||||
iceServers: this.getIceServersConf(),
|
iceServers: this.getIceServersConf(),
|
||||||
|
|
|
@ -71,4 +71,11 @@ export interface OpenViduAdvancedConfiguration {
|
||||||
*/
|
*/
|
||||||
noStreamPlayingEventExceptionTimeout?: number;
|
noStreamPlayingEventExceptionTimeout?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable simulcast for Publishers or not.
|
||||||
|
*
|
||||||
|
* Default to `false`.
|
||||||
|
*/
|
||||||
|
enableSimulcastExperimental?: boolean;
|
||||||
|
|
||||||
}
|
}
|
|
@ -30,6 +30,49 @@ const logger: OpenViduLogger = OpenViduLogger.getInstance();
|
||||||
*/
|
*/
|
||||||
let platform: PlatformUtils;
|
let platform: PlatformUtils;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table of sender video encodings for simulcast.
|
||||||
|
* Note that this is just a polite request, but the browser is free to honor it
|
||||||
|
* or just play by its own rules.
|
||||||
|
*
|
||||||
|
* Chrome imposes some restrictions based on the size of the video, max bitrate,
|
||||||
|
* and available bandwidth. Check here for the video size table:
|
||||||
|
* https://chromium.googlesource.com/external/webrtc/+/master/media/engine/simulcast.cc#90
|
||||||
|
*
|
||||||
|
* | Size (px) | Bitrate (kbps) | Max Layers |
|
||||||
|
* |----------:|---------------:|-----------:|
|
||||||
|
* | 1920x1080 | 5000 | 3 |
|
||||||
|
* | 1280x720 | 2500 | 3 |
|
||||||
|
* | 960x540 | 1200 | 3 |
|
||||||
|
* | 640x360 | 700 | 2 |
|
||||||
|
* | 480x270 | 450 | 2 |
|
||||||
|
* | 320x180 | 200 | 1 |
|
||||||
|
*/
|
||||||
|
const simulcastVideoEncodings: RTCRtpEncodingParameters[] = [
|
||||||
|
{
|
||||||
|
rid: "r0",
|
||||||
|
maxBitrate: 700000,
|
||||||
|
|
||||||
|
// TODO: Remove for final version; leave the browser decide:
|
||||||
|
// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
|
||||||
|
// > If the scaleResolutionDownBy attribues of sendEncodings are still
|
||||||
|
// > undefined, initialize each encoding's scaleResolutionDownBy to
|
||||||
|
// > 2^(length of sendEncodings - encoding index - 1). This results in
|
||||||
|
// > smaller-to-larger resolutions where the last encoding has no scaling
|
||||||
|
// > applied to it, e.g. 4:2:1 if the length is 3.
|
||||||
|
scaleResolutionDownBy: 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rid: "r1",
|
||||||
|
maxBitrate: 800000,
|
||||||
|
scaleResolutionDownBy: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rid: "r2",
|
||||||
|
maxBitrate: 900000,
|
||||||
|
scaleResolutionDownBy: 1,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export interface WebRtcPeerConfiguration {
|
export interface WebRtcPeerConfiguration {
|
||||||
mediaConstraints: {
|
mediaConstraints: {
|
||||||
|
@ -64,7 +107,7 @@ export class WebRtcPeer {
|
||||||
...configuration,
|
...configuration,
|
||||||
iceServers:
|
iceServers:
|
||||||
!!configuration.iceServers &&
|
!!configuration.iceServers &&
|
||||||
configuration.iceServers.length > 0
|
configuration.iceServers.length > 0
|
||||||
? configuration.iceServers
|
? configuration.iceServers
|
||||||
: freeice(),
|
: freeice(),
|
||||||
mediaStream:
|
mediaStream:
|
||||||
|
@ -127,6 +170,8 @@ export class WebRtcPeer {
|
||||||
if ("addTransceiver" in this.pc) {
|
if ("addTransceiver" in this.pc) {
|
||||||
logger.debug("[createOffer] Method RTCPeerConnection.addTransceiver() is available; using it");
|
logger.debug("[createOffer] Method RTCPeerConnection.addTransceiver() is available; using it");
|
||||||
|
|
||||||
|
// Spec doc: https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
|
||||||
|
|
||||||
if (this.configuration.mode !== "recvonly") {
|
if (this.configuration.mode !== "recvonly") {
|
||||||
// To send media, assume that all desired media tracks
|
// To send media, assume that all desired media tracks
|
||||||
// have been already added by higher level code to our
|
// have been already added by higher level code to our
|
||||||
|
@ -138,11 +183,14 @@ export class WebRtcPeer {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const track of this.configuration.mediaStream.getTracks()) {
|
for (const track of this.configuration.mediaStream.getTracks()) {
|
||||||
this.pc.addTransceiver(track, {
|
const tcInit: RTCRtpTransceiverInit = {
|
||||||
direction: this.configuration.mode,
|
direction: this.configuration.mode,
|
||||||
streams: [this.configuration.mediaStream],
|
streams: [this.configuration.mediaStream],
|
||||||
sendEncodings: [],
|
};
|
||||||
});
|
if (this.configuration.simulcast && track.kind === "video") {
|
||||||
|
tcInit.sendEncodings = simulcastVideoEncodings;
|
||||||
|
}
|
||||||
|
this.pc.addTransceiver(track, tcInit);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// To just receive media, create new recvonly transceivers.
|
// To just receive media, create new recvonly transceivers.
|
||||||
|
|
Loading…
Reference in New Issue