mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Ensure network transfers are associated with the right session
We currently don't check which session is causing a network transfer (it could be a preloaded item in a playlist). To clearly associate network transfer data with sessions, we need to keep track of transferred bytes and transfer time per session. PiperOrigin-RevId: 422867845
This commit is contained in:
parent
081700f72b
commit
301fcd649a
@ -75,6 +75,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||||
@ -113,6 +114,8 @@ public final class MediaMetricsListener
|
|||||||
private final long startTimeMs;
|
private final long startTimeMs;
|
||||||
private final Timeline.Window window;
|
private final Timeline.Window window;
|
||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
|
private final HashMap<String, Long> bandwidthTimeMs;
|
||||||
|
private final HashMap<String, Long> bandwidthBytes;
|
||||||
|
|
||||||
@Nullable private String activeSessionId;
|
@Nullable private String activeSessionId;
|
||||||
@Nullable private PlaybackMetrics.Builder metricsBuilder;
|
@Nullable private PlaybackMetrics.Builder metricsBuilder;
|
||||||
@ -131,8 +134,6 @@ public final class MediaMetricsListener
|
|||||||
private boolean hasFatalError;
|
private boolean hasFatalError;
|
||||||
private int droppedFrames;
|
private int droppedFrames;
|
||||||
private int playedFrames;
|
private int playedFrames;
|
||||||
private long bandwidthTimeMs;
|
|
||||||
private long bandwidthBytes;
|
|
||||||
private int audioUnderruns;
|
private int audioUnderruns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,6 +147,8 @@ public final class MediaMetricsListener
|
|||||||
this.playbackSession = playbackSession;
|
this.playbackSession = playbackSession;
|
||||||
window = new Timeline.Window();
|
window = new Timeline.Window();
|
||||||
period = new Timeline.Period();
|
period = new Timeline.Period();
|
||||||
|
bandwidthBytes = new HashMap<>();
|
||||||
|
bandwidthTimeMs = new HashMap<>();
|
||||||
startTimeMs = SystemClock.elapsedRealtime();
|
startTimeMs = SystemClock.elapsedRealtime();
|
||||||
currentPlaybackState = PlaybackStateEvent.STATE_NOT_STARTED;
|
currentPlaybackState = PlaybackStateEvent.STATE_NOT_STARTED;
|
||||||
currentNetworkType = NetworkEvent.NETWORK_TYPE_UNKNOWN;
|
currentNetworkType = NetworkEvent.NETWORK_TYPE_UNKNOWN;
|
||||||
@ -188,8 +191,11 @@ public final class MediaMetricsListener
|
|||||||
if ((eventTime.mediaPeriodId != null && eventTime.mediaPeriodId.isAd())
|
if ((eventTime.mediaPeriodId != null && eventTime.mediaPeriodId.isAd())
|
||||||
|| !sessionId.equals(activeSessionId)) {
|
|| !sessionId.equals(activeSessionId)) {
|
||||||
// Ignore ad sessions and other sessions that are finished before becoming active.
|
// Ignore ad sessions and other sessions that are finished before becoming active.
|
||||||
|
} else {
|
||||||
|
finishCurrentSession();
|
||||||
}
|
}
|
||||||
finishCurrentSession();
|
bandwidthTimeMs.remove(sessionId);
|
||||||
|
bandwidthBytes.remove(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnalyticsListener implementation.
|
// AnalyticsListener implementation.
|
||||||
@ -216,8 +222,17 @@ public final class MediaMetricsListener
|
|||||||
@Override
|
@Override
|
||||||
public void onBandwidthEstimate(
|
public void onBandwidthEstimate(
|
||||||
EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) {
|
EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) {
|
||||||
bandwidthTimeMs += totalLoadTimeMs;
|
if (eventTime.mediaPeriodId != null) {
|
||||||
bandwidthBytes += totalBytesLoaded;
|
String sessionId =
|
||||||
|
sessionManager.getSessionForMediaPeriodId(
|
||||||
|
eventTime.timeline, checkNotNull(eventTime.mediaPeriodId));
|
||||||
|
@Nullable Long prevBandwidthBytes = bandwidthBytes.get(sessionId);
|
||||||
|
@Nullable Long prevBandwidthTimeMs = bandwidthTimeMs.get(sessionId);
|
||||||
|
bandwidthBytes.put(
|
||||||
|
sessionId, (prevBandwidthBytes == null ? 0 : prevBandwidthBytes) + totalBytesLoaded);
|
||||||
|
bandwidthTimeMs.put(
|
||||||
|
sessionId, (prevBandwidthTimeMs == null ? 0 : prevBandwidthTimeMs) + totalLoadTimeMs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -581,12 +596,14 @@ public final class MediaMetricsListener
|
|||||||
metricsBuilder.setAudioUnderrunCount(audioUnderruns);
|
metricsBuilder.setAudioUnderrunCount(audioUnderruns);
|
||||||
metricsBuilder.setVideoFramesDropped(droppedFrames);
|
metricsBuilder.setVideoFramesDropped(droppedFrames);
|
||||||
metricsBuilder.setVideoFramesPlayed(playedFrames);
|
metricsBuilder.setVideoFramesPlayed(playedFrames);
|
||||||
metricsBuilder.setNetworkTransferDurationMillis(bandwidthTimeMs);
|
@Nullable Long networkTimeMs = bandwidthTimeMs.get(activeSessionId);
|
||||||
|
metricsBuilder.setNetworkTransferDurationMillis(networkTimeMs == null ? 0 : networkTimeMs);
|
||||||
// TODO(b/181121847): Report localBytesRead. This requires additional callbacks or plumbing.
|
// TODO(b/181121847): Report localBytesRead. This requires additional callbacks or plumbing.
|
||||||
metricsBuilder.setNetworkBytesRead(bandwidthBytes);
|
@Nullable Long networkBytes = bandwidthBytes.get(activeSessionId);
|
||||||
|
metricsBuilder.setNetworkBytesRead(networkBytes == null ? 0 : networkBytes);
|
||||||
// TODO(b/181121847): Detect stream sources mixed and local depending on localBytesRead.
|
// TODO(b/181121847): Detect stream sources mixed and local depending on localBytesRead.
|
||||||
metricsBuilder.setStreamSource(
|
metricsBuilder.setStreamSource(
|
||||||
bandwidthBytes > 0
|
networkBytes != null && networkBytes > 0
|
||||||
? PlaybackMetrics.STREAM_SOURCE_NETWORK
|
? PlaybackMetrics.STREAM_SOURCE_NETWORK
|
||||||
: PlaybackMetrics.STREAM_SOURCE_UNKNOWN);
|
: PlaybackMetrics.STREAM_SOURCE_UNKNOWN);
|
||||||
playbackSession.reportPlaybackMetrics(metricsBuilder.build());
|
playbackSession.reportPlaybackMetrics(metricsBuilder.build());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user