@twilio/voice-sdk
Version:
Twilio's JavaScript Voice SDK
563 lines (562 loc) • 17.7 kB
TypeScript
import { EventEmitter } from 'events';
import Call from '../call';
import Device from '../device';
import { TwilioError } from '../errors';
import { RTCSampleTotals } from '../rtc/sample';
import RTCSample from '../rtc/sample';
import RTCWarning from '../rtc/warning';
import { NetworkTiming, TimeMeasurement } from './timing';
/**
* Placeholder until we convert peerconnection.js to TypeScript.
* Represents the audio output object coming from Client SDK's PeerConnection object.
*/
export interface AudioOutput {
/**
* The audio element used to play out the sound.
*/
audio: HTMLAudioElement;
}
/**
* @mergeModuleWith PreflightTest
*/
export declare interface PreflightTest {
/**
* Raised when [[PreflightTest.status]] has transitioned to [[PreflightTest.Status.Completed]].
* During this time, [[PreflightTest.report]] is available and ready to be inspected.
* In some cases, this will not trigger if the test encounters a fatal error prior connecting to Twilio.
* See [[PreflightTest.failedEvent]].
* @param report
* @example `preflight.on('completed', report => console.log(report))`
* @event
*/
completedEvent(report: PreflightTest.Report): void;
/**
* Raised when [[PreflightTest.status]] has transitioned to [[PreflightTest.Status.Connected]].
* @example `preflight.on('connected', () => console.log('Test connected'))`
* @event
*/
connectedEvent(): void;
/**
* Raised when [[PreflightTest.status]] has transitioned to [[PreflightTest.Status.Failed]].
* This happens when establishing a connection to Twilio has failed or when a test call has encountered a fatal error.
* This is also raised if [[PreflightTest.stop]] is called while the test is in progress.
* @param error
* @example `preflight.on('failed', error => console.log(error))`
* @event
*/
failedEvent(error: TwilioError | DOMException): void;
/**
* Raised when the [[Call]] gets a webrtc sample object. This event is published every second.
* @param sample
* @example `preflight.on('sample', sample => console.log(sample))`
* @event
*/
sampleEvent(sample: RTCSample): void;
/**
* Raised whenever the [[Call]] encounters a warning.
* @param name - The name of the warning.
* @example `preflight.on('warning', (name, data) => console.log({ name, data }))`
* @event
*/
warningEvent(name: string, data: PreflightTest.Warning): void;
}
/**
* Runs some tests to identify issues, if any, prohibiting successful calling.
*/
export declare class PreflightTest extends EventEmitter {
/**
* The {@link Call} for this test call
*/
private _call;
/**
* Callsid generated for this test call
*/
private _callSid;
/**
* The {@link Device} for this test call
*/
private _device;
/**
* The timer when doing an echo test
* The echo test is used when fakeMicInput is set to true
*/
private _echoTimer;
/**
* The edge that the `Twilio.Device` connected to.
*/
private _edge;
/**
* End of test timestamp
*/
private _endTime;
/**
* Whether this test has already logged an insights-connection-warning.
*/
private _hasInsightsErrored;
/**
* Latest WebRTC sample collected for this test
*/
private _latestSample;
/**
* An instance of Logger to use.
*/
private _log;
/**
* Network related timing measurements for this test
*/
private _networkTiming;
/**
* The options passed to {@link PreflightTest} constructor
*/
private _options;
/**
* The report for this test.
*/
private _report;
/**
* The WebRTC ICE candidates stats information collected during the test
*/
private _rtcIceCandidateStatsReport;
/**
* WebRTC samples collected during this test
*/
private _samples;
/**
* Timer for setting up signaling connection
*/
private _signalingTimeoutTimer;
/**
* Start of test timestamp
*/
private _startTime;
/**
* Current status of this test
*/
private _status;
/**
* List of warning names and warning data detected during this test
*/
private _warnings;
/**
* Construct a {@link PreflightTest} instance.
* @param token - A Twilio JWT token string.
* @param options
*/
constructor(token: string, options: PreflightTest.ExtendedOptions);
/**
* Stops the current test and raises a failed event.
*/
stop(): void;
/**
* Emit a {PreflightTest.Warning}
*/
private _emitWarning;
/**
* Returns call quality base on the RTC Stats
*/
private _getCallQuality;
/**
* Returns the report for this test.
*/
private _getReport;
/**
* Returns RTC stats totals for this test
*/
private _getRTCSampleTotals;
/**
* Returns RTC related stats captured during the test call
*/
private _getRTCStats;
/**
* Returns a MediaStream from a media file
*/
private _getStreamFromFile;
/**
* Initialize the device
*/
private _initDevice;
/**
* Called on {@link Device} error event
* @param error
*/
private _onDeviceError;
/**
* Called on {@link Device} ready event
*/
private _onDeviceRegistered;
/**
* Called when there is a fatal error
* @param error
*/
private _onFailed;
/**
* Called when the device goes offline.
* This indicates that the test has been completed, but we won't know if it failed or not.
* The onError event will be the indicator whether the test failed.
*/
private _onUnregistered;
/**
* Clean up all handlers for device and call
*/
private _releaseHandlers;
/**
* Setup the event handlers for the {@link Call} of the test call
* @param call
*/
private _setupCallHandlers;
/**
* The callsid generated for the test call.
*/
get callSid(): string | undefined;
/**
* A timestamp in milliseconds of when the test ended.
*/
get endTime(): number | undefined;
/**
* The latest WebRTC sample collected.
*/
get latestSample(): RTCSample | undefined;
/**
* The report for this test.
*/
get report(): PreflightTest.Report | undefined;
/**
* A timestamp in milliseconds of when the test started.
*/
get startTime(): number;
/**
* The status of the test.
*/
get status(): PreflightTest.Status;
}
/**
* @mergeModuleWith PreflightTest
*/
export declare namespace PreflightTest {
/**
* The quality of the call determined by different mos ranges.
* Mos is calculated base on the WebRTC stats - rtt, jitter, and packet lost.
*/
enum CallQuality {
/**
* If the average mos is over 4.2.
*/
Excellent = "excellent",
/**
* If the average mos is between 4.1 and 4.2 both inclusive.
*/
Great = "great",
/**
* If the average mos is between 3.7 and 4.0 both inclusive.
*/
Good = "good",
/**
* If the average mos is between 3.1 and 3.6 both inclusive.
*/
Fair = "fair",
/**
* If the average mos is 3.0 or below.
*/
Degraded = "degraded"
}
/**
* Possible events that a [[PreflightTest]] might emit.
*/
enum Events {
/**
* See [[PreflightTest.completedEvent]]
*/
Completed = "completed",
/**
* See [[PreflightTest.connectedEvent]]
*/
Connected = "connected",
/**
* See [[PreflightTest.failedEvent]]
*/
Failed = "failed",
/**
* See [[PreflightTest.sampleEvent]]
*/
Sample = "sample",
/**
* See [[PreflightTest.warningEvent]]
*/
Warning = "warning"
}
/**
* Possible status of the test.
*/
enum Status {
/**
* Call to Twilio has initiated.
*/
Connecting = "connecting",
/**
* Call to Twilio has been established.
*/
Connected = "connected",
/**
* The connection to Twilio has been disconnected and the test call has completed.
*/
Completed = "completed",
/**
* The test has stopped and failed.
*/
Failed = "failed"
}
/**
* The WebRTC API's [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* dictionary which provides information related to an ICE candidate.
*/
type RTCIceCandidateStats = any;
/**
* Options that may be passed to {@link PreflightTest} constructor for internal testing.
* @internal
*/
interface ExtendedOptions extends Options {
/**
* The AudioContext instance to use
*/
audioContext?: AudioContext;
/**
* A string or array of strings representing the URI of the signaling
* gateway to connect to.
*/
chunderw?: string | string[];
/**
* Device class to use.
*/
deviceFactory?: typeof Device;
/**
* A string representing the URI of the insights gateway to connect to.
*/
eventgw?: string;
/**
* File input stream to use instead of reading from mic
*/
fileInputStream?: MediaStream;
/**
* The getRTCIceCandidateStatsReport to use for testing.
*/
getRTCIceCandidateStatsReport?: Function;
/**
* An RTCConfiguration to pass to the RTCPeerConnection constructor.
*/
rtcConfiguration?: RTCConfiguration;
}
/**
* A WebRTC stats report containing relevant information about selected and gathered ICE candidates
*/
interface RTCIceCandidateStatsReport {
/**
* 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;
}
/**
* Options passed to {@link PreflightTest} constructor.
*/
interface Options {
/**
* An ordered array of codec names that will be used during the test call,
* from most to least preferred.
* @default ['pcmu','opus']
*/
codecPreferences?: Call.Codec[];
/**
* Specifies which Twilio Data Center to use when initiating the test call.
* Please see this
* [page](https://www.twilio.com/docs/voice/client/edges)
* for the list of available edges.
* @default roaming
*/
edge?: string;
/**
* If set to `true`, the test call will ignore microphone input and will use a default audio file.
* If set to `false`, the test call will capture the audio from the microphone.
* Setting this to `true` is only supported on Chrome and will throw a fatal error on other browsers
* @default false
*/
fakeMicInput?: boolean;
/**
* An array of custom ICE servers to use to connect media. If you provide both STUN and TURN server configurations,
* the test will detect whether a TURN server is required to establish a connection.
*
* The following example demonstrates how to use [Twilio's Network Traversal Service](https://www.twilio.com/stun-turn)
* to generate STUN/TURN credentials and how to specify a specific [edge location](https://www.twilio.com/docs/global-infrastructure/edge-locations).
*
* ```ts
* import Client from 'twilio';
* import { Device } from '@twilio/voice-sdk';
*
* // 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 });
*
* let iceServers = token.iceServers;
*
* // By default, global will be used as the default edge location.
* // You can replace global with a specific edge name for each of the iceServer configuration.
* iceServers = iceServers.map(config => {
* let { url, urls, ...rest } = config;
* url = url.replace('global', 'ashburn');
* urls = urls.replace('global', 'ashburn');
*
* return { url, urls, ...rest };
* });
*
* // Use the TURN credentials using the iceServers parameter
* const preflightTest = Device.runPreflight(token, { iceServers });
*
* // Read from the report object to determine whether TURN is required to connect to media
* preflightTest.on('completed', (report) => {
* console.log(report.isTurnRequired);
* });
* ```
*
* @default null
*/
iceServers?: RTCIceServer[];
/**
* Log level to use in the Device.
* @default 'error'
*/
logLevel?: string;
/**
* Amount of time to wait for setting up signaling connection.
* @default 10000
*/
signalingTimeoutMs?: number;
}
/**
* Represents the WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected.
*/
interface RTCSelectedIceCandidatePairStats {
/**
* An [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* object which provides information related to the selected local ICE candidate.
*/
localCandidate: RTCIceCandidateStats;
/**
* An [RTCIceCandidateStats](https://developer.mozilla.org/en-US/docs/Web/API/RTCIceCandidateStats)
* object which provides information related to the selected remote ICE candidate.
*/
remoteCandidate: RTCIceCandidateStats;
}
/**
* Represents RTC related stats that are extracted from RTC samples.
*/
interface RTCStats {
/**
* Packets delay variation.
*/
jitter: Stats;
/**
* Mean opinion score, 1.0 through roughly 4.5.
*/
mos: Stats;
/**
* Round trip time, to the server back to the client.
*/
rtt: Stats;
}
/**
* Represents general stats for a specific metric.
*/
interface Stats {
/**
* The average value for this metric.
*/
average: number;
/**
* The maximum value for this metric.
*/
max: number;
/**
* The minimum value for this metric.
*/
min: number;
}
/**
* Represents the report generated from a {@link PreflightTest}.
*/
interface Report {
/**
* The quality of the call determined by different mos ranges.
*/
callQuality?: CallQuality;
/**
* CallSid generaged during the test.
*/
callSid: string | undefined;
/**
* The edge that the test call was connected to.
*/
edge?: string;
/**
* An array of WebRTC stats for the ICE candidates gathered when connecting to media.
*/
iceCandidateStats: RTCIceCandidateStats[];
/**
* Whether a TURN server is required to connect to media.
* This is dependent on the selected ICE candidates, and will be true if either is of type "relay",
* false if both are of another type, or undefined if there are no selected ICE candidates.
* See `PreflightTest.Options.iceServers` for more details.
*/
isTurnRequired?: boolean;
/**
* Network related time measurements.
*/
networkTiming: NetworkTiming;
/**
* WebRTC samples collected during the test.
*/
samples: RTCSample[];
/**
* The edge passed to `Device.runPreflight`.
*/
selectedEdge?: string;
/**
* A WebRTC stats for the ICE candidate pair used to connect to media, if candidates were selected.
*/
selectedIceCandidatePairStats?: RTCSelectedIceCandidatePairStats;
/**
* RTC related stats captured during the test.
*/
stats?: RTCStats;
/**
* Time measurements of test run time.
*/
testTiming: TimeMeasurement;
/**
* Calculated totals in RTC statistics samples.
*/
totals?: RTCSampleTotals;
/**
* List of warning names and warning data detected during this test.
*/
warnings: PreflightTest.Warning[];
}
/**
* A warning that can be raised by Preflight, and returned in the Report.warnings field.
*/
interface Warning {
/**
* Description of the Warning
*/
description: string;
/**
* Name of the Warning
*/
name: string;
/**
* If applicable, the RTCWarning that triggered this warning.
*/
rtcWarning?: RTCWarning;
}
}