Implement GstWebRTCAPI as class instead of global instance

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1373>
This commit is contained in:
Yorick Smilda 2024-02-07 11:32:21 +01:00 committed by GStreamer Marge Bot
parent 594400a7f5
commit 563eff1193
10 changed files with 391 additions and 424 deletions

View file

@ -220,13 +220,7 @@
} }
</style> </style>
<script> <script>
const signalingProtocol = window.location.protocol.startsWith("https") ? "wss" : "ws"; function initCapture(api) {
window.gstWebRTCConfig = {
meta: { name: `WebClient-${Date.now()}` },
signalingServerUrl: `${signalingProtocol}://${window.location.host}/webrtc`
};
function initCapture() {
const captureSection = document.getElementById("capture"); const captureSection = document.getElementById("capture");
const clientIdElement = captureSection.querySelector(".client-id"); const clientIdElement = captureSection.querySelector(".client-id");
const videoElement = captureSection.getElementsByTagName("video")[0]; const videoElement = captureSection.getElementsByTagName("video")[0];
@ -235,7 +229,7 @@
connected: function(clientId) { clientIdElement.textContent = clientId; }, connected: function(clientId) { clientIdElement.textContent = clientId; },
disconnected: function() { clientIdElement.textContent = "none"; } disconnected: function() { clientIdElement.textContent = "none"; }
}; };
gstWebRTCAPI.registerConnectionListener(listener); api.registerConnectionListener(listener);
document.getElementById("capture-button").addEventListener("click", (event) => { document.getElementById("capture-button").addEventListener("click", (event) => {
event.preventDefault(); event.preventDefault();
@ -249,7 +243,7 @@
video: { width: 1280, height: 720 } video: { width: 1280, height: 720 }
}; };
navigator.mediaDevices.getUserMedia(constraints).then((stream) => { navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
const session = gstWebRTCAPI.createProducerSession(stream); const session = api.createProducerSession(stream);
if (session) { if (session) {
captureSection._producerSession = session; captureSection._producerSession = session;
@ -270,7 +264,7 @@
session.addEventListener("stateChanged", (event) => { session.addEventListener("stateChanged", (event) => {
if ((captureSection._producerSession === session) && if ((captureSection._producerSession === session) &&
(event.target.state === gstWebRTCAPI.SessionState.streaming)) { (event.target.state === GstWebRTCAPI.SessionState.streaming)) {
videoElement.srcObject = stream; videoElement.srcObject = stream;
videoElement.play().catch(() => {}); videoElement.play().catch(() => {});
captureSection.classList.remove("starting"); captureSection.classList.remove("starting");
@ -306,7 +300,7 @@
}); });
} }
function initRemoteStreams() { function initRemoteStreams(api) {
const remoteStreamsElement = document.getElementById("remote-streams"); const remoteStreamsElement = document.getElementById("remote-streams");
const listener = { const listener = {
@ -347,7 +341,7 @@
if (entryElement._consumerSession) { if (entryElement._consumerSession) {
entryElement._consumerSession.close(); entryElement._consumerSession.close();
} else { } else {
const session = gstWebRTCAPI.createConsumerSession(producerId); const session = api.createConsumerSession(producerId);
if (session) { if (session) {
entryElement._consumerSession = session; entryElement._consumerSession = session;
@ -408,8 +402,8 @@
} }
}; };
gstWebRTCAPI.registerProducersListener(listener); api.registerProducersListener(listener);
for (const producer of gstWebRTCAPI.getAvailableProducers()) { for (const producer of api.getAvailableProducers()) {
listener.producerAdded(producer); listener.producerAdded(producer);
} }
} }
@ -422,8 +416,15 @@
} }
}); });
initCapture(); const signalingProtocol = window.location.protocol.startsWith("https") ? "wss" : "ws";
initRemoteStreams(); const gstWebRTCConfig = {
meta: { name: `WebClient-${Date.now()}` },
signalingServerUrl: `${signalingProtocol}://${window.location.host}/webrtc`,
};
const api = new GstWebRTCAPI(gstWebRTCConfig);
initCapture(api);
initRemoteStreams(api);
}); });
</script> </script>
</head> </head>

View file

@ -1,6 +1,6 @@
{ {
"name": "gstwebrtc-api", "name": "gstwebrtc-api",
"version": "1.0.1", "version": "2.0.0",
"description": "Javascript API to integrate GStreamer WebRTC streams (webrtcsrc/webrtcsink) in a web browser", "description": "Javascript API to integrate GStreamer WebRTC streams (webrtcsrc/webrtcsink) in a web browser",
"keywords": [ "keywords": [
"webrtc", "webrtc",

View file

@ -11,17 +11,16 @@
/** /**
* GStreamer WebRTC configuration. * GStreamer WebRTC configuration.
* <p>You can override default values by defining configuration before receiving the <i>DOMContentLoaded</i> event.<br> * <p>The config can be passed on creation of the GstWebRTCAPI class.</p>
* Once the <i>DOMContentLoaded</i> event triggered, changing configuration will have no effect.</p>
* <p>For example: * <p>For example:
* <pre> * <pre>
* const signalingProtocol = window.location.protocol.startsWith("https") ? "wss" : "ws"; * const signalingProtocol = window.location.protocol.startsWith("https") ? "wss" : "ws";
* window.gstWebRTCConfig = { * const api = new GstWebRTCAPI({
* meta: { name: `WebClient-${Date.now()}` }, * meta: { name: `WebClient-${Date.now()}` },
* signalingServerUrl: `${signalingProtocol}://${window.location.host}/webrtc` * signalingServerUrl: `${signalingProtocol}://${window.location.host}/webrtc`
* }; * });
* </pre></p> * </pre></p>
* @typedef {object} gstWebRTCConfig * @typedef {object} GstWebRTCConfig
* @property {object} meta=null - Client free-form information that will be exchanged with all peers through the * @property {object} meta=null - Client free-form information that will be exchanged with all peers through the
* signaling <i>meta</i> property, its content depends on your application. * signaling <i>meta</i> property, its content depends on your application.
* @property {string} signalingServerUrl=ws://127.0.0.1:8443 - The WebRTC signaling server URL. * @property {string} signalingServerUrl=ws://127.0.0.1:8443 - The WebRTC signaling server URL.

View file

@ -15,28 +15,28 @@ import RemoteController from "./remote-controller.js";
/** /**
* Event name: "streamsChanged".<br> * Event name: "streamsChanged".<br>
* Triggered when the underlying media streams of a {@link gstWebRTCAPI.ConsumerSession} change. * Triggered when the underlying media streams of a {@link GstWebRTCAPI.ConsumerSession} change.
* @event gstWebRTCAPI#StreamsChangedEvent * @event GstWebRTCAPI#StreamsChangedEvent
* @type {external:Event} * @type {external:Event}
* @see gstWebRTCAPI.ConsumerSession#streams * @see GstWebRTCAPI.ConsumerSession#streams
*/ */
/** /**
* Event name: "remoteControllerChanged".<br> * Event name: "remoteControllerChanged".<br>
* Triggered when the underlying remote controller of a {@link gstWebRTCAPI.ConsumerSession} changes. * Triggered when the underlying remote controller of a {@link GstWebRTCAPI.ConsumerSession} changes.
* @event gstWebRTCAPI#RemoteControllerChangedEvent * @event GstWebRTCAPI#RemoteControllerChangedEvent
* @type {external:Event} * @type {external:Event}
* @see gstWebRTCAPI.ConsumerSession#remoteController * @see GstWebRTCAPI.ConsumerSession#remoteController
*/ */
/** /**
* @class gstWebRTCAPI.ConsumerSession * @class GstWebRTCAPI.ConsumerSession
* @hideconstructor * @hideconstructor
* @classdesc Consumer session managing a peer-to-peer WebRTC channel between a remote producer and this client * @classdesc Consumer session managing a peer-to-peer WebRTC channel between a remote producer and this client
* instance. * instance.
* <p>Call {@link gstWebRTCAPI#createConsumerSession} to create a ConsumerSession instance.</p> * <p>Call {@link GstWebRTCAPI#createConsumerSession} to create a ConsumerSession instance.</p>
* @extends {gstWebRTCAPI.WebRTCSession} * @extends {GstWebRTCAPI.WebRTCSession}
* @fires {@link gstWebRTCAPI#event:StreamsChangedEvent} * @fires {@link GstWebRTCAPI#event:StreamsChangedEvent}
* @fires {@link gstWebRTCAPI#event:RemoteControllerChangedEvent} * @fires {@link GstWebRTCAPI#event:RemoteControllerChangedEvent}
*/ */
export default class ConsumerSession extends WebRTCSession { export default class ConsumerSession extends WebRTCSession {
constructor(peerId, comChannel) { constructor(peerId, comChannel) {
@ -55,7 +55,7 @@ export default class ConsumerSession extends WebRTCSession {
/** /**
* The array of remote media streams consumed locally through this WebRTC channel. * The array of remote media streams consumed locally through this WebRTC channel.
* @member {external:MediaStream[]} gstWebRTCAPI.ConsumerSession#streams * @member {external:MediaStream[]} GstWebRTCAPI.ConsumerSession#streams
* @readonly * @readonly
*/ */
get streams() { get streams() {
@ -65,7 +65,7 @@ export default class ConsumerSession extends WebRTCSession {
/** /**
* The remote controller associated with this WebRTC consumer session. Value may be null if consumer session * The remote controller associated with this WebRTC consumer session. Value may be null if consumer session
* has no remote controller. * has no remote controller.
* @member {gstWebRTCAPI.RemoteController} gstWebRTCAPI.ConsumerSession#remoteController * @member {GstWebRTCAPI.RemoteController} GstWebRTCAPI.ConsumerSession#remoteController
* @readonly * @readonly
*/ */
get remoteController() { get remoteController() {
@ -77,10 +77,10 @@ export default class ConsumerSession extends WebRTCSession {
* This method must be called after creating the consumer session in order to start receiving the remote streams. * This method must be called after creating the consumer session in order to start receiving the remote streams.
* It registers this consumer session to the signaling server and gets ready to receive audio/video streams. * It registers this consumer session to the signaling server and gets ready to receive audio/video streams.
* <p>Even on success, streaming can fail later if any error occurs during or after connection. In order to know * <p>Even on success, streaming can fail later if any error occurs during or after connection. In order to know
* the effective streaming state, you should be listening to the [error]{@link gstWebRTCAPI#event:ErrorEvent}, * the effective streaming state, you should be listening to the [error]{@link GstWebRTCAPI#event:ErrorEvent},
* [stateChanged]{@link gstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link gstWebRTCAPI#event:ClosedEvent} * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent}
* events.</p> * events.</p>
* @method gstWebRTCAPI.ConsumerSession#connect * @method GstWebRTCAPI.ConsumerSession#connect
* @returns {boolean} true in case of success (may fail later during or after connection) or false in case of * @returns {boolean} true in case of success (may fail later during or after connection) or false in case of
* immediate error (wrong session state or no connection to the signaling server). * immediate error (wrong session state or no connection to the signaling server).
*/ */

View file

@ -13,367 +13,337 @@ import defaultConfig from "./config.js";
import ComChannel from "./com-channel.js"; import ComChannel from "./com-channel.js";
import SessionState from "./session-state.js"; import SessionState from "./session-state.js";
const apiState = { /**
config: null, * @class GstWebRTCAPI
channel: null, * @classdesc The API entry point that manages a WebRTC.
producers: {}, */
connectionListeners: [], export default class GstWebRTCAPI {
producersListeners: [] /**
}; * @constructor GstWebRTCAPI
* @param {GstWebRTCConfig} [userConfig] - The user configuration.<br>Only the parameters different from the default
* ones need to be provided.
*/
constructor(userConfig) {
this._channel = null;
this._producers = {};
this._connectionListeners = [];
this._producersListeners = [];
/** const config = Object.assign({}, defaultConfig);
* @interface gstWebRTCAPI.ConnectionListener if (userConfig && (typeof (userConfig) === "object")) {
*/ Object.assign(config, userConfig);
/** }
* Callback method called when this client connects to the WebRTC signaling server.
* The callback implementation should not throw any exception.
* @method gstWebRTCAPI.ConnectionListener#connected
* @abstract
* @param {string} clientId - The unique identifier of this WebRTC client.<br>This identifier is provided by the
* signaling server to uniquely identify each connected peer.
*/
/**
* Callback method called when this client disconnects from the WebRTC signaling server.
* The callback implementation should not throw any exception.
* @method gstWebRTCAPI.ConnectionListener#disconnected
* @abstract
*/
/** if (typeof (config.meta) !== "object") {
* Registers a connection listener that will be called each time the WebRTC API connects to or disconnects from the config.meta = null;
* signaling server. }
* @function
* @memberof gstWebRTCAPI this._config = config;
* @instance this.connectChannel();
* @param {gstWebRTCAPI.ConnectionListener} listener - The connection listener to register.
* @returns {boolean} true in case of success (or if the listener was already registered), or false if the listener
* doesn't implement all callback functions and cannot be registered.
*/
function registerConnectionListener(listener) {
if (!listener || (typeof (listener) !== "object") ||
(typeof (listener.connected) !== "function") ||
(typeof (listener.disconnected) !== "function")) {
return false;
} }
if (!apiState.connectionListeners.includes(listener)) { /**
apiState.connectionListeners.push(listener); * @interface GstWebRTCAPI.ConnectionListener
} */
/**
* Callback method called when this client connects to the WebRTC signaling server.
* The callback implementation should not throw any exception.
* @method GstWebRTCAPI.ConnectionListener#connected
* @abstract
* @param {string} clientId - The unique identifier of this WebRTC client.<br>This identifier is provided by the
* signaling server to uniquely identify each connected peer.
*/
/**
* Callback method called when this client disconnects from the WebRTC signaling server.
* The callback implementation should not throw any exception.
* @method GstWebRTCAPI.ConnectionListener#disconnected
* @abstract
*/
return true; /**
} * Registers a connection listener that will be called each time the WebRTC API connects to or disconnects from the
* signaling server.
* @method GstWebRTCAPI#registerConnectionListener
* @param {GstWebRTCAPI.ConnectionListener} listener - The connection listener to register.
* @returns {boolean} true in case of success (or if the listener was already registered), or false if the listener
* doesn't implement all callback functions and cannot be registered.
*/
registerConnectionListener(listener) {
if (!listener || (typeof (listener) !== "object") ||
(typeof (listener.connected) !== "function") ||
(typeof (listener.disconnected) !== "function")) {
return false;
}
if (!this._connectionListeners.includes(listener)) {
this._connectionListeners.push(listener);
}
/**
* Unregisters a connection listener.<br>
* The removed listener will never be called again and can be garbage collected.
* @function
* @memberof gstWebRTCAPI
* @instance
* @param {gstWebRTCAPI.ConnectionListener} listener - The connection listener to unregister.
* @returns {boolean} true if the listener is found and unregistered, or false if the listener was not previously
* registered.
*/
function unregisterConnectionListener(listener) {
const idx = apiState.connectionListeners.indexOf(listener);
if (idx >= 0) {
apiState.connectionListeners.splice(idx, 1);
return true; return true;
} }
return false; /**
} * Unregisters a connection listener.<br>
* The removed listener will never be called again and can be garbage collected.
* @method GstWebRTCAPI#unregisterConnectionListener
* @param {GstWebRTCAPI.ConnectionListener} listener - The connection listener to unregister.
* @returns {boolean} true if the listener is found and unregistered, or false if the listener was not previously
* registered.
*/
unregisterConnectionListener(listener) {
const idx = this._connectionListeners.indexOf(listener);
if (idx >= 0) {
this._connectionListeners.splice(idx, 1);
return true;
}
/**
* Unregisters all previously registered connection listeners.
* @function
* @memberof gstWebRTCAPI
* @instance
*/
function unregisterAllConnectionListeners() {
apiState.connectionListeners = [];
}
/**
* Creates a new producer session.
* <p>You can only create a producer session at once.<br>
* To request streaming from a new stream you will first need to close the previous producer session.</p>
* <p>You can only request a producer session while you are connected to the signaling server. You can use the
* {@link gstWebRTCAPI.ConnectionListener} interface and {@link gstWebRTCAPI#registerConnectionListener} function to
* listen to the connection state.</p>
* @function
* @memberof gstWebRTCAPI
* @instance
* @param {external:MediaStream} stream - The audio/video stream to offer as a producer through WebRTC.
* @returns {gstWebRTCAPI.ProducerSession} The created producer session or null in case of error. To start streaming,
* you still need to call {@link gstWebRTCAPI.ProducerSession#start} after adding on the returned session all the event
* listeners you may need.
*/
function createProducerSession(stream) {
if (apiState.channel) {
return apiState.channel.createProducerSession(stream);
} else {
return null;
}
}
/**
* Information about a remote producer registered by the signaling server.
* @typedef {object} gstWebRTCAPI.Producer
* @readonly
* @property {string} id - The remote producer unique identifier set by the signaling server (always non-empty).
* @property {object} meta - Free-form object containing extra information about the remote producer (always non-null,
* but may be empty). Its content depends on your application.
*/
/**
* Gets the list of all remote WebRTC producers available on the signaling server.
* <p>The remote producers list is only populated once you've connected to the signaling server. You can use the
* {@link gstWebRTCAPI.ConnectionListener} interface and {@link gstWebRTCAPI#registerConnectionListener} function to
* listen to the connection state.</p>
* @function
* @memberof gstWebRTCAPI
* @instance
* @returns {gstWebRTCAPI.Producer[]} The list of remote WebRTC producers available.
*/
function getAvailableProducers() {
return Object.values(apiState.producers);
}
/**
* @interface gstWebRTCAPI.ProducersListener
*/
/**
* Callback method called when a remote producer is added on the signaling server.
* The callback implementation should not throw any exception.
* @method gstWebRTCAPI.ProducersListener#producerAdded
* @abstract
* @param {gstWebRTCAPI.Producer} producer - The remote producer added on server-side.
*/
/**
* Callback method called when a remote producer is removed from the signaling server.
* The callback implementation should not throw any exception.
* @method gstWebRTCAPI.ProducersListener#producerRemoved
* @abstract
* @param {gstWebRTCAPI.Producer} producer - The remote producer removed on server-side.
*/
/**
* Registers a producers listener that will be called each time a producer is added or removed on the signaling
* server.
* @function
* @memberof gstWebRTCAPI
* @instance
* @param {gstWebRTCAPI.ProducersListener} listener - The producer listener to register.
* @returns {boolean} true in case of success (or if the listener was already registered), or false if the listener
* doesn't implement all callback functions and cannot be registered.
*/
function registerProducersListener(listener) {
if (!listener || (typeof (listener) !== "object") ||
(typeof (listener.producerAdded) !== "function") ||
(typeof (listener.producerRemoved) !== "function")) {
return false; return false;
} }
if (!apiState.producersListeners.includes(listener)) { /**
apiState.producersListeners.push(listener); * Unregisters all previously registered connection listeners.
* @method GstWebRTCAPI#unregisterAllConnectionListeners
*/
unregisterAllConnectionListeners() {
this._connectionListeners = [];
} }
return true; /**
} * Creates a new producer session.
* <p>You can only create one producer session at a time.<br>
* To request streaming from a new stream you will first need to close the previous producer session.</p>
* <p>You can only request a producer session while you are connected to the signaling server. You can use the
* {@link GstWebRTCAPI.ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to
* listen to the connection state.</p>
* @method GstWebRTCAPI#createProducerSession
* @param {external:MediaStream} stream - The audio/video stream to offer as a producer through WebRTC.
* @returns {GstWebRTCAPI.ProducerSession} The created producer session or null in case of error. To start streaming,
* you still need to call {@link GstWebRTCAPI.ProducerSession#start} after adding on the returned session all the event
* listeners you may need.
*/
createProducerSession(stream) {
if (this._channel) {
return this._channel.createProducerSession(stream);
}
return null;
}
/**
* Information about a remote producer registered by the signaling server.
* @typedef {object} GstWebRTCAPI.Producer
* @readonly
* @property {string} id - The remote producer unique identifier set by the signaling server (always non-empty).
* @property {object} meta - Free-form object containing extra information about the remote producer (always non-null,
* but may be empty). Its content depends on your application.
*/
/**
* Gets the list of all remote WebRTC producers available on the signaling server.
* <p>The remote producers list is only populated once you've connected to the signaling server. You can use the
* {@link GstWebRTCAPI.ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to
* listen to the connection state.</p>
* @method GstWebRTCAPI#getAvailableProducers
* @returns {GstWebRTCAPI.Producer[]} The list of remote WebRTC producers available.
*/
getAvailableProducers() {
return Object.values(this._producers);
}
/**
* @interface GstWebRTCAPI.ProducersListener
*/
/**
* Callback method called when a remote producer is added on the signaling server.
* The callback implementation should not throw any exception.
* @method GstWebRTCAPI.ProducersListener#producerAdded
* @abstract
* @param {GstWebRTCAPI.Producer} producer - The remote producer added on server-side.
*/
/**
* Callback method called when a remote producer is removed from the signaling server.
* The callback implementation should not throw any exception.
* @method GstWebRTCAPI.ProducersListener#producerRemoved
* @abstract
* @param {GstWebRTCAPI.Producer} producer - The remote producer removed on server-side.
*/
/**
* Registers a producers listener that will be called each time a producer is added or removed on the signaling
* server.
* @method GstWebRTCAPI#registerProducersListener
* @param {GstWebRTCAPI.ProducersListener} listener - The producer listener to register.
* @returns {boolean} true in case of success (or if the listener was already registered), or false if the listener
* doesn't implement all callback functions and cannot be registered.
*/
registerProducersListener(listener) {
if (!listener || (typeof (listener) !== "object") ||
(typeof (listener.producerAdded) !== "function") ||
(typeof (listener.producerRemoved) !== "function")) {
return false;
}
if (!this._producersListeners.includes(listener)) {
this._producersListeners.push(listener);
}
/**
* Unregisters a producers listener.<br>
* The removed listener will never be called again and can be garbage collected.
* @function
* @memberof gstWebRTCAPI
* @instance
* @param {gstWebRTCAPI.ProducersListener} listener - The producers listener to unregister.
* @returns {boolean} true if the listener is found and unregistered, or false if the listener was not previously
* registered.
*/
function unregisterProducersListener(listener) {
const idx = apiState.producersListeners.indexOf(listener);
if (idx >= 0) {
apiState.producersListeners.splice(idx, 1);
return true; return true;
} }
return false; /**
} * Unregisters a producers listener.<br>
* The removed listener will never be called again and can be garbage collected.
* @method GstWebRTCAPI#unregisterProducersListener
* @param {GstWebRTCAPI.ProducersListener} listener - The producers listener to unregister.
* @returns {boolean} true if the listener is found and unregistered, or false if the listener was not previously
* registered.
*/
unregisterProducersListener(listener) {
const idx = this._producersListeners.indexOf(listener);
if (idx >= 0) {
this._producersListeners.splice(idx, 1);
return true;
}
/** return false;
* Unregisters all previously registered producers listeners. }
* @function
* @memberof gstWebRTCAPI
* @instance
*/
function unregisterAllProducersListeners() {
apiState.producersListeners = [];
}
/** /**
* Creates a consumer session by connecting the local client to a remote WebRTC producer. * Unregisters all previously registered producers listeners.
* <p>You can only create one consumer session per remote producer.</p> * @method GstWebRTCAPI#unregisterAllProducersListeners
* <p>You can only request a new consumer session while you are connected to the signaling server. You can use the */
* {@link gstWebRTCAPI.ConnectionListener} interface and {@link gstWebRTCAPI#registerConnectionListener} function to unregisterAllProducersListeners() {
* listen to the connection state.</p> this._producersListeners = [];
* @function }
* @memberof gstWebRTCAPI
* @instance /**
* @param {string} producerId - The unique identifier of the remote producer to connect to. * Creates a consumer session by connecting the local client to a remote WebRTC producer.
* @returns {gstWebRTCAPI.ConsumerSession} The WebRTC session between the selected remote producer and this local * <p>You can only create one consumer session per remote producer.</p>
* consumer, or null in case of error. To start connecting and receiving the remote streams, you still need to call * <p>You can only request a new consumer session while you are connected to the signaling server. You can use the
* {@link gstWebRTCAPI.ConsumerSession#connect} after adding on the returned session all the event listeners you may * {@link GstWebRTCAPI.ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to
* need. * listen to the connection state.</p>
*/ * @method GstWebRTCAPI#createConsumerSession
function createConsumerSession(producerId) { * @param {string} producerId - The unique identifier of the remote producer to connect to.
if (apiState.channel) { * @returns {GstWebRTCAPI.ConsumerSession} The WebRTC session between the selected remote producer and this local
return apiState.channel.createConsumerSession(producerId); * consumer, or null in case of error. To start connecting and receiving the remote streams, you still need to call
} else { * {@link GstWebRTCAPI.ConsumerSession#connect} after adding on the returned session all the event listeners you may
* need.
*/
createConsumerSession(producerId) {
if (this._channel) {
return this._channel.createConsumerSession(producerId);
}
return null; return null;
} }
}
/** connectChannel() {
* The GStreamer WebRTC Javascript API. if (this._channel) {
* @namespace gstWebRTCAPI const oldChannel = this._channel;
*/ this._channel = null;
const gstWebRTCAPI = Object.freeze({ oldChannel.close();
SessionState: SessionState, for (const key in this._producers) {
registerConnectionListener: registerConnectionListener, this.triggerProducerRemoved(key);
unregisterConnectionListener: unregisterConnectionListener, }
unregisterAllConnectionListeners: unregisterAllConnectionListeners, this._producers = {};
createProducerSession: createProducerSession, this.triggerDisconnected();
getAvailableProducers: getAvailableProducers,
registerProducersListener: registerProducersListener,
unregisterProducersListener: unregisterProducersListener,
unregisterAllProducersListeners: unregisterAllProducersListeners,
createConsumerSession: createConsumerSession
});
function triggerConnected(clientId) {
for (const listener of apiState.connectionListeners) {
try {
listener.connected(clientId);
} catch (ex) {
console.error("a listener callback should not throw any exception", ex);
} }
}
}
function triggerDisconnected() { this._channel = new ComChannel(
for (const listener of apiState.connectionListeners) { this._config.signalingServerUrl,
try { this._config.meta,
listener.disconnected(); this._config.webrtcConfig
} catch (ex) { );
console.error("a listener callback should not throw any exception", ex);
}
}
}
function triggerProducerAdded(producer) { this._channel.addEventListener("error", (event) => {
if (producer.id in apiState.producers) { if (event.target === this._channel) {
return; console.error(event.message, event.error);
}
});
this._channel.addEventListener("closed", (event) => {
if (event.target !== this._channel) {
return;
}
this._channel = null;
for (const key in this._producers) {
this.triggerProducerRemoved(key);
}
this._producers = {};
this.triggerDisconnected();
if (this._config.reconnectionTimeout > 0) {
window.setTimeout(() => {
this.connectChannel();
}, this._config.reconnectionTimeout);
}
});
this._channel.addEventListener("ready", (event) => {
if (event.target === this._channel) {
this.triggerConnected(this._channel.channelId);
}
});
this._channel.addEventListener("producerAdded", (event) => {
if (event.target === this._channel) {
this.triggerProducerAdded(event.detail);
}
});
this._channel.addEventListener("producerRemoved", (event) => {
if (event.target === this._channel) {
this.triggerProducerRemoved(event.detail.id);
}
});
} }
apiState.producers[producer.id] = producer; triggerConnected(clientId) {
for (const listener of apiState.producersListeners) { for (const listener of this._connectionListeners) {
try {
listener.producerAdded(producer);
} catch (ex) {
console.error("a listener callback should not throw any exception", ex);
}
}
}
function triggerProducerRemoved(producerId) {
if (producerId in apiState.producers) {
const producer = apiState.producers[producerId];
delete apiState.producers[producerId];
for (const listener of apiState.producersListeners) {
try { try {
listener.producerRemoved(producer); listener.connected(clientId);
} catch (ex) { } catch (ex) {
console.error("a listener callback should not throw any exception", ex); console.error("a listener callback should not throw any exception", ex);
} }
} }
} }
}
function connectChannel() { triggerDisconnected() {
if (apiState.channel) { for (const listener of this._connectionListeners) {
const oldChannel = apiState.channel; try {
apiState.channel = null; listener.disconnected();
oldChannel.close(); } catch (ex) {
for (const key in apiState.producers) { console.error("a listener callback should not throw any exception", ex);
triggerProducerRemoved(key);
}
apiState.producers = {};
triggerDisconnected();
}
apiState.channel = new ComChannel(
apiState.config.signalingServerUrl,
apiState.config.meta,
apiState.config.webrtcConfig);
apiState.channel.addEventListener("error", (event) => {
if (event.target === apiState.channel) {
console.error(event.message, event.error);
}
});
apiState.channel.addEventListener("closed", (event) => {
if (event.target === apiState.channel) {
apiState.channel = null;
for (const key in apiState.producers) {
triggerProducerRemoved(key);
}
apiState.producers = {};
triggerDisconnected();
if (apiState.config.reconnectionTimeout > 0) {
window.setTimeout(connectChannel, apiState.config.reconnectionTimeout);
} }
} }
}); }
apiState.channel.addEventListener("ready", (event) => { triggerProducerAdded(producer) {
if (event.target === apiState.channel) { if (producer.id in this._producers) {
triggerConnected(apiState.channel.channelId); return;
} }
});
apiState.channel.addEventListener("producerAdded", (event) => { this._producers[producer.id] = producer;
if (event.target === apiState.channel) { for (const listener of this._producersListeners) {
triggerProducerAdded(event.detail); try {
listener.producerAdded(producer);
} catch (ex) {
console.error("a listener callback should not throw any exception", ex);
}
} }
}); }
apiState.channel.addEventListener("producerRemoved", (event) => { triggerProducerRemoved(producerId) {
if (event.target === apiState.channel) { if (producerId in this._producers) {
triggerProducerRemoved(event.detail.id); const producer = this._producers[producerId];
delete this._producers[producerId];
for (const listener of this._producersListeners) {
try {
listener.producerRemoved(producer);
} catch (ex) {
console.error("a listener callback should not throw any exception", ex);
}
}
} }
}); }
} }
function start(userConfig) { GstWebRTCAPI.SessionState = SessionState;
if (apiState.config) {
throw new Error("GstWebRTC API is already started");
}
const config = Object.assign({}, defaultConfig);
if (userConfig && (typeof (userConfig) === "object")) {
Object.assign(config, userConfig);
}
if (typeof (config.meta) !== "object") {
config.meta = null;
}
apiState.config = config;
connectChannel();
}
export { gstWebRTCAPI, start };

View file

@ -10,7 +10,7 @@
*/ */
import "webrtc-adapter"; import "webrtc-adapter";
import { gstWebRTCAPI, start } from "./gstwebrtc-api.js"; import GstWebRTCAPI from "./gstwebrtc-api.js";
/** /**
* @external MediaStream * @external MediaStream
@ -49,9 +49,6 @@ import { gstWebRTCAPI, start } from "./gstwebrtc-api.js";
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement
*/ */
if (!window.gstWebRTCAPI) { if (!window.GstWebRTCAPI) {
window.gstWebRTCAPI = gstWebRTCAPI; window.GstWebRTCAPI = GstWebRTCAPI;
window.addEventListener("DOMContentLoaded", () => {
start(window.gstWebRTCConfig);
});
} }

View file

@ -13,10 +13,10 @@ import WebRTCSession from "./webrtc-session.js";
import SessionState from "./session-state.js"; import SessionState from "./session-state.js";
/** /**
* @class gstWebRTCAPI.ClientSession * @class GstWebRTCAPI.ClientSession
* @hideconstructor * @hideconstructor
* @classdesc Client session representing a link between a remote consumer and a local producer session. * @classdesc Client session representing a link between a remote consumer and a local producer session.
* @extends {gstWebRTCAPI.WebRTCSession} * @extends {GstWebRTCAPI.WebRTCSession}
*/ */
class ClientSession extends WebRTCSession { class ClientSession extends WebRTCSession {
constructor(peerId, sessionId, comChannel, stream) { constructor(peerId, sessionId, comChannel, stream) {
@ -102,33 +102,33 @@ class ClientSession extends WebRTCSession {
/** /**
* Event name: "clientConsumerAdded".<br> * Event name: "clientConsumerAdded".<br>
* Triggered when a remote consumer peer connects to a local {@link gstWebRTCAPI.ProducerSession}. * Triggered when a remote consumer peer connects to a local {@link GstWebRTCAPI.ProducerSession}.
* @event gstWebRTCAPI#ClientConsumerAddedEvent * @event GstWebRTCAPI#ClientConsumerAddedEvent
* @type {external:CustomEvent} * @type {external:CustomEvent}
* @property {gstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the added consumer peer. * @property {GstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the added consumer peer.
* @see gstWebRTCAPI.ProducerSession * @see GstWebRTCAPI.ProducerSession
*/ */
/** /**
* Event name: "clientConsumerRemoved".<br> * Event name: "clientConsumerRemoved".<br>
* Triggered when a remote consumer peer disconnects from a local {@link gstWebRTCAPI.ProducerSession}. * Triggered when a remote consumer peer disconnects from a local {@link GstWebRTCAPI.ProducerSession}.
* @event gstWebRTCAPI#ClientConsumerRemovedEvent * @event GstWebRTCAPI#ClientConsumerRemovedEvent
* @type {external:CustomEvent} * @type {external:CustomEvent}
* @property {gstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the removed consumer peer. * @property {GstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the removed consumer peer.
* @see gstWebRTCAPI.ProducerSession * @see GstWebRTCAPI.ProducerSession
*/ */
/** /**
* @class gstWebRTCAPI.ProducerSession * @class GstWebRTCAPI.ProducerSession
* @hideconstructor * @hideconstructor
* @classdesc Producer session managing the streaming out of a local {@link external:MediaStream}.<br> * @classdesc Producer session managing the streaming out of a local {@link external:MediaStream}.<br>
* It manages all underlying WebRTC connections to each peer client consuming the stream. * It manages all underlying WebRTC connections to each peer client consuming the stream.
* <p>Call {@link gstWebRTCAPI#createProducerSession} to create a ProducerSession instance.</p> * <p>Call {@link GstWebRTCAPI#createProducerSession} to create a ProducerSession instance.</p>
* @extends {external:EventTarget} * @extends {external:EventTarget}
* @fires {@link gstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:ErrorEvent}
* @fires {@link gstWebRTCAPI#event:StateChangedEvent} * @fires {@link GstWebRTCAPI#event:StateChangedEvent}
* @fires {@link gstWebRTCAPI#event:ClosedEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent}
* @fires {@link gstWebRTCAPI#event:ClientConsumerAddedEvent} * @fires {@link GstWebRTCAPI#event:ClientConsumerAddedEvent}
* @fires {@link gstWebRTCAPI#event:ClientConsumerRemovedEvent} * @fires {@link GstWebRTCAPI#event:ClientConsumerRemovedEvent}
*/ */
export default class ProducerSession extends EventTarget { export default class ProducerSession extends EventTarget {
constructor(comChannel, stream) { constructor(comChannel, stream) {
@ -142,7 +142,7 @@ export default class ProducerSession extends EventTarget {
/** /**
* The local stream produced out by this session. * The local stream produced out by this session.
* @member {external:MediaStream} gstWebRTCAPI.ProducerSession#stream * @member {external:MediaStream} GstWebRTCAPI.ProducerSession#stream
* @readonly * @readonly
*/ */
get stream() { get stream() {
@ -151,7 +151,7 @@ export default class ProducerSession extends EventTarget {
/** /**
* The current producer session state. * The current producer session state.
* @member {gstWebRTCAPI.SessionState} gstWebRTCAPI.ProducerSession#state * @member {GstWebRTCAPI.SessionState} GstWebRTCAPI.ProducerSession#state
* @readonly * @readonly
*/ */
get state() { get state() {
@ -163,10 +163,10 @@ export default class ProducerSession extends EventTarget {
* This method must be called after creating the producer session in order to start streaming. It registers this * This method must be called after creating the producer session in order to start streaming. It registers this
* producer session to the signaling server and gets ready to serve peer requests from consumers. * producer session to the signaling server and gets ready to serve peer requests from consumers.
* <p>Even on success, streaming can fail later if any error occurs during or after connection. In order to know * <p>Even on success, streaming can fail later if any error occurs during or after connection. In order to know
* the effective streaming state, you should be listening to the [error]{@link gstWebRTCAPI#event:ErrorEvent}, * the effective streaming state, you should be listening to the [error]{@link GstWebRTCAPI#event:ErrorEvent},
* [stateChanged]{@link gstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link gstWebRTCAPI#event:ClosedEvent} * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent}
* events.</p> * events.</p>
* @method gstWebRTCAPI.ProducerSession#start * @method GstWebRTCAPI.ProducerSession#start
* @returns {boolean} true in case of success (may fail later during or after connection) or false in case of * @returns {boolean} true in case of success (may fail later during or after connection) or false in case of
* immediate error (wrong session state or no connection to the signaling server). * immediate error (wrong session state or no connection to the signaling server).
*/ */
@ -203,7 +203,7 @@ export default class ProducerSession extends EventTarget {
* Terminates the producer session.<br> * Terminates the producer session.<br>
* It immediately disconnects all peer consumers attached to this producer session and unregisters the producer * It immediately disconnects all peer consumers attached to this producer session and unregisters the producer
* from the signaling server. * from the signaling server.
* @method gstWebRTCAPI.ProducerSession#close * @method GstWebRTCAPI.ProducerSession#close
*/ */
close() { close() {
if (this._state !== SessionState.closed) { if (this._state !== SessionState.closed) {

View file

@ -65,7 +65,7 @@ function getModifiers(event) {
} }
/** /**
* @class gstWebRTCAPI.RemoteController * @class GstWebRTCAPI.RemoteController
* @hideconstructor * @hideconstructor
* @classdesc Manages a specific WebRTC data channel created by a remote GStreamer webrtcsink producer and offering * @classdesc Manages a specific WebRTC data channel created by a remote GStreamer webrtcsink producer and offering
* remote control of the producer through * remote control of the producer through
@ -76,10 +76,10 @@ function getModifiers(event) {
* <p>You can attach an {@link external:HTMLVideoElement} to the remote controller, then all mouse and keyboard events * <p>You can attach an {@link external:HTMLVideoElement} to the remote controller, then all mouse and keyboard events
* emitted by this element will be automatically relayed to the remote producer.</p> * emitted by this element will be automatically relayed to the remote producer.</p>
* @extends {external:EventTarget} * @extends {external:EventTarget}
* @fires {@link gstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:ErrorEvent}
* @fires {@link gstWebRTCAPI#event:ClosedEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent}
* @see gstWebRTCAPI.ConsumerSession#remoteController * @see GstWebRTCAPI.ConsumerSession#remoteController
* @see gstWebRTCAPI.RemoteController#attachVideoElement * @see GstWebRTCAPI.RemoteController#attachVideoElement
* @see https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/net/webrtc/gstwebrtc-api#produce-a-gstreamer-interactive-webrtc-stream-with-remote-control * @see https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/net/webrtc/gstwebrtc-api#produce-a-gstreamer-interactive-webrtc-stream-with-remote-control
*/ */
export default class RemoteController extends EventTarget { export default class RemoteController extends EventTarget {
@ -114,7 +114,7 @@ export default class RemoteController extends EventTarget {
/** /**
* The underlying WebRTC data channel connected to a remote GStreamer webrtcsink producer offering remote control. * The underlying WebRTC data channel connected to a remote GStreamer webrtcsink producer offering remote control.
* The value may be null if the remote controller has been closed. * The value may be null if the remote controller has been closed.
* @member {external:RTCDataChannel} gstWebRTCAPI.RemoteController#rtcDataChannel * @member {external:RTCDataChannel} GstWebRTCAPI.RemoteController#rtcDataChannel
* @readonly * @readonly
*/ */
get rtcDataChannel() { get rtcDataChannel() {
@ -123,7 +123,7 @@ export default class RemoteController extends EventTarget {
/** /**
* The consumer session associated with this remote controller. * The consumer session associated with this remote controller.
* @member {gstWebRTCAPI.ConsumerSession} gstWebRTCAPI.RemoteController#consumerSession * @member {GstWebRTCAPI.ConsumerSession} GstWebRTCAPI.RemoteController#consumerSession
* @readonly * @readonly
*/ */
get consumerSession() { get consumerSession() {
@ -133,9 +133,9 @@ export default class RemoteController extends EventTarget {
/** /**
* The video element that is currently used to send all mouse and keyboard events to the remote producer. Value may * The video element that is currently used to send all mouse and keyboard events to the remote producer. Value may
* be null if no video element is attached. * be null if no video element is attached.
* @member {external:HTMLVideoElement} gstWebRTCAPI.RemoteController#videoElement * @member {external:HTMLVideoElement} GstWebRTCAPI.RemoteController#videoElement
* @readonly * @readonly
* @see gstWebRTCAPI.RemoteController#attachVideoElement * @see GstWebRTCAPI.RemoteController#attachVideoElement
*/ */
get videoElement() { get videoElement() {
return this._videoElement; return this._videoElement;
@ -145,7 +145,7 @@ export default class RemoteController extends EventTarget {
* Associates a video element with this remote controller.<br> * Associates a video element with this remote controller.<br>
* When a video element is attached to this remote controller, all mouse and keyboard events emitted by this * When a video element is attached to this remote controller, all mouse and keyboard events emitted by this
* element will be sent to the remote GStreamer webrtcink producer. * element will be sent to the remote GStreamer webrtcink producer.
* @method gstWebRTCAPI.RemoteController#attachVideoElement * @method GstWebRTCAPI.RemoteController#attachVideoElement
* @param {external:HTMLVideoElement|null} element - the video element to use to relay mouse and keyboard events, * @param {external:HTMLVideoElement|null} element - the video element to use to relay mouse and keyboard events,
* or null to detach any previously attached element. If the provided element parameter is not null and not a * or null to detach any previously attached element. If the provided element parameter is not null and not a
* valid instance of an {@link external:HTMLVideoElement}, then the method does nothing. * valid instance of an {@link external:HTMLVideoElement}, then the method does nothing.
@ -183,7 +183,7 @@ export default class RemoteController extends EventTarget {
* Closes the remote controller channel.<br> * Closes the remote controller channel.<br>
* It immediately shuts down the underlying WebRTC data channel connected to a remote GStreamer webrtcsink * It immediately shuts down the underlying WebRTC data channel connected to a remote GStreamer webrtcsink
* producer and detaches any video element that may be used to relay mouse and keyboard events. * producer and detaches any video element that may be used to relay mouse and keyboard events.
* @method gstWebRTCAPI.RemoteController#close * @method GstWebRTCAPI.RemoteController#close
*/ */
close() { close() {
this.attachVideoElement(null); this.attachVideoElement(null);

View file

@ -12,7 +12,7 @@
/** /**
* Session states enumeration.<br> * Session states enumeration.<br>
* Session state always increases from idle to closed and never switches backwards. * Session state always increases from idle to closed and never switches backwards.
* @typedef {enum} gstWebRTCAPI.SessionState * @typedef {enum} GstWebRTCAPI.SessionState
* @readonly * @readonly
* @property {0} idle - Default state when creating a new session, goes to <i>connecting</i> when starting * @property {0} idle - Default state when creating a new session, goes to <i>connecting</i> when starting
* the session. * the session.

View file

@ -15,53 +15,53 @@ import SessionState from "./session-state.js";
* Event name: "error".<br> * Event name: "error".<br>
* Triggered when any kind of error occurs. * Triggered when any kind of error occurs.
* <p>When emitted by a session, it is in general an unrecoverable error. Normally, the session is automatically closed * <p>When emitted by a session, it is in general an unrecoverable error. Normally, the session is automatically closed
* but in the specific case of a {@link gstWebRTCAPI.ProducerSession}, when the error occurs on an underlying * but in the specific case of a {@link GstWebRTCAPI.ProducerSession}, when the error occurs on an underlying
* {@link gstWebRTCAPI.ClientSession} between the producer session and a remote client consuming the streamed media, * {@link GstWebRTCAPI.ClientSession} between the producer session and a remote client consuming the streamed media,
* then only the failing {@link gstWebRTCAPI.ClientSession} is closed. The producer session can keep on serving the * then only the failing {@link GstWebRTCAPI.ClientSession} is closed. The producer session can keep on serving the
* other consumer peers.</p> * other consumer peers.</p>
* @event gstWebRTCAPI#ErrorEvent * @event GstWebRTCAPI#ErrorEvent
* @type {external:ErrorEvent} * @type {external:ErrorEvent}
* @property {string} message - The error message. * @property {string} message - The error message.
* @property {external:Error} error - The error exception. * @property {external:Error} error - The error exception.
* @see gstWebRTCAPI.WebRTCSession * @see GstWebRTCAPI.WebRTCSession
* @see gstWebRTCAPI.RemoteController * @see GstWebRTCAPI.RemoteController
*/ */
/** /**
* Event name: "stateChanged".<br> * Event name: "stateChanged".<br>
* Triggered each time a session state changes. * Triggered each time a session state changes.
* @event gstWebRTCAPI#StateChangedEvent * @event GstWebRTCAPI#StateChangedEvent
* @type {external:Event} * @type {external:Event}
* @see gstWebRTCAPI.WebRTCSession#state * @see GstWebRTCAPI.WebRTCSession#state
*/ */
/** /**
* Event name: "rtcPeerConnectionChanged".<br> * Event name: "rtcPeerConnectionChanged".<br>
* Triggered each time a session internal {@link external:RTCPeerConnection} changes. This can occur during the session * Triggered each time a session internal {@link external:RTCPeerConnection} changes. This can occur during the session
* connecting state when the peer-to-peer WebRTC connection is established, and when closing the * connecting state when the peer-to-peer WebRTC connection is established, and when closing the
* {@link gstWebRTCAPI.WebRTCSession}. * {@link GstWebRTCAPI.WebRTCSession}.
* @event gstWebRTCAPI#RTCPeerConnectionChangedEvent * @event GstWebRTCAPI#RTCPeerConnectionChangedEvent
* @type {external:Event} * @type {external:Event}
* @see gstWebRTCAPI.WebRTCSession#rtcPeerConnection * @see GstWebRTCAPI.WebRTCSession#rtcPeerConnection
*/ */
/** /**
* Event name: "closed".<br> * Event name: "closed".<br>
* Triggered when a session is definitively closed (then it can be garbage collected as session instances are not * Triggered when a session is definitively closed (then it can be garbage collected as session instances are not
* reusable). * reusable).
* @event gstWebRTCAPI#ClosedEvent * @event GstWebRTCAPI#ClosedEvent
* @type {external:Event} * @type {external:Event}
*/ */
/** /**
* @class gstWebRTCAPI.WebRTCSession * @class GstWebRTCAPI.WebRTCSession
* @hideconstructor * @hideconstructor
* @classdesc Manages a WebRTC session between a producer and a consumer (peer-to-peer channel). * @classdesc Manages a WebRTC session between a producer and a consumer (peer-to-peer channel).
* @extends {external:EventTarget} * @extends {external:EventTarget}
* @fires {@link gstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:ErrorEvent}
* @fires {@link gstWebRTCAPI#event:StateChangedEvent} * @fires {@link GstWebRTCAPI#event:StateChangedEvent}
* @fires {@link gstWebRTCAPI#event:RTCPeerConnectionChangedEvent} * @fires {@link GstWebRTCAPI#event:RTCPeerConnectionChangedEvent}
* @fires {@link gstWebRTCAPI#event:ClosedEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent}
* @see gstWebRTCAPI.ConsumerSession * @see GstWebRTCAPI.ConsumerSession
* @see gstWebRTCAPI.ProducerSession * @see GstWebRTCAPI.ProducerSession
* @see gstWebRTCAPI.ClientSession * @see GstWebRTCAPI.ClientSession
*/ */
export default class WebRTCSession extends EventTarget { export default class WebRTCSession extends EventTarget {
constructor(peerId, comChannel) { constructor(peerId, comChannel) {
@ -76,7 +76,7 @@ export default class WebRTCSession extends EventTarget {
/** /**
* Unique identifier of the remote peer to which this session is connected. * Unique identifier of the remote peer to which this session is connected.
* @member {string} gstWebRTCAPI.WebRTCSession#peerId * @member {string} GstWebRTCAPI.WebRTCSession#peerId
* @readonly * @readonly
*/ */
get peerId() { get peerId() {
@ -87,8 +87,8 @@ export default class WebRTCSession extends EventTarget {
* Unique identifier of this session (defined by the signaling server).<br> * Unique identifier of this session (defined by the signaling server).<br>
* The local session ID equals "" until it is created on server side. This is done during the connection handshake. * The local session ID equals "" until it is created on server side. This is done during the connection handshake.
* The local session ID is guaranteed to be valid and to correctly reflect the signaling server value once * The local session ID is guaranteed to be valid and to correctly reflect the signaling server value once
* session state has switched to {@link gstWebRTCAPI.SessionState#streaming}. * session state has switched to {@link GstWebRTCAPI.SessionState#streaming}.
* @member {string} gstWebRTCAPI.WebRTCSession#sessionId * @member {string} GstWebRTCAPI.WebRTCSession#sessionId
* @readonly * @readonly
*/ */
get sessionId() { get sessionId() {
@ -97,7 +97,7 @@ export default class WebRTCSession extends EventTarget {
/** /**
* The current WebRTC session state. * The current WebRTC session state.
* @member {gstWebRTCAPI.SessionState} gstWebRTCAPI.WebRTCSession#state * @member {GstWebRTCAPI.SessionState} GstWebRTCAPI.WebRTCSession#state
* @readonly * @readonly
*/ */
get state() { get state() {
@ -107,9 +107,9 @@ export default class WebRTCSession extends EventTarget {
/** /**
* The internal {@link external:RTCPeerConnection} used to manage the underlying WebRTC connection with session * The internal {@link external:RTCPeerConnection} used to manage the underlying WebRTC connection with session
* peer. Value may be null if session has no active WebRTC connection. You can listen to the * peer. Value may be null if session has no active WebRTC connection. You can listen to the
* {@link gstWebRTCAPI#event:RTCPeerConnectionChangedEvent} event to be informed when the connection is established * {@link GstWebRTCAPI#event:RTCPeerConnectionChangedEvent} event to be informed when the connection is established
* or destroyed. * or destroyed.
* @member {external:RTCPeerConnection} gstWebRTCAPI.WebRTCSession#rtcPeerConnection * @member {external:RTCPeerConnection} GstWebRTCAPI.WebRTCSession#rtcPeerConnection
* @readonly * @readonly
*/ */
get rtcPeerConnection() { get rtcPeerConnection() {
@ -120,7 +120,7 @@ export default class WebRTCSession extends EventTarget {
* Terminates the WebRTC session.<br> * Terminates the WebRTC session.<br>
* It immediately disconnects the remote peer attached to this session and unregisters the session from the * It immediately disconnects the remote peer attached to this session and unregisters the session from the
* signaling server. * signaling server.
* @method gstWebRTCAPI.WebRTCSession#close * @method GstWebRTCAPI.WebRTCSession#close
*/ */
close() { close() {
if (this._state !== SessionState.closed) { if (this._state !== SessionState.closed) {