Pre-call Test - Flutter
VideoSDK.runPreCallTest() checks the camera and the microphone, and then measures the network, before the user joins a room. VideoSDK.stopPreCallTest() stops a running test. This page lists the types that the test uses. For a full pre-call flow, see the Precall guide.
Run the test before you join a room, and only one test at a time. Creating a room does not stop a test that is still running, so stop it before you create and join the room.
runPreCallTest()
VideoSDK.runPreCallTest(options, {onStatsChange}) returns a Future<PreCallTestResult>.
- It completes with the
PreCallTestResultwhen the test ends, also when it is stopped. It fails with aPreCallTestExceptionwhen the test fails. onStatsChangereceives the latestPreCallNetworkQualitywhile the test measures the network.VideoSDK.stopPreCallTest()stops the running test and completes once it has ended. The test'sFuturethen completes withabortedset totrue. When the stop fails, it throws aPreCallTestException.
Example
try {
final PreCallTestResult result = await VideoSDK.runPreCallTest(
PreCallTestOptions(token: "<TOKEN>"),
onStatsChange: (PreCallNetworkQuality stats) {
print("Uplink quality so far: ${stats.uplink.quality}");
},
);
print("Downlink quality: ${result.networkQuality?.downlink.quality}");
} on PreCallTestException catch (error) {
print("Pre-call test failed: ${error.code} ${error.message}");
}
// To stop it early, for example when the user leaves the screen:
await VideoSDK.stopPreCallTest();
PreCallTestOptions
The options that you pass to runPreCallTest(). Only token is required.
- token:
String- The authentication token. - samplingDuration:
int?- How long to measure the network, in milliseconds, from10000to120000. Defaults to15000. - audioOnly:
bool- Skip the camera and test audio only. Defaults tofalse. - videoTrack:
CustomStreamTrack?- A camera track that you created withcreateCameraVideoTrack(). The test uses it as it is and does not stop it. - audioTrack:
CustomStreamTrack?- A microphone track that you created withcreateMicrophoneAudioTrack(). The test uses it as it is and does not stop it. - videoConfig:
PreCallVideoConfig?- How the test opens the camera when you pass novideoTrack. - audioConfig:
PreCallAudioConfig?- How the test opens the microphone when you pass noaudioTrack.
Pass videoTrack or videoConfig, not both, and audioTrack or audioConfig, not both. With audioOnly: true, pass no video option. Otherwise the test fails with ERROR_PRECALL_INVALID_CONFIG.
Example
final PreCallTestOptions options = PreCallTestOptions(
token: "<TOKEN>",
samplingDuration: 20000,
videoConfig: const PreCallVideoConfig(
encoderConfig: CustomCameraTrackConfig.h540p_w960p,
facingMode: FacingMode.FRONT,
),
audioConfig: const PreCallAudioConfig(
encoderConfig: CustomMicrophoneTrackConfig.SPEECH_STANDARD,
),
);
PreCallVideoConfig
How the test opens the camera. Every field is optional, and a field you leave out uses the default.
- cameraId:
String?- ThedeviceIdof a camera fromgetCameras(). - encoderConfig:
CustomCameraTrackConfig?- The resolution. Defaults toh720p_w1280p. Use one of the values listed in Custom Tracks. - facingMode:
FacingMode?- The front or back camera, when you pass nocameraId. Defaults toFacingMode.FRONT. - multiStream:
bool?- Send the video in several resolution layers. Defaults totrue. - bitrateMode:
BitrateMode?- Defaults toBitrateMode.BALANCED. - maxLayer:
EncodingLayer?- The highest number of layers to send,EncodingLayer.MAX_LAYER_2orEncodingLayer.MAX_LAYER_3, whenmultiStreamistrue.
PreCallAudioConfig
How the test opens the microphone. Every field is optional.
- microphoneId:
String?- ThedeviceIdof a microphone fromgetMics(). - encoderConfig:
CustomMicrophoneTrackConfig?- Defaults toSPEECH_STANDARD. - noiseConfig:
NoiseConfig?-noiseSuppression,echoCancellation,autoGainControlandhighPassFilter.
PreCallTestResult
What runPreCallTest() completes with.
- aborted:
bool-truewhen the test was stopped before it finished. - testDuration:
int- How long the test ran, in milliseconds. - camera:
PreCallMediaReport?- The camera check.nullfor an audio-only test, or when the test was stopped before the camera was checked. - microphone:
PreCallMediaReport?- The microphone check.nullwhen the test was stopped before the microphone was checked. - networkQuality:
PreCallNetworkQuality?- The network results.nullwhen the network part of the test did not run, for example because the test was stopped. - toJson():
Map<String, dynamic>- The whole result as a read-only map, for logging or for your server. It does not include the tracks.
PreCallMediaReport
The result of the camera or the microphone check.
- status:
bool-truewhen the device opened and captured media. - track:
CustomStreamTrack?- The track that was tested. If you passedvideoTrackoraudioTrack, it is that same track. If the test opened the device itself, it is a new track that stays open after the test and belongs to your app: pass it tocreateRoom()ascustomCameraTrackorcustomMicrophoneTrack, or call itsstop().nullwhen the device could not be opened. - captureResolution:
String?- The captured size, such as"1280x720". Camera only. - fps:
int?- The captured frames per second. Camera only. - codec:
String?- The codec the test sent the media with, such as"VP8"or"opus". Set only after the network part of the test succeeded. - error:
PreCallTestException?- Why the check failed, whenstatusisfalse.
PreCallNetworkQuality
The network results. onStatsChange of runPreCallTest() receives the latest values while the test runs, and networkQuality of the result holds the final ones.
- audioOnly:
bool-truewhen the test ran without video. - uplink:
PreCallDirectionQuality- What this device sends. - downlink:
PreCallDirectionQuality- What this device receives.
PreCallDirectionQuality
The results for one direction.
- quality:
int- The score, from1(bad) to5(excellent).0means it is not known yet. - factors:
List<String>- What lowered the score, such asrtt,packetLoss,jitter,bandwidthorfreeze. Empty when nothing did. - audio:
PreCallAudioQuality?- The audio values.nullwhen no audio was measured. - video:
PreCallVideoQuality?- The video values.nullwhen no video was measured.
PreCallAudioQuality
- quality:
int- The audio score, from1(bad) to5(excellent), or0when it is not known. - rtt:
int?- Round-trip time, in milliseconds. - bitrate:
int?- In bits per second. - packetLoss:
double?- Lost packets, in percent. - jitter:
int?- In milliseconds. - bytesSent:
int?- Uplink only. - bytesReceived:
int?- Downlink only.
PreCallVideoQuality
It has the fields of PreCallAudioQuality, for video, plus:
- fps:
int?- Frames per second. - resolution:
String?- The size, such as"1280x720". - qualityLimitationReason:
String?- Why the sent video was limited:none,bandwidth,cpuorother. Uplink only. - framesDropped:
int?- Downlink only. - freezeCount:
int?- Downlink only. - framesDroppedRatio:
double?- Downlink only. - totalFreezesDuration:
double?- How long the video was frozen in total. Downlink only.
PreCallTestException
The exception that runPreCallTest() fails with, and the error of a PreCallMediaReport whose check failed. VideoSDK.stopPreCallTest() throws it too.
- code:
String- The error code, such as"ERROR_PRECALL_INVALID_TOKEN". It is a string, not a number. - message:
String- What went wrong. - name:
String- Always"PreCallTestError".
Pre-call test errors lists the codes. When the test opens the devices itself and only one of them fails, the test still completes. That device's report has status set to false and an error with a code such as ERROR_CAMERA_IN_USE.
Example
try {
final PreCallTestResult result = await VideoSDK.runPreCallTest(
PreCallTestOptions(token: "<TOKEN>"),
);
final PreCallMediaReport? camera = result.camera;
if (camera != null && !camera.status) {
print("Camera check failed: ${camera.error?.code}");
}
} on PreCallTestException catch (error) {
print("Pre-call test failed: ${error.code} ${error.message}");
}
Got a Question? Ask us on discord

