Skip to content

ExoPlayer Quality Test

Once registered, you can create a Builder for the respective QualityTest which can also be launched in the onCreate method of your activity. In our example we will be using the ExoPlayerQualityTest builder. Have a look at the ExoplayerTestActivity in the demo app for more info.

Warning

Do not instantiate the builder before the registration is complete, as you will receive an exception. Make sure your application is checking the registration before starting the test.

For our ExoPlayerQualityTest, we will play a DASH stream with a known manifest URL. The playback duration is 30 seconds in the below example, and the maximum test duration is a timeout for the test in case of network problems. The analysis duration is a timeout for the actual analysis of the results on the remote server.

Starting the Test

Here is how you can start the test:

ExoPlayerQualityTest mQTest;

ExoPlayerQualityTest.Builder builder = new ExoPlayerQualityTest.Builder(
    this,
    Uri.parse("https://example.com/manifest.mpd")
)
.setMaxPlaybackDuration(30 * 1000)
.setMaxTestDuration(60 * 1000)
.setMaxAnalysisDuration(10 * 1000)
.setResultListener(this)
.setProgressInterval(1000);

try {
    mQTest = builder.build();
    mQTest.start();
} catch (Exception e) {
    Log.e(TAG, "Test start failed", e);
    // Handle exception
}

Tip

You can get other test URLs from the hls.js demo or the dash.js demo. All of these should work fine with the ExoPlayerQualityTest.

Receiving Test Results

To receive the outcomes of the test, your activity or class must implement the ExoPlayerQualityTestResultListener interface. This interface includes methods for handling successful results, errors, and state changes.

Test Success

When the test completes successfully, the onTestResult method is called:

@Override
public void onTestResult(@NonNull Map<String, Object> result) {
    Log.i(TAG, "Test result received: " + result);
    // Convert the result to a JSON string for display or storage
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    String resultJson = gson.toJson(result);
    // Process or display the resultJson
}

The results correspond to the measurement data, so please refer to that page for more information on the values.

Test Errors

If an error occurs during the test, the onTestError method is invoked:

@Override
public void onTestError(@NonNull QualityTestException error) {
    // Handle the error, e.g., display a message to the user
    Log.e(TAG, "Test error: " + error.getMessage(), error);
}

Test State Changes

You can monitor the lifecycle of the test by implementing the onTestStateChanged method from the ExoPlayerQualityTestResultListener interface:

@Override
public void onTestStateChanged(QualityTestState state) {
    Log.d(TAG, "Test state: " + state);
}

Performance Monitoring Datasource

We provide a special loader for ExoPlayer that monitors the performance of each segment request. This is useful for performance monitoring, connection troubleshooting, etc.

To use it, you must instantiate the ExoPlayer yourself (i.e., not use the ExoPlayerQualityTest's internal ExoPlayer instance). Before you instantiate the ExoPlayer itself, call:

import com.aveq.qoereporting.PerformanceMonitoringHttpDataSourceFactory;
import com.aveq.qoereporting.PerformanceMonitoringHttpDataSource.PerformanceListener;

// ...

DefaultHttpDataSource.Factory defaultHttpDataSourceFactory = new DefaultHttpDataSource.Factory();
HttpDataSource.Factory performanceMonitoringFactory =
        new PerformanceMonitoringHttpDataSourceFactory(defaultHttpDataSourceFactory, this);
MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(performanceMonitoringFactory);

ExoPlayer mPlayer = new ExoPlayer.Builder(mContext)
    .setMediaSourceFactory(mediaSourceFactory)
    .build();

Then pass that ExoPlayer instance to the ExoPlayerQualityTest builder:

ExoPlayerQualityTest.Builder builder = new ExoPlayerQualityTest.Builder(
    this,
    Uri.parse("https://example.com/manifest.mpd")
)
.setExternalPlayer(mPlayer);

Now make sure your activity implements the PerformanceMonitoringHttpDataSource.PerformanceListener interface:

/**
 * Called when performance metrics are available for a segment request.
 *
 * @param url              The URL of the segment.
 * @param bytesTransferred The number of bytes transferred.
 * @param totalTime        The total time taken to transfer the segment in seconds.
 * @param ttfb             The time to first byte in milliseconds.
 * @param throughput       The throughput in kilobits per second.
 */
@Override
public void onRequestPerformance(String url, long bytesTransferred, double totalTime, long ttfb, double throughput) {
    // Handle the performance data
}

You will receive onRequestPerformance calls for each segment request.

Instrumented Usage

The ExoPlayerQualityTest can be initiated via adb by passing intent extras to the demo ExoplayerTestActivity. This is useful for automated testing scenarios.

adb shell am start -n "com.aveq.qualitytestlibdemo/.ExoplayerTestActivity" \
  --ez autoRunTest true \
  --el maxPlaybackDuration 30000 \
  --el maxTestDuration 45000 \
  --ez displayPlayer true

Note that these intent parameters are directly passed to the ExoPlayer quality test; check the demo app source code for more info on how they are handled.

We provide a shell script to run the quality test using the above call, which extracts the test results directly from the Android log. See ./run_exoplayer_quality_test.sh for more info.