Player Debugging
Player Debugging¶
This chapter covers some details related to the DebugPlugin
,
a module that attaches to the PlayerController
and logs relevant information that helps troubleshoot stream issues.
Adding to the project¶
The plugin is distributed with the SDK and you can add it as a dependency in your gradle file:
dependencies {
...
compile 'com.castlabs.player:debug-plugin:4.2.0'
...
}
Once added you can register it with the SDK. The DebugPlugin
must be created with its builder.
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PlayerSDK.register(new DebugPlugin.Builder().logAll(true).get());
PlayerSDK.init(getApplicationContext());
}
}
Note that here we are enabling all the debugging options. You can also pick whatever debug options
you desire with the same Builder
.
Please refer to the Javadocs for more info.
Graphics¶
This plugin also provides debugging views that will graph player metrics. There’s a default debugging
overlay which can be enabled in the DebugPlugin
with the debugOverlay
method.
You can also optionally build your own layout and choose what information to display. This is explained in the following section.
Charts¶
The DebugPlugin
provides two charts:
PlayerStateChart
. Shows a horizontal player state graph.
PlayerMetricChart
. Shows a line graph displaying one or more Metrics.
These two Graphs can be used as common Android Views
in an xml file.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.castlabs.sdk.debug.view.PlayerStateChart
android:id="@+id/stateChart"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<com.castlabs.sdk.debug.view.PlayerMetricChart
android:layout_below="@id/stateChart"
android:id="@+id/metricChart"
android:layout_width="match_parent"
android:layout_height="300dp"/>
</RelativeLayout>
Then, the charts must be configured and provided with a PlayerController
.
// State plot
stateChart = chartsView.findViewById(R.id.stateChart);
// Metric plot, will show bandwidth estimation and player buffer
metricChart = chartsView.findViewById(R.id.metricChart);
metricChart.enableMetrics(PlayerMetricChart.METRIC_ABR_BANDWIDTH_ESTIMATION
| PlayerMetricChart.METRIC_BUFFER_AHEAD);
// Bind to PlayerController
stateChart.setPlayerController(playerController);
metricChart.setPlayerController(playerController);
When the host view is not visible anymore, you should unbind the Charts from the PlayerController
stateChart.unsetPlayerController();
metricChart.unsetPlayerController();
PlayerMetricChart and Metrics¶
PlayerMetricChart
is a powerful class that can plot the outputs of any Metric
.
A Metric
provides the required underlying infrastructure to interact with the PlayerMetricChart
and the necessary data to it. You can create additional Metrics by extending this class.
In order to enable a set of desired metrics in the PlayerMetricChart
you can use the
enableMetrics
passing
one or more of the PlayerMetricChart.METRIC_*
constants.
// Metric plot, will show bandwidth estimation and player buffer
metricChart.enableMetrics(PlayerMetricChart.METRIC_ABR_BANDWIDTH_ESTIMATION
| PlayerMetricChart.METRIC_BUFFER_AHEAD);
If you want more control over how such Metric``s are displayed, you can create them yourself and
add them to the ``PlayerMetricChart
.
metricChart.addMetric(new BandwidthMetric(Color.BLUE, YAxis.AxisDependency.LEFT));
metricChart.addMetric(new PlayingQualityMetric(Color.BLUE, YAxis.AxisDependency.LEFT));
metricChart.addMetric(new ChunkDownloadTimeMetric(Color.BLUE, YAxis.AxisDependency.RIGHT, ChunkDownloadTimeMetric.MODE_VIDEO));
You can add any number of Metric
to the chart.
Metric creation¶
You can also create your own Metric
for a PlayerMetricChart
to display.
To do this, you should extend the Metric
class and
override its abstract methods.
In addition to the abstract methods, you have access to the following:
addTimedDataPoint(float)
. Main data input. Use this method to add a data point to this metric.
dataSet
. You can use this protected property to modify the underlying dataSet, right after calling thesuper
constructor.Configuration overridable methods,
replicateLastValue()
,keepLastDroppedValue()
andextendToRightEdge()
.
Please refer to the appropriate Javadocs to get more details about Metric
creation.
AV Sync¶
Plugin can measure AV sync values and calculate streaming mean and standard deviation values of it.
Consider audio component having aPTS
that should be rendered at System time aSysTime
and video component having vPTS
and vSysTime
.
Assume AV components are encoded correctly i.e. when aPTS
and vPTS
have the same value then rendering at the same time does not
produce any UX AV sync issues. In reality, aSysTime
and vSysTime
are always different, even if scheduled to be the same. The delta is considered
to be AV sync value and is usually within the duration of 1-2 video frames.
Plugin measures AV sync per each video frame and calculates scheduled
and actual
(released) values. Scheduled means the calculated or desired
render time and actual is when the video and audio frames are actually rendered. The following AV sync values are logged:
Calculated
value per video frame
Min
andmax
valuesStreaming (accumulated)
mean
andStreaming (accumulated)
standard deviation
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
long logAVSyncThresholdUs = 1000000L; // log AVsync values exceeding 1sec, per video frame
long logMeanAndDeviationPeriodUs = 1000000L; // log min, max, mean and deviation every 1sec
PlayerSDK.register(new DebugPlugin.Builder()
.logVideoFrameMetadata(true, logAVSyncThresholdUs, logMeanAndDeviationPeriodUs)
.get()
);
PlayerSDK.init(getApplicationContext());
}
}
Generic Logging in Builds¶
The Log level of the SDK can be configured using the following API in the PlayerSDK to one of the following values,
android.util.Log#VERBOSE android.util.Log#DEBUG android.util.Log#INFO android.util.Log#WARN android.util.Log#ERROR android.util.Log#ASSERT
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
PlayerSDK.setLogLevel(sdkLogLevel)
}
}
Known Compatibility Issues¶
When using the OKHTTPClient logger, the configuration HttpLoggingInterceptor.Level.BODY <https://square.github.io/okhttp/3.x/logging-interceptor/okhttp3/logging/HttpLoggingInterceptor.Level.html> interferes with the Bandwidth estimation algorithm of the SDK thereby causing rendition switches to malfunction and therefore must be avoided.
Third party acknowledgement¶
The DebugPlugin
uses and distributes a copy of the MPAndroidChart
library which is under the Apache License 2.0.