diff --git a/net/webrtc/gstwebrtc-api/.eslintrc.json b/net/webrtc/gstwebrtc-api/.eslintrc.json index b804e8ca5..6e5ebba52 100644 --- a/net/webrtc/gstwebrtc-api/.eslintrc.json +++ b/net/webrtc/gstwebrtc-api/.eslintrc.json @@ -56,6 +56,10 @@ "no-multiple-empty-lines": "error", "no-trailing-spaces": "error", "quotes": "error", - "semi": "error" - } + "semi": "error", + "jsdoc/no-undefined-types": "warn" + }, + "plugins": [ + "jsdoc" + ] } diff --git a/net/webrtc/gstwebrtc-api/jsdoc.conf.json b/net/webrtc/gstwebrtc-api/jsdoc.conf.json new file mode 100644 index 000000000..f023cb6c8 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/jsdoc.conf.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + "node_modules/jsdoc-tsimport-plugin/index.js" + ] +} diff --git a/net/webrtc/gstwebrtc-api/package.json b/net/webrtc/gstwebrtc-api/package.json index f06af648f..ebeab7d1a 100644 --- a/net/webrtc/gstwebrtc-api/package.json +++ b/net/webrtc/gstwebrtc-api/package.json @@ -32,6 +32,7 @@ "docs/", "src/", "test/", + "types/", "index.html", "LICENSE-MPL-2.0", "webpack.config.cjs" @@ -39,16 +40,19 @@ "devDependencies": { "chai": "4.3.8", "eslint": "8.49.0", + "eslint-plugin-jsdoc": "50.6.1", "html-webpack-plugin": "5.5.3", "jsdoc": "4.0.2", "mocha": "10.2.0", "rimraf": "5.0.1", "terser-webpack-plugin": "5.3.9", + "typescript": "5.7.3", "webpack": "5.88.2", "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.1" }, "dependencies": { + "jsdoc-tsimport-plugin": "1.0.5", "patch-package": "8.0.0", "webrtc-adapter": "8.2.3" }, @@ -56,11 +60,13 @@ "check": "eslint src", "format": "eslint --fix --fix-type layout src", "build": "rimraf dist && webpack", - "docs": "rimraf docs && jsdoc src/*.js -d docs/ -p package.json -R README.md", + "docs": "rimraf docs && jsdoc src/*.js -d docs/ -p package.json -R README.md -c jsdoc.conf.json", "make": "npm run check && npm run build && npm run docs", "test": "mocha --node-env=test --exit", "prepack": "npm run test && npm run make", "start": "webpack serve", "postinstall": "patch-package" - } + }, + "types": "types/index.d.ts", + "main": "src/index.js" } diff --git a/net/webrtc/gstwebrtc-api/src/com-channel.js b/net/webrtc/gstwebrtc-api/src/com-channel.js index e9b9fa543..0947e78bb 100644 --- a/net/webrtc/gstwebrtc-api/src/com-channel.js +++ b/net/webrtc/gstwebrtc-api/src/com-channel.js @@ -53,7 +53,7 @@ function normalizeProducer(producer, excludedId) { return Object.freeze(normalizedProducer); } -export default class ComChannel extends EventTarget { +class ComChannel extends EventTarget { constructor(url, meta, webrtcConfig) { super(); @@ -336,3 +336,5 @@ export default class ComChannel extends EventTarget { } } } + +export default ComChannel; diff --git a/net/webrtc/gstwebrtc-api/src/config.js b/net/webrtc/gstwebrtc-api/src/config.js index 9b726fc11..5d8236380 100644 --- a/net/webrtc/gstwebrtc-api/src/config.js +++ b/net/webrtc/gstwebrtc-api/src/config.js @@ -27,9 +27,14 @@ * @property {number} reconnectionTimeout=2500 - Timeout in milliseconds to reconnect to the signaling server in * case of an unexpected disconnection. * @property {object} webrtcConfig={iceServers...} - The WebRTC peer connection configuration passed to - * {@link external:RTCPeerConnection}. Default configuration only includes a list of free STUN servers + * {@link RTCPeerConnection}. Default configuration only includes a list of free STUN servers * (stun[0-4].l.google.com:19302). */ + +/** + * Default GstWebRTCAPI configuration. + * @type {GstWebRTCConfig} + */ const defaultConfig = Object.freeze({ meta: null, signalingServerUrl: "ws://127.0.0.1:8443", @@ -46,4 +51,4 @@ const defaultConfig = Object.freeze({ } }); -export { defaultConfig as default }; +export default defaultConfig; diff --git a/net/webrtc/gstwebrtc-api/src/consumer-session.js b/net/webrtc/gstwebrtc-api/src/consumer-session.js index 7dddd86fb..660f7f39f 100644 --- a/net/webrtc/gstwebrtc-api/src/consumer-session.js +++ b/net/webrtc/gstwebrtc-api/src/consumer-session.js @@ -15,30 +15,30 @@ import RemoteController from "./remote-controller.js"; /** * Event name: "streamsChanged".
- * Triggered when the underlying media streams of a {@link GstWebRTCAPI.ConsumerSession} change. + * Triggered when the underlying media streams of a {@link ConsumerSession} change. * @event GstWebRTCAPI#StreamsChangedEvent - * @type {external:Event} - * @see GstWebRTCAPI.ConsumerSession#streams + * @type {Event} + * @see ConsumerSession#streams */ /** * Event name: "remoteControllerChanged".
- * Triggered when the underlying remote controller of a {@link GstWebRTCAPI.ConsumerSession} changes. + * Triggered when the underlying remote controller of a {@link ConsumerSession} changes. * @event GstWebRTCAPI#RemoteControllerChangedEvent - * @type {external:Event} - * @see GstWebRTCAPI.ConsumerSession#remoteController + * @type {Event} + * @see ConsumerSession#remoteController */ /** - * @class GstWebRTCAPI.ConsumerSession + * @class ConsumerSession * @hideconstructor * @classdesc Consumer session managing a peer-to-peer WebRTC channel between a remote producer and this client * instance. *

Call {@link GstWebRTCAPI#createConsumerSession} to create a ConsumerSession instance.

- * @extends {GstWebRTCAPI.WebRTCSession} + * @extends {WebRTCSession} * @fires {@link GstWebRTCAPI#event:StreamsChangedEvent} * @fires {@link GstWebRTCAPI#event:RemoteControllerChangedEvent} */ -export default class ConsumerSession extends WebRTCSession { +class ConsumerSession extends WebRTCSession { constructor(peerId, comChannel, offerOptions) { super(peerId, comChannel); this._streams = []; @@ -60,6 +60,7 @@ export default class ConsumerSession extends WebRTCSession { /** * Defines whether the SDP should be munged in order to enable stereo with chrome. + * @method * @param {boolean} enable - Enable or disable the hack, default is false */ set mungeStereoHack(enable) { @@ -69,36 +70,35 @@ export default class ConsumerSession extends WebRTCSession { } /** - * The array of remote media streams consumed locally through this WebRTC channel. - * @member {external:MediaStream[]} GstWebRTCAPI.ConsumerSession#streams - * @readonly - */ + * The array of remote media streams consumed locally through this WebRTC channel. + * @type {MediaStream[]} + * @readonly + */ get streams() { return this._streams; } /** - * The remote controller associated with this WebRTC consumer session. Value may be null if consumer session - * has no remote controller. - * @member {GstWebRTCAPI.RemoteController} GstWebRTCAPI.ConsumerSession#remoteController - * @readonly - */ + * The remote controller associated with this WebRTC consumer session. Value may be null if consumer session + * has no remote controller. + * @type {RemoteController} + * @readonly + */ get remoteController() { return this._remoteController; } /** - * Connects the consumer session to its remote producer.
- * 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. - *

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}, - * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent} - * events.

- * @method GstWebRTCAPI.ConsumerSession#connect - * @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). - */ + * Connects the consumer session to its remote producer.
+ * 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. + *

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}, + * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent} + * events.

+ * @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). + */ connect() { if (!this._comChannel || (this._state === SessionState.closed)) { return false; @@ -357,3 +357,5 @@ export default class ConsumerSession extends WebRTCSession { } } } + +export default ConsumerSession; diff --git a/net/webrtc/gstwebrtc-api/src/gstwebrtc-api.js b/net/webrtc/gstwebrtc-api/src/gstwebrtc-api.js index ad66eaf8b..a98290486 100644 --- a/net/webrtc/gstwebrtc-api/src/gstwebrtc-api.js +++ b/net/webrtc/gstwebrtc-api/src/gstwebrtc-api.js @@ -12,16 +12,16 @@ import defaultConfig from "./config.js"; import ComChannel from "./com-channel.js"; import SessionState from "./session-state.js"; +import ConsumerSession from "./consumer-session.js"; +import ProducerSession from "./producer-session.js"; -/** - * @class GstWebRTCAPI - * @classdesc The API entry point that manages a WebRTC. - */ -export default class GstWebRTCAPI { +class GstWebRTCAPI { /** - * @constructor GstWebRTCAPI - * @param {GstWebRTCConfig} [userConfig] - The user configuration.
Only the parameters different from the default - * ones need to be provided. + * @class GstWebRTCAPI + * @classdesc The API entry point that manages a WebRTC. + * @constructor + * @param {import('./config.js').GstWebRTCConfig} [userConfig] - The user configuration.
+ * Only the parameters different from the default ones need to be provided. */ constructor(userConfig) { this._channel = null; @@ -43,12 +43,12 @@ export default class GstWebRTCAPI { } /** - * @interface GstWebRTCAPI.ConnectionListener + * @interface 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 + * @method ConnectionListener#connected * @abstract * @param {string} clientId - The unique identifier of this WebRTC client.
This identifier is provided by the * signaling server to uniquely identify each connected peer. @@ -56,15 +56,14 @@ export default class GstWebRTCAPI { /** * Callback method called when this client disconnects from the WebRTC signaling server. * The callback implementation should not throw any exception. - * @method GstWebRTCAPI.ConnectionListener#disconnected + * @method ConnectionListener#disconnected * @abstract */ /** * 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. + * @param {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. */ @@ -85,8 +84,7 @@ export default class GstWebRTCAPI { /** * Unregisters a connection listener.
* 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. + * @param {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. */ @@ -102,7 +100,6 @@ export default class GstWebRTCAPI { /** * Unregisters all previously registered connection listeners. - * @method GstWebRTCAPI#unregisterAllConnectionListeners */ unregisterAllConnectionListeners() { this._connectionListeners = []; @@ -113,12 +110,11 @@ export default class GstWebRTCAPI { *

You can only create one producer session at a time.
* To request streaming from a new stream you will first need to close the previous producer session.

*

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 + * {@link ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to * listen to the connection state.

- * @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 + * @param {MediaStream} stream - The audio/video stream to offer as a producer through WebRTC. + * @returns {ProducerSession} The created producer session or null in case of error. To start streaming, + * you still need to call {@link ProducerSession#start} after adding on the returned session all the event * listeners you may need. */ createProducerSession(stream) { @@ -130,7 +126,7 @@ export default class GstWebRTCAPI { /** * Information about a remote producer registered by the signaling server. - * @typedef {object} GstWebRTCAPI.Producer + * @typedef {object} 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, @@ -140,38 +136,36 @@ export default class GstWebRTCAPI { /** * Gets the list of all remote WebRTC producers available on the signaling server. *

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 + * {@link ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to * listen to the connection state.

- * @method GstWebRTCAPI#getAvailableProducers - * @returns {GstWebRTCAPI.Producer[]} The list of remote WebRTC producers available. + * @returns {Producer[]} The list of remote WebRTC producers available. */ getAvailableProducers() { return Object.values(this._producers); } /** - * @interface GstWebRTCAPI.ProducersListener + * @interface 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 + * @method ProducersListener#producerAdded * @abstract - * @param {GstWebRTCAPI.Producer} producer - The remote producer added on server-side. + * @param {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 + * @method ProducersListener#producerRemoved * @abstract - * @param {GstWebRTCAPI.Producer} producer - The remote producer removed on server-side. + * @param {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. + * @param {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. */ @@ -192,8 +186,7 @@ export default class GstWebRTCAPI { /** * Unregisters a producers listener.
* 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. + * @param {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. */ @@ -209,7 +202,6 @@ export default class GstWebRTCAPI { /** * Unregisters all previously registered producers listeners. - * @method GstWebRTCAPI#unregisterAllProducersListeners */ unregisterAllProducersListeners() { this._producersListeners = []; @@ -219,13 +211,12 @@ export default class GstWebRTCAPI { * Creates a consumer session by connecting the local client to a remote WebRTC producer. *

You can only create one consumer session per remote producer.

*

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} method to + * {@link ConnectionListener} interface and {@link GstWebRTCAPI#registerConnectionListener} method to * listen to the connection state.

- * @method GstWebRTCAPI#createConsumerSession * @param {string} producerId - The unique identifier of the remote producer to connect to. - * @returns {GstWebRTCAPI.ConsumerSession} The WebRTC session between the selected remote producer and this local + * @returns {ConsumerSession} The WebRTC session between the selected remote producer and this local * consumer, or null in case of error. To start connecting and receiving the remote streams, you still need to call - * {@link GstWebRTCAPI.ConsumerSession#connect} after adding on the returned session all the event listeners you may + * {@link ConsumerSession#connect} after adding on the returned session all the event listeners you may * need. */ createConsumerSession(producerId) { @@ -238,12 +229,11 @@ export default class GstWebRTCAPI { /** * Creates a consumer session by connecting the local client to a remote WebRTC producer and creating the offer. *

See {@link GstWebRTCAPI#createConsumerSession} for more information

- * @method GstWebRTCAPI#createConsumerSessionWithOfferOptions * @param {string} producerId - The unique identifier of the remote producer to connect to. - * @param {external:RTCOfferOptions} offerOptions - An object to use when creating the offer. - * @returns {GstWebRTCAPI.ConsumerSession} The WebRTC session between the selected remote producer and this local + * @param {RTCOfferOptions} offerOptions - An object to use when creating the offer. + * @returns {ConsumerSession} The WebRTC session between the selected remote producer and this local * consumer, or null in case of error. To start connecting and receiving the remote streams, you still need to call - * {@link GstWebRTCAPI.ConsumerSession#connect} after adding on the returned session all the event listeners you may + * {@link ConsumerSession#connect} after adding on the returned session all the event listeners you may * need. */ createConsumerSessionWithOfferOptions(producerId, offerOptions) { @@ -365,3 +355,5 @@ export default class GstWebRTCAPI { } GstWebRTCAPI.SessionState = SessionState; + +export default GstWebRTCAPI; diff --git a/net/webrtc/gstwebrtc-api/src/index.js b/net/webrtc/gstwebrtc-api/src/index.js index 29119a570..f928fb20a 100644 --- a/net/webrtc/gstwebrtc-api/src/index.js +++ b/net/webrtc/gstwebrtc-api/src/index.js @@ -24,6 +24,10 @@ import GstWebRTCAPI from "./gstwebrtc-api.js"; * @external RTCDataChannel * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel */ +/** + * @external RTCOfferOptions + * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer#options + */ /** * @external EventTarget * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget @@ -52,3 +56,5 @@ import GstWebRTCAPI from "./gstwebrtc-api.js"; if (!window.GstWebRTCAPI) { window.GstWebRTCAPI = GstWebRTCAPI; } + +export default GstWebRTCAPI; diff --git a/net/webrtc/gstwebrtc-api/src/producer-session.js b/net/webrtc/gstwebrtc-api/src/producer-session.js index b09c608bc..97e69053c 100644 --- a/net/webrtc/gstwebrtc-api/src/producer-session.js +++ b/net/webrtc/gstwebrtc-api/src/producer-session.js @@ -13,10 +13,10 @@ import WebRTCSession from "./webrtc-session.js"; import SessionState from "./session-state.js"; /** - * @class GstWebRTCAPI.ClientSession + * @class ClientSession * @hideconstructor * @classdesc Client session representing a link between a remote consumer and a local producer session. - * @extends {GstWebRTCAPI.WebRTCSession} + * @extends {WebRTCSession} */ class ClientSession extends WebRTCSession { constructor(peerId, sessionId, comChannel, stream) { @@ -102,35 +102,35 @@ class ClientSession extends WebRTCSession { /** * Event name: "clientConsumerAdded".
- * Triggered when a remote consumer peer connects to a local {@link GstWebRTCAPI.ProducerSession}. + * Triggered when a remote consumer peer connects to a local {@link ProducerSession}. * @event GstWebRTCAPI#ClientConsumerAddedEvent - * @type {external:CustomEvent} - * @property {GstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the added consumer peer. - * @see GstWebRTCAPI.ProducerSession + * @type {CustomEvent} + * @property {ClientSession} detail - The WebRTC session associated with the added consumer peer. + * @see ProducerSession */ /** * Event name: "clientConsumerRemoved".
- * Triggered when a remote consumer peer disconnects from a local {@link GstWebRTCAPI.ProducerSession}. + * Triggered when a remote consumer peer disconnects from a local {@link ProducerSession}. * @event GstWebRTCAPI#ClientConsumerRemovedEvent - * @type {external:CustomEvent} - * @property {GstWebRTCAPI.ClientSession} detail - The WebRTC session associated with the removed consumer peer. - * @see GstWebRTCAPI.ProducerSession + * @type {CustomEvent} + * @property {ClientSession} detail - The WebRTC session associated with the removed consumer peer. + * @see ProducerSession */ /** - * @class GstWebRTCAPI.ProducerSession + * @class ProducerSession * @hideconstructor - * @classdesc Producer session managing the streaming out of a local {@link external:MediaStream}.
+ * @classdesc Producer session managing the streaming out of a local {@link MediaStream}.
* It manages all underlying WebRTC connections to each peer client consuming the stream. *

Call {@link GstWebRTCAPI#createProducerSession} to create a ProducerSession instance.

- * @extends {external:EventTarget} + * @extends {EventTarget} * @fires {@link GstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:StateChangedEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent} * @fires {@link GstWebRTCAPI#event:ClientConsumerAddedEvent} * @fires {@link GstWebRTCAPI#event:ClientConsumerRemovedEvent} */ -export default class ProducerSession extends EventTarget { +class ProducerSession extends EventTarget { constructor(comChannel, stream) { super(); @@ -141,35 +141,34 @@ export default class ProducerSession extends EventTarget { } /** - * The local stream produced out by this session. - * @member {external:MediaStream} GstWebRTCAPI.ProducerSession#stream - * @readonly - */ + * The local stream produced out by this session. + * @type {MediaStream} + * @readonly + */ get stream() { return this._stream; } /** - * The current producer session state. - * @member {GstWebRTCAPI.SessionState} GstWebRTCAPI.ProducerSession#state - * @readonly - */ + * The current producer session state. + * @type {SessionState} + * @readonly + */ get state() { return this._state; } /** - * Starts the producer session.
- * 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. - *

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}, - * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent} - * events.

- * @method GstWebRTCAPI.ProducerSession#start - * @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). - */ + * Starts the producer session.
+ * 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. + *

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}, + * [stateChanged]{@link GstWebRTCAPI#event:StateChangedEvent} and/or [closed]{@link GstWebRTCAPI#event:ClosedEvent} + * events.

+ * @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). + */ start() { if (!this._comChannel || (this._state === SessionState.closed)) { return false; @@ -200,11 +199,10 @@ export default class ProducerSession extends EventTarget { } /** - * Terminates the producer session.
- * It immediately disconnects all peer consumers attached to this producer session and unregisters the producer - * from the signaling server. - * @method GstWebRTCAPI.ProducerSession#close - */ + * Terminates the producer session.
+ * It immediately disconnects all peer consumers attached to this producer session and unregisters the producer + * from the signaling server. + */ close() { if (this._state !== SessionState.closed) { for (const track of this._stream.getTracks()) { @@ -277,3 +275,5 @@ export default class ProducerSession extends EventTarget { } } } + +export default ProducerSession; diff --git a/net/webrtc/gstwebrtc-api/src/remote-controller.js b/net/webrtc/gstwebrtc-api/src/remote-controller.js index 6af8c4841..ebd3034ee 100644 --- a/net/webrtc/gstwebrtc-api/src/remote-controller.js +++ b/net/webrtc/gstwebrtc-api/src/remote-controller.js @@ -10,6 +10,7 @@ */ import getKeysymString from "./keysyms.js"; +import ConsumerSession from "./consumer-session.js"; const eventsNames = Object.freeze([ "wheel", @@ -68,21 +69,21 @@ function getModifiers(event) { * Event name: "info".
* Triggered when a remote peer sends an information message over the control data channel. * @event GstWebRTCAPI#InfoEvent - * @type {external:CustomEvent} + * @type {CustomEvent} * @property {object} detail - The info message - * @see GstWebRTCAPI.RemoteController + * @see RemoteController */ /** * Event name: "controlResponse".
* Triggered when a remote peer sends a response after a control request. * @event GstWebRTCAPI#ControlResponseEvent - * @type {external:CustomEvent} + * @type {CustomEvent} * @property {object} detail - The response message - * @see GstWebRTCAPI.RemoteController + * @see RemoteController */ /** - * @class GstWebRTCAPI.RemoteController + * @class RemoteController * @hideconstructor * @classdesc Manages a specific WebRTC data channel created by a remote GStreamer webrtcsink producer and offering * remote control of the producer through @@ -90,18 +91,18 @@ function getModifiers(event) { *

The remote control data channel is created by the GStreamer webrtcsink element on the producer side. Then it is * announced through the consumer session thanks to the {@link gstWebRTCAPI#event:RemoteControllerChangedEvent} * event.

- *

You can attach an {@link external:HTMLVideoElement} to the remote controller, then all mouse and keyboard events + *

You can attach an {@link HTMLVideoElement} to the remote controller, then all mouse and keyboard events * emitted by this element will be automatically relayed to the remote producer.

- * @extends {external:EventTarget} + * @extends {EventTarget} * @fires {@link GstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent} * @fires {@link GstWebRTCAPI#event:InfoEvent} * @fires {@link GstWebRTCAPI#event:ControlResponseEvent} - * @see GstWebRTCAPI.ConsumerSession#remoteController - * @see GstWebRTCAPI.RemoteController#attachVideoElement + * @see ConsumerSession#remoteController + * @see 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 */ -export default class RemoteController extends EventTarget { +class RemoteController extends EventTarget { constructor(rtcDataChannel, consumerSession) { super(); @@ -150,44 +151,43 @@ export default class RemoteController extends EventTarget { /** - * 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. - * @member {external:RTCDataChannel} GstWebRTCAPI.RemoteController#rtcDataChannel - * @readonly - */ + * 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. + * @type {RTCDataChannel} + * @readonly + */ get rtcDataChannel() { return this._rtcDataChannel; } /** - * The consumer session associated with this remote controller. - * @member {GstWebRTCAPI.ConsumerSession} GstWebRTCAPI.RemoteController#consumerSession - * @readonly - */ + * The consumer session associated with this remote controller. + * @type {ConsumerSession} + * @readonly + */ get consumerSession() { return this._consumerSession; } /** - * 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. - * @member {external:HTMLVideoElement} GstWebRTCAPI.RemoteController#videoElement - * @readonly - * @see GstWebRTCAPI.RemoteController#attachVideoElement - */ + * 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. + * @type {HTMLVideoElement} + * @readonly + * @see RemoteController#attachVideoElement + */ get videoElement() { return this._videoElement; } /** - * Associates a video element with this remote controller.
- * 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. - * @method GstWebRTCAPI.RemoteController#attachVideoElement - * @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 - * valid instance of an {@link external:HTMLVideoElement}, then the method does nothing. - */ + * Associates a video element with this remote controller.
+ * 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. + * @param {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 + * valid instance of an {@link HTMLVideoElement}, then the method does nothing. + */ attachVideoElement(element) { if ((element instanceof HTMLVideoElement) && (element !== this._videoElement)) { if (this._videoElement) { @@ -218,13 +218,12 @@ export default class RemoteController extends EventTarget { } /** - * Send a request over the control data channel.
- * - * @method GstWebRTCAPI.RemoteController#sendControlRequest - * @fires {@link GstWebRTCAPI#event:ErrorEvent} - * @param {object|string} request - The request to send over the channel - * @returns {number} The identifier attributed to the request, or -1 if an exception occurred - */ + * Send a request over the control data channel.
+ * + * @fires {@link GstWebRTCAPI#event:ErrorEvent} + * @param {object|string} request - The request to send over the channel + * @returns {number} The identifier attributed to the request, or -1 if an exception occurred + */ sendControlRequest(request) { try { if (!request || ((typeof (request) !== "object") && (typeof (request) !== "string"))) { @@ -253,11 +252,10 @@ export default class RemoteController extends EventTarget { } /** - * Closes the remote controller channel.
- * 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. - * @method GstWebRTCAPI.RemoteController#close - */ + * Closes the remote controller channel.
+ * 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. + */ close() { this.attachVideoElement(null); @@ -417,3 +415,5 @@ export default class RemoteController extends EventTarget { } } } + +export default RemoteController; diff --git a/net/webrtc/gstwebrtc-api/src/session-state.js b/net/webrtc/gstwebrtc-api/src/session-state.js index b7babf918..7953e001a 100644 --- a/net/webrtc/gstwebrtc-api/src/session-state.js +++ b/net/webrtc/gstwebrtc-api/src/session-state.js @@ -12,21 +12,29 @@ /** * Session states enumeration.
* Session state always increases from idle to closed and never switches backwards. - * @typedef {enum} GstWebRTCAPI.SessionState + * @enum {number} * @readonly - * @property {0} idle - Default state when creating a new session, goes to connecting when starting - * the session. - * @property {1} connecting - Session is trying to connect to remote peers, goes to streaming in case of - * success or closed in case of error. - * @property {2} streaming - Session is correctly connected to remote peers and currently streaming audio/video, goes - * to closed when any peer closes the session. - * @property {3} closed - Session is closed and can be garbage collected, state will not change anymore. */ -const SessionState = Object.freeze({ +const SessionState = /** @type {const} */ { + /** + * (0) Default state when creating a new session, goes to connecting when starting the session. + */ idle: 0, + /** + * (1) Session is trying to connect to remote peers, goes to streaming in case of + * success or closed in case of error. + */ connecting: 1, + /** + * (2) Session is correctly connected to remote peers and currently streaming audio/video, goes + * to closed when any peer closes the session. + */ streaming: 2, + /** + * (3) Session is closed and can be garbage collected, state will not change anymore. + */ closed: 3 -}); +}; +Object.freeze(SessionState); -export { SessionState as default }; +export default SessionState; diff --git a/net/webrtc/gstwebrtc-api/src/webrtc-session.js b/net/webrtc/gstwebrtc-api/src/webrtc-session.js index 6e3c004b9..b11b431ed 100644 --- a/net/webrtc/gstwebrtc-api/src/webrtc-session.js +++ b/net/webrtc/gstwebrtc-api/src/webrtc-session.js @@ -10,60 +10,62 @@ */ import SessionState from "./session-state.js"; +import ProducerSession from "./producer-session.js"; +import ClientSession from "./producer-session.js"; /** * Event name: "error".
* Triggered when any kind of error occurs. *

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 - * {@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 + * but in the specific case of a {@link ProducerSession}, when the error occurs on an underlying + * {@link ClientSession} between the producer session and a remote client consuming the streamed media, + * then only the failing {@link ClientSession} is closed. The producer session can keep on serving the * other consumer peers.

* @event GstWebRTCAPI#ErrorEvent - * @type {external:ErrorEvent} + * @type {ErrorEvent} * @property {string} message - The error message. - * @property {external:Error} error - The error exception. - * @see GstWebRTCAPI.WebRTCSession - * @see GstWebRTCAPI.RemoteController + * @property {Error} error - The error exception. + * @see WebRTCSession + * @see RemoteController */ /** * Event name: "stateChanged".
* Triggered each time a session state changes. * @event GstWebRTCAPI#StateChangedEvent - * @type {external:Event} - * @see GstWebRTCAPI.WebRTCSession#state + * @type {Event} + * @see WebRTCSession#state */ /** * Event name: "rtcPeerConnectionChanged".
- * Triggered each time a session internal {@link external:RTCPeerConnection} changes. This can occur during the session + * Triggered each time a session internal {@link RTCPeerConnection} changes. This can occur during the session * connecting state when the peer-to-peer WebRTC connection is established, and when closing the - * {@link GstWebRTCAPI.WebRTCSession}. + * {@link WebRTCSession}. * @event GstWebRTCAPI#RTCPeerConnectionChangedEvent - * @type {external:Event} - * @see GstWebRTCAPI.WebRTCSession#rtcPeerConnection + * @type {Event} + * @see WebRTCSession#rtcPeerConnection */ /** * Event name: "closed".
* Triggered when a session is definitively closed (then it can be garbage collected as session instances are not * reusable). * @event GstWebRTCAPI#ClosedEvent - * @type {external:Event} + * @type {Event} */ /** - * @class GstWebRTCAPI.WebRTCSession + * @class WebRTCSession * @hideconstructor * @classdesc Manages a WebRTC session between a producer and a consumer (peer-to-peer channel). - * @extends {external:EventTarget} + * @extends {EventTarget} * @fires {@link GstWebRTCAPI#event:ErrorEvent} * @fires {@link GstWebRTCAPI#event:StateChangedEvent} * @fires {@link GstWebRTCAPI#event:RTCPeerConnectionChangedEvent} * @fires {@link GstWebRTCAPI#event:ClosedEvent} - * @see GstWebRTCAPI.ConsumerSession - * @see GstWebRTCAPI.ProducerSession - * @see GstWebRTCAPI.ClientSession + * @see ConsumerSession + * @see ProducerSession + * @see ClientSession */ -export default class WebRTCSession extends EventTarget { +class WebRTCSession extends EventTarget { constructor(peerId, comChannel) { super(); @@ -75,53 +77,52 @@ export default class WebRTCSession extends EventTarget { } /** - * Unique identifier of the remote peer to which this session is connected. - * @member {string} GstWebRTCAPI.WebRTCSession#peerId - * @readonly - */ + * Unique identifier of the remote peer to which this session is connected. + * @type {string} + * @readonly + */ get peerId() { return this._peerId; } /** - * Unique identifier of this session (defined by the signaling server).
- * 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 - * session state has switched to {@link GstWebRTCAPI.SessionState#streaming}. - * @member {string} GstWebRTCAPI.WebRTCSession#sessionId - * @readonly - */ + * Unique identifier of this session (defined by the signaling server).
+ * 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 + * session state has switched to {@link SessionState#streaming}. + * @type {string} + * @readonly + */ get sessionId() { return this._sessionId; } /** - * The current WebRTC session state. - * @member {GstWebRTCAPI.SessionState} GstWebRTCAPI.WebRTCSession#state - * @readonly - */ + * The current WebRTC session state. + * @type {SessionState} + * @readonly + */ get state() { return this._state; } /** - * 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 - * {@link GstWebRTCAPI#event:RTCPeerConnectionChangedEvent} event to be informed when the connection is established - * or destroyed. - * @member {external:RTCPeerConnection} GstWebRTCAPI.WebRTCSession#rtcPeerConnection - * @readonly - */ + * The internal {@link 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 + * {@link GstWebRTCAPI#event:RTCPeerConnectionChangedEvent} event to be informed when the connection is established + * or destroyed. + * @type {RTCPeerConnection} + * @readonly + */ get rtcPeerConnection() { return this._rtcPeerConnection; } /** - * Terminates the WebRTC session.
- * It immediately disconnects the remote peer attached to this session and unregisters the session from the - * signaling server. - * @method GstWebRTCAPI.WebRTCSession#close - */ + * Terminates the WebRTC session.
+ * It immediately disconnects the remote peer attached to this session and unregisters the session from the + * signaling server. + */ close() { if (this._state !== SessionState.closed) { if ((this._state !== SessionState.idle) && this._comChannel && this._sessionId) { @@ -146,3 +147,5 @@ export default class WebRTCSession extends EventTarget { } } } + +export default WebRTCSession; diff --git a/net/webrtc/gstwebrtc-api/tsconfig.json b/net/webrtc/gstwebrtc-api/tsconfig.json new file mode 100644 index 000000000..e5dee6f2d --- /dev/null +++ b/net/webrtc/gstwebrtc-api/tsconfig.json @@ -0,0 +1,10 @@ +{ + "include": ["src/index.js"], + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "removeComments": true, + "outDir": "./types", + } +} diff --git a/net/webrtc/gstwebrtc-api/types/config.d.ts b/net/webrtc/gstwebrtc-api/types/config.d.ts new file mode 100644 index 000000000..cd3a93add --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/config.d.ts @@ -0,0 +1,8 @@ +export default defaultConfig; +export type GstWebRTCConfig = { + meta: object; + signalingServerUrl: string; + reconnectionTimeout: number; + webrtcConfig: object; +}; +declare const defaultConfig: GstWebRTCConfig; diff --git a/net/webrtc/gstwebrtc-api/types/consumer-session.d.ts b/net/webrtc/gstwebrtc-api/types/consumer-session.d.ts new file mode 100644 index 000000000..0ae6021cb --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/consumer-session.d.ts @@ -0,0 +1,9 @@ +export default ConsumerSession; +declare class ConsumerSession extends WebRTCSession { + set mungeStereoHack(enable: boolean); + readonly get streams(): MediaStream[]; + readonly get remoteController(): RemoteController; + connect(): boolean; +} +import WebRTCSession from "./webrtc-session.js"; +import RemoteController from "./remote-controller.js"; diff --git a/net/webrtc/gstwebrtc-api/types/gstwebrtc-api.d.ts b/net/webrtc/gstwebrtc-api/types/gstwebrtc-api.d.ts new file mode 100644 index 000000000..e8dfd8297 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/gstwebrtc-api.d.ts @@ -0,0 +1,34 @@ +export default GstWebRTCAPI; +declare class GstWebRTCAPI { + constructor(userConfig?: import("./config.js").GstWebRTCConfig); + registerConnectionListener(listener: ConnectionListener): boolean; + unregisterConnectionListener(listener: ConnectionListener): boolean; + unregisterAllConnectionListeners(): void; + createProducerSession(stream: MediaStream): ProducerSession; + getAvailableProducers(): any[]; + registerProducersListener(listener: ProducersListener): boolean; + unregisterProducersListener(listener: ProducersListener): boolean; + unregisterAllProducersListeners(): void; + createConsumerSession(producerId: string): ConsumerSession; + createConsumerSessionWithOfferOptions(producerId: string, offerOptions: any): ConsumerSession; +} +declare namespace GstWebRTCAPI { + export { SessionState }; +} +import ProducerSession from "./producer-session.js"; +import ConsumerSession from "./consumer-session.js"; +import SessionState from "./session-state.js"; + +/* Added manually */ +interface ConnectionListener { + connected(clientId: string): void; + disconnected(): void; +} +interface ProducersListener { + producerAdded(producer: Producer): void; + producerRemoved(producer: Producer): void; +} +type Producer = { + readonly id: string; + readonly meta: Record; +}; diff --git a/net/webrtc/gstwebrtc-api/types/index.d.ts b/net/webrtc/gstwebrtc-api/types/index.d.ts new file mode 100644 index 000000000..29e967e41 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/index.d.ts @@ -0,0 +1,2 @@ +export default GstWebRTCAPI; +import GstWebRTCAPI from "./gstwebrtc-api.js"; diff --git a/net/webrtc/gstwebrtc-api/types/producer-session.d.ts b/net/webrtc/gstwebrtc-api/types/producer-session.d.ts new file mode 100644 index 000000000..dc085325f --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/producer-session.d.ts @@ -0,0 +1,8 @@ +export default ProducerSession; +declare class ProducerSession extends EventTarget { + readonly get stream(): MediaStream; + readonly get state(): SessionState; + start(): boolean; + close(): void; +} +import SessionState from "./session-state.js"; diff --git a/net/webrtc/gstwebrtc-api/types/remote-controller.d.ts b/net/webrtc/gstwebrtc-api/types/remote-controller.d.ts new file mode 100644 index 000000000..6034c5e60 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/remote-controller.d.ts @@ -0,0 +1,10 @@ +export default RemoteController; +declare class RemoteController extends EventTarget { + readonly get rtcDataChannel(): RTCDataChannel; + readonly get consumerSession(): ConsumerSession; + readonly get videoElement(): HTMLVideoElement; + attachVideoElement(element: HTMLVideoElement | null): void; + sendControlRequest(request: object | string): number; + close(): void; +} +import ConsumerSession from "./consumer-session.js"; diff --git a/net/webrtc/gstwebrtc-api/types/session-state.d.ts b/net/webrtc/gstwebrtc-api/types/session-state.d.ts new file mode 100644 index 000000000..8151abfb6 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/session-state.d.ts @@ -0,0 +1,8 @@ +export default SessionState; +type SessionState = number; +declare namespace SessionState { + let idle: number; + let connecting: number; + let streaming: number; + let closed: number; +} diff --git a/net/webrtc/gstwebrtc-api/types/webrtc-session.d.ts b/net/webrtc/gstwebrtc-api/types/webrtc-session.d.ts new file mode 100644 index 000000000..3aed7d6f3 --- /dev/null +++ b/net/webrtc/gstwebrtc-api/types/webrtc-session.d.ts @@ -0,0 +1,9 @@ +export default WebRTCSession; +declare class WebRTCSession extends EventTarget { + readonly get peerId(): string; + readonly get sessionId(): string; + readonly get state(): SessionState; + readonly get rtcPeerConnection(): RTCPeerConnection; + close(): void; +} +import SessionState from "./session-state.js";