Stream Probe introduces Time To First Byte (TTFB) measurement for media segments in this update. Developers can now see first-byte latency alongside throughput and size directly in the debug overlay, without writing any custom instrumentation.
TL;DR
Version 0.5.0 adds a TimingDataSourceFactory that wraps your existing DataSource.Factory and measures how long each segment takes to reach the first byte. The result shows up in the Segments overlay and gets folded into SegmentMetric via a thread-safe NetworkTimingRegistry.
What's New
- TimingDataSourceFactory: wraps the host
DataSource.Factoryand times theopen()call to capture TTFB per segment - NetworkTimingRegistry: thread-safe handoff layer that bridges I/O thread timing data to the playback thread without race conditions
wrapDataSourceFactory()in the public API: one call inStreamProbesetup wires up the timing pipeline- Segments overlay update: TTFB now renders alongside segment size and throughput in the debug UI
- SDK bumped to 0.5.0
How to Use
Pass your DataSource.Factory through the new wrapper when setting up Stream Probe:
val streamProbe = StreamProbe.Builder(context)
.dataSourceFactory(streamProbe.wrapDataSourceFactory(yourDataSourceFactory))
.build()
Once configured, the Segments overlay will show TTFB automatically for each loaded segment.
FAQ
What exactly does TTFB measure here?
TTFB is the duration from when ExoPlayer calls open() on a data source to when the first byte is ready. It reflects real network latency for each individual segment, not just overall buffering time.
Does this require changes to my existing DataSource.Factory?
No. wrapDataSourceFactory() wraps your existing factory without modifying it. Your factory keeps working exactly as before.
Why is a separate NetworkTimingRegistry needed?
ExoPlayer's I/O operations run on a background thread, but the overlay updates on the playback thread. The registry handles the cross-thread handoff safely so timing data isn't lost or corrupted.
Will this add overhead to playback?
The timing measurement is a single timestamp diff around the open() call. The overhead is negligible and does not affect segment loading performance.