///
import { EventEmitter } from 'events';
import { DiagnosticError } from './errors';
import { AudioElement, SubsetRequired, TimeMeasurement } from './types';
export declare interface AudioOutputTest {
/**
* This event is emitted when the test ends.
* @param event [[AudioOutputTest.Events.End]]
* @param report A summary of the test.
* @private
*/
emit(event: AudioOutputTest.Events.End, report: AudioOutputTest.Report): boolean;
/**
* This event is emitted when the test encounters an error, fatal or not.
* @param event [[AudioOutputTest.Events.Error]]
* @param error An error that was encountered during the run time of the test.
* @private
*/
emit(event: AudioOutputTest.Events.Error, error: DiagnosticError): boolean;
/**
* This event is emitted by the test after succesfully starting, and emits
* the volume of the audio source every [[AudioOutputTest.Options.volumeEventIntervalMs]]
* milliseconds.
* @param event [[AudioOutputTest.Events.Volume]]
* @param value The volume of the audio source.
* @private
*/
emit(event: AudioOutputTest.Events.Volume, value: number): boolean;
/**
* Raised when the test ends. The stop condition depends on if the option
* to loop was set to `true` or `false`. If `false`, then the test ends either
* when the audio file is finished playing, or when a time has elapsed
* greater than [[AudioOutputTest.Options.duration]].
* @event
* @param event [[AudioOutputTest.Events.End]]
* @param listener A listener function that expects the following parameters
* when the event is raised:
* - A [[AudioOutputTest.Report]] that summarizes the run time of the test.
* @returns This [[AudioOutputTest]] instance.
*/
on(event: AudioOutputTest.Events.End, listener: (report: AudioOutputTest.Report) => any): this;
/**
* Raised when the test has run into an error, fatal or not.
* @event
* @param event [[AudioOutputTest.Events.Error]]
* @param listener A listener function that expects the following parameters
* when the event is raised:
* - The [[DiagnosticError]].
* @returns This [[AudioOutputTest]] instance.
*/
on(event: AudioOutputTest.Events.Error, listener: (error: DiagnosticError) => any): this;
/**
* Raised every [[AudioOutputTest.Options.volumeEventIntervalMs]] after the test
* starts successfully. Will have a `number` parameter representing the
* current volume of the audio file.
* @event
* @param event [[AudioOutputTest.Events.Volume]]
* @param listener A listener function that expects the following parameters
* when the event is raised:
* - A number representing the volume of the audio source.
* @returns This [[AudioOutputTest]] instance.
*/
on(event: AudioOutputTest.Events.Volume, listener: (value: number) => any): this;
}
/**
* [[AudioOutputTest]] class that parses options and starts an audio output device
* test.
*
* Please see [[testAudioOutputDevice]] for details and recommended practices.
*/
export declare class AudioOutputTest extends EventEmitter {
/**
* The name of the test.
*/
static readonly testName: string;
/**
* Default options for the [[AudioOutputTest]]. Overwritten by any option passed
* during the construction of the test.
*/
private static defaultOptions;
/**
* Holds `AudioElement`s that are attached to the DOM to load and play audio.
*/
private _audio;
/**
* An `AudioContext` that is used to process the audio source.
*/
private _audioContext;
/**
* The default media devices when starting the test.
*/
private _defaultDevices;
/**
* A timestamp of when the test ends.
*/
private _endTime;
/**
* An array of errors encountered by the test during its run time.
*/
private readonly _errors;
/**
* Options passed to and set in the constructor to be used during the run
* time of the test.
*/
private _options;
/**
* A timestamp of when the test starts. This is set in the constructor and not
* when the test succesfully starts.
*/
private _startTime;
/**
* Volume values generated by the test over its run time.
*/
private readonly _values;
/**
* Timeout created by `setTimeout`, used to loop the volume logic.
*/
private _volumeTimeout;
/**
* Sets up several things for the [[AudioOutputTest]] to run later in the
* `_startTest` function.
* @param options Optional settings to pass to the test.
*/
constructor(options?: AudioOutputTest.Options);
/**
* Stops the test.
*/
stop(): void;
/**
* Cleanup the test.
*/
private _cleanup;
/**
* Error event handler. Adds the error to the internal list of errors that is
* forwarded in the report.
* @param error
*/
private _onError;
/**
* Volume event handler, adds the value to the list `_values` and emits it
* under the event `volume`.
* @param volume
*/
private _onVolume;
/**
* Warning event handler.
* @param warning
*/
private _onWarning;
/**
* Entry point of the test, called after setup in the constructor.
* Emits the volume levels of the audio.
*
* @event [[AudioOutputTest.Events.Volume]]
*/
private _startTest;
}
export declare namespace AudioOutputTest {
/**
* Events that the [[AudioOutputTest]] will emit as it runs.
* Please see [[AudioOutputTest.on]] for how to listen to these
* events.
*/
enum Events {
End = "end",
Error = "error",
Volume = "volume"
}
/**
* Options passed to [[AudioOutputTest]] constructor.
*/
interface Options {
/**
* An `AudioContext` to be used by the test.
* @private
*/
audioContextFactory?: typeof window.AudioContext;
/**
* A constuctor that is used to create an [[AudioElement]], useful for
* mocks.
* @private
*/
audioElementFactory?: new (...args: any[]) => AudioElement;
/**
* Whether or not to log debug statements to the console.
* @private
*/
debug?: boolean;
/**
* The `deviceId` of the audio device to attempt to play audio out of.
* This option is directly passed to [HTMLMediaElement.setSinkId](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId).
*/
deviceId?: string;
/**
* Whether or not to loop the audio.
* See [[AudioOutputTest]] for details on the behavior of "timing out".
* @default true
*/
doLoop?: boolean;
/**
* Duration in milliseconds to run the test for. If this amount of time elapses, the test
* is considered "timed out".
* See [[AudioOutputTest]] for details on the behavior of "timing out".
* @default Infinity
*/
duration?: number;
/**
* Used to mock the call to `enumerateDevices`.
* @private
*/
enumerateDevices?: typeof navigator.mediaDevices.enumerateDevices;
/**
* The URI of the audio file to use for the test.
*/
testURI?: string;
/**
* The interval between emissions of volume events in milliseconds.
* @default 100
*/
volumeEventIntervalMs?: number;
}
/**
* Represents the report generated from an [[AudioOutputTest]].
*/
interface Report {
/**
* The `deviceId` of the audio device used to play audio out of.
*/
deviceId: string | undefined;
/**
* Any errors that occurred during the run-time of the [[AudioOutputTest]].
*/
errors: DiagnosticError[];
/**
* Name of the test, set to [[AudioOutputTest.testName]].
*/
testName: typeof AudioOutputTest.testName;
/**
* Time measurements of test run time.
*/
testTiming: TimeMeasurement;
/**
* The URI of the audio file used during the test.
*/
testURI?: string;
/**
* The volume values emitted by the test during its run-time.
*/
values: number[];
}
/**
* Option typing after initialization, so we can have type guarantees.
* @private
*/
type InternalOptions = SubsetRequired;
}
/**
* [[AudioOutputTest]] tests audio output capabilities. It serves to help diagnose
* potential audio device issues that would prevent a user from being able to
* hear audio.
*
* ---
*
* The [[AudioOutputTest]] class is an `EventEmitter` (please see [[AudioOutputTest.on]] for
* events and their details) and helps to diagnose issues by playing a sound clip
* (by default the sound clip is the ringing tone from the `twilio-client.js`
* SDK) and emitting volume events of the sound clip as it plays.
* ```ts
* import { AudioOutputTest, testAudioOutputDevice } from '@twilio/rtc-diagnostics';
* const options: AudioOutputTest.Options = { ... };
* // `options` may be left `undefined` to use default option values
* const audioOutputTest: AudioOutputTest = testAudioOutputDevice(options);
* ```
* The application can use the volume events to show in its UI that audio is
* playing and that the end-user should be hearing something.
* ```ts
* audioOutputTest.on(AudioOutputTest.Events.Volume, (volume: number) => {
* ui.updateVolume(volume); // Update your UI with the volume value here.
* });
* ```
*
* The application should ask the end-user to confirm that the sound being played
* can be heard. The application should call [[AudioOutputTest.stop]] with `true` if
* the end-user hears the sound, and `false` if not.
* ```ts
* // If the user was able to hear the audio, the UI should indicate they should
* // click this button...
* const passButton = ...;
* passButton.on('click', () => {
* audioOutputTest.stop();
* // display a confirmation dialog to the user
* });
*
* // ...conversely, if they were not able to hear the audio, they should click
* // this one.
* const failButton = ...;
* failButton.on('click', () => {
* audioOutputTest.stop();
* // display a warning to the user
* });
* ```
* Caling [[AudioOutputTest.stop]] will immediately end the test.
*
* ---
*
* The [[AudioOutputTest]] object will always emit a [[AudioOutputTest.Report]] with
* the [[AudioOutputTest.Events.End]] event, regardless of the occurence of errors
* during the runtime of the test.
*
* Fatal errors will immediately end the test and emit a report such that the
* value of [[AudioOutputTest.Report.errors]] will contain the fatal error.
*
* Non-fatal errors will not end the test, but will be included in the value of
* [[AudioOutputTest.Report.errors]] upon completion of the test.
*
* If the data at `testURI` is unable to be loaded, meaning the error event is
* raised on the audio element, a fatal error has occurred.
*
* If `doLoop` is set to `false`, then the test will run for either the option
* `duration`, or the full duration of the audio file, which ever is shorter.
* If `doLoop` is set to `true`, it will only run as long as the `duration`
* option.
*
* ---
*
* The function [[testAudioOutputDevice]] serves as factory function that accepts
* [[AudioOutputTest.Options]] as its only parameter and will instantiate an
* [[AudioOutputTest]] object with those options.
* ```ts
* import { AudioOutputTest, testAudioOutputDevice } from '@twilio/rtc-diagnostics';
* const options: AudioOutputTest.Options = { ... };
* const audioOutputTest: AudioOutputTest = testAudioOutputDevice(options);
* ```
* @param options Options to pass to the [[AudioOutputTest]] constructor.
*/
export declare function testAudioOutputDevice(options?: AudioOutputTest.Options): AudioOutputTest;