/// import { EventEmitter } from 'events'; import { WarningName } from './constants'; import { DiagnosticError } from './errors/DiagnosticError'; import { TimeMeasurement } from './types'; import { RTCIceCandidateStats, RTCIceCandidateStatsReport, RTCSelectedIceCandidatePairStats } from './utils/candidate'; export declare interface MediaConnectionBitrateTest { /** * Raised every second with a `bitrate` parameter in kbps which represents the connection's bitrate since the last time this event was raised. * The bitrate value is limited by either your downlink or uplink, whichever is lower. * For example, if your downlink and uplink is 50mbps and 10mbps respectively, bitrate value will not exceed 10mbps. * @param event [[MediaConnectionBitrateTest.Events.Bitrate]]. * @param listener A callback with a `bitrate`(kbps) parameter since the last time this event was raised. * @returns This [[MediaConnectionBitrateTest]] instance. * @event */ on(event: MediaConnectionBitrateTest.Events.Bitrate, listener: (bitrate: number) => any): this; /** * Raised when the test encounters an error. * When this happens, the test will immediately stop and emit [[MediaConnectionBitrateTest.Events.End]]. * @param event [[MediaConnectionBitrateTest.Events.Error]]. * @param listener A callback with a [[DiagnosticError]] parameter. * @returns This [[MediaConnectionBitrateTest]] instance. * @event */ on(event: MediaConnectionBitrateTest.Events.Error, listener: (error: DiagnosticError) => any): this; /** * Raised upon completion of the test. * @param event [[MediaConnectionBitrateTest.Events.End]]. * @param listener A callback with a [[MediaConnectionBitrateTest.Report]] parameter. * @returns This [[MediaConnectionBitrateTest]] instance. * @event */ on(event: MediaConnectionBitrateTest.Events.End, listener: (report: MediaConnectionBitrateTest.Report) => any): this; /** * Raised when the test encounters a non-fatal warning during its run-time. * @param event [[MediaConnectionBitrateTest.Events.Warning]]. * @param listener A callback with a [[WarningName]] parameter. * @returns This [[MediaConnectionBitrateTest]] instance. * @event */ on(event: MediaConnectionBitrateTest.Events.Warning, listener: (warningName: WarningName) => any): this; /** * Raised when the test clears a previously encountered non-fatal warning during its run-time. * @param event [[MediaConnectionBitrateTest.Events.WarningCleared]]. * @param listener A callback with a [[WarningName]] parameter. * @returns This [[MediaConnectionBitrateTest]] instance. * @event */ on(event: MediaConnectionBitrateTest.Events.WarningCleared, listener: (warningName: WarningName) => any): this; } /** * MediaConnectionBitrateTest uses two [RTCPeerConnections](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) * connected via a [Twilio Network Traversal Service](https://www.twilio.com/docs/stun-turn). * Using [RTCDataChannel](https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel), one RTCPeerConnection will saturate the data channel buffer and will * constantly send data packets to the other RTCPeerConnection. The receiving peer will measure the bitrate base on the amount of packets received every second. * See [[MediaConnectionBitrateTest.Options.iceServers]] for information how to use Twilio NTS. */ export declare class MediaConnectionBitrateTest extends EventEmitter { /** * Name of this test */ static readonly testName: string; /** * Active warnings to keep track of. */ readonly activeWarnings: Set; /** * Interval id for checking bitrate */ private _checkBitrateIntervalId; /** * A timestamp of when the test ends. */ private _endTime; /** * Errors detected during the test */ private _errors; /** * An array of WebRTC stats for the ICE candidates gathered when connecting to media. */ private _iceCandidateStats; /** * Number of bytes received the last time it was checked */ private _lastBytesChecked; /** * Last timestamp when the bytes received was checked */ private _lastCheckedTimestamp; /** * The options passed to [[MediaConnectionBitrateTest]] constructor. */ private _options; /** * The RTCPeerConnection that will receive data */ private _pcReceiver; /** * The RTCPeerConnection that will send data */ private _pcSender; /** * RTCDataChannel to use for sending data */ private _rtcDataChannel; /** * A WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected. */ private _selectedIceCandidatePairStats; /** * Interval id for sending data */ private _sendDataIntervalId; /** * A timestamp of when the test starts. This is set during initialization of the test * and not when the test succesfully starts. */ private _startTime; /** * Timeout reference that should be cleared when we receive any data. If this * times out, it means something has timed out our [[MediaConnectionBitrateTest]]. */ private _timeout; /** * Total number of bytes received by the receiver RTCPeerConnection */ private _totalBytesReceived; /** * Bitrate (kbps) values collected during the test */ private _values; /** * Construct a [[MediaConnectionBitrateTest]] instance. The test will start immediately. * Test should be allowed to run for a minimum of 8 seconds. To stop the test, call [[MediaConnectionBitrateTest.stop]]. * @constructor * @param options */ constructor(options: MediaConnectionBitrateTest.ExtendedOptions); /** * Stops the current test. */ stop(): void; /** * Calculate bitrate by comparing bytes received between current time and the last time it was checked */ private _checkBitrate; /** * Generate and returns the report for this test */ private _getReport; /** * Check current bitrate values and emit warnings * if [[WarningName.LowBitrate]] criteria are met. */ private _maybeEmitWarning; /** * Called when an error is detected * @param message - Message that describes the error * @param error - The error object * @param isFatal - Whether this is a fatal error */ private _onError; /** * Called when a local candidate is gathered * @param remotePc - The remote RTCPeerConnection */ private _onIceCandidate; /** * Called when a message is received * @param event */ private _onMessageReceived; /** * Called when an answer is created by the receiver * @param answer - The answer session description created by the receiver RTCPeerConnection */ private _onReceiverAnswerCreated; /** * Called when an offer has been created by the sender * @param offer - The offer session description created by the sender RTCPeerConnection */ private _onSenderOfferCreated; /** * Send packets using data channel */ private _sendData; /** * Setup data channel for sending data */ private _setupDataChannel; /** * Setup network related event listeners on a PeerConnection * @param pc */ private _setupNetworkListeners; /** * Starts the test. */ private _startTest; } export declare namespace MediaConnectionBitrateTest { /** * Possible events that a [[MediaConnectionBitrateTest]] might emit. See [[MediaConnectionBitrateTest.on]]. */ enum Events { Bitrate = "bitrate", End = "end", Error = "error", Warning = "warning", WarningCleared = "warning-cleared" } /** * Options that may be passed to [[MediaConnectionBitrateTest]] constructor for internal testing. * @internalapi */ interface ExtendedOptions extends Options { /** * A function that generates a WebRTC stats report containing relevant information about ICE candidates for * the given [PeerConnection](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) */ getRTCIceCandidateStatsReport?: (peerConnection: RTCPeerConnection) => Promise; } /** * Options passed to [[MediaConnectionBitrateTest]] constructor. */ interface Options { /** * The array of [RTCIceServer](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceServer) configurations to use. * You need to provide STUN and TURN server configurations to ensure that your network bitrate is tested. * You can use [Twilio's Network Traversal Service](https://www.twilio.com/stun-turn) to get STUN and TURN server configurations. * * The following example demonstrates how to use the [twilio npm module](https://www.npmjs.com/package/twilio) to generate * credentials with a ttl of 120 seconds, using UDP protocol, and specifying ashburn as the * [edge location](https://www.twilio.com/docs/global-infrastructure/edge-locations). * * ```ts * import Client from 'twilio'; * import { testMediaConnectionBitrate } from '@twilio/rtc-diagnostics'; * * // Generate the STUN and TURN server credentials with a ttl of 120 seconds * const client = Client(twilioAccountSid, authToken); * const token = await client.tokens.create({ ttl: 120 }); * const iceServers = []; * * // Grab STUN server * iceServers.push({ urls: token.iceServers.find(item => item.urls.includes('stun:global.stun.twilio.com')).urls }); * * // Grab TURN servers. * // Use the following filters if you want to use UDP, TCP, or TLS * // UDP: turn:global.turn.twilio.com:3478?transport=udp * // TCP: turn:global.turn.twilio.com:3478?transport=tcp * // TLS: turn:global.turn.twilio.com:443?transport=tcp * let { urls, username, credential } = token.iceServers * .find(item => item.url === 'turn:global.turn.twilio.com:3478?transport=udp'); * iceServers.push({ urls, username, credential }); * * // By default, global will be used as the default edge location. * // You can replace global with a specific edge name. * iceServers.forEach(iceServer => { * iceServer.urls = iceServer.urls.replace('global', 'ashburn'); * }); * * // Use the TURN credentials using the iceServers parameter * const mediaConnectionBitrateTest = testMediaConnectionBitrate({ iceServers }); * ``` * Note, for production code, the above code should not be executed client side as it requires the authToken which must be treated like a private key. */ iceServers: RTCIceServer[]; /** * The minimum bitrate in kilobits per second expected to be available. * This value is used to determine when to raise [[WarningName.LowBitrate]] warning. * @default 100 */ minBitrateThreshold?: number; } /** * Represents the report generated from a [[MediaConnectionBitrateTest]]. */ interface Report { /** * Average bitrate calculated during the test. */ averageBitrate: number; /** * Any errors that occurred during the test. */ errors: DiagnosticError[]; /** * An array of WebRTC stats for the ICE candidates gathered when connecting to media. */ iceCandidateStats: RTCIceCandidateStats[]; /** * A WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected. */ selectedIceCandidatePairStats?: RTCSelectedIceCandidatePairStats; /** * The name of the test. */ testName: typeof MediaConnectionBitrateTest.testName; /** * Time measurements of test run time. */ testTiming: TimeMeasurement; /** * Bitrate values collected during the test. */ values: number[]; } } /** * The test uses two [RTCPeerConnections](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) connected via a Twilio TURN server. * Using [RTCDataChannel](https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel), one RTCPeerConnection will saturate the data channel buffer and will * constantly send data packets to the other RTCPeerConnection. The receiving peer will measure the bitrate base on the amount of packets received every second. * * Example: * ```ts * import { testMediaConnectionBitrate } from '@twilio/rtc-diagnostics'; * * const mediaConnectionBitrateTest = testMediaConnectionBitrate({ * iceServers: [{ * urls: 'stun:global.stun.twilio.com:3478?transport=udp', * }, { * credential: 'bar', * username: 'foo', * urls: 'turn:global.turn.twilio.com:3478?transport=udp', * }], * }); * * mediaConnectionBitrateTest.on('bitrate', (bitrate) => { * console.log(bitrate); * }); * * mediaConnectionBitrateTest.on('error', (error) => { * console.log(error); * }); * * mediaConnectionBitrateTest.on('end', (report) => { * console.log(report); * }); * * // Run the test for 15 seconds * setTimeout(() => { * mediaConnectionBitrateTest.stop(); * }, 15000); * ``` * See [[MediaConnectionBitrateTest.Options.iceServers]] for details on how to obtain STUN and TURN server configurations. */ export declare function testMediaConnectionBitrate(options: MediaConnectionBitrateTest.Options): MediaConnectionBitrateTest;