mirror of
https://github.com/samsonjs/media.git
synced 2026-04-03 10:55:48 +00:00
Extend EventTime with full current position info.
EventTime contains information about when an event happened and where it belongs to. Both places can be fully described using timeline, window index, media period id and position. Right now, only the information for where the event belongs to is fully contained in EventTime, whereas the time when the event happened only has the position, and none of the other information (timeline, window, period). This change adds the missing information, so that the EventTime can easily be used without having access to the Player. This also ensures Event metadata is self-contained and can be stored and reused later. issue:#7332 PiperOrigin-RevId: 311727004
This commit is contained in:
parent
78c850a885
commit
f3d331c9f7
6 changed files with 82 additions and 20 deletions
|
|
@ -88,6 +88,9 @@
|
|||
`CacheDataSink.Factory` and `CacheDataSource.Factory` respectively.
|
||||
* Enable the configuration of `SilenceSkippingAudioProcessor`
|
||||
([#6705](https://github.com/google/ExoPlayer/issues/6705)).
|
||||
* Extend `EventTime` with more details about the current player state for
|
||||
easier access
|
||||
([#7332](https://github.com/google/ExoPlayer/issues/7332)).
|
||||
* Video: Pass frame rate hint to `Surface.setFrameRate` on Android R devices.
|
||||
* Text:
|
||||
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
|
||||
|
|
|
|||
|
|
@ -659,12 +659,16 @@ public class AnalyticsCollector
|
|||
eventPositionMs =
|
||||
timeline.isEmpty() ? 0 : timeline.getWindow(windowIndex, window).getDefaultPositionMs();
|
||||
}
|
||||
@Nullable MediaPeriodInfo currentInfo = mediaPeriodQueueTracker.getCurrentPlayerMediaPeriod();
|
||||
return new EventTime(
|
||||
realtimeMs,
|
||||
timeline,
|
||||
windowIndex,
|
||||
mediaPeriodId,
|
||||
eventPositionMs,
|
||||
player.getCurrentTimeline(),
|
||||
player.getCurrentWindowIndex(),
|
||||
currentInfo == null ? null : currentInfo.mediaPeriodId,
|
||||
player.getCurrentPosition(),
|
||||
player.getTotalBufferedDuration());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public interface AnalyticsListener {
|
|||
*/
|
||||
public final long realtimeMs;
|
||||
|
||||
/** Timeline at the time of the event. */
|
||||
/** Most recent {@link Timeline} that contains the event position. */
|
||||
public final Timeline timeline;
|
||||
|
||||
/**
|
||||
|
|
@ -66,8 +66,8 @@ public interface AnalyticsListener {
|
|||
public final int windowIndex;
|
||||
|
||||
/**
|
||||
* Media period identifier for the media period this event belongs to, or {@code null} if the
|
||||
* event is not associated with a specific media period.
|
||||
* {@link MediaPeriodId Media period identifier} for the media period this event belongs to, or
|
||||
* {@code null} if the event is not associated with a specific media period.
|
||||
*/
|
||||
@Nullable public final MediaPeriodId mediaPeriodId;
|
||||
|
||||
|
|
@ -77,8 +77,27 @@ public interface AnalyticsListener {
|
|||
public final long eventPlaybackPositionMs;
|
||||
|
||||
/**
|
||||
* Position in the current timeline window ({@link Player#getCurrentWindowIndex()}) or the
|
||||
* currently playing ad at the time of the event, in milliseconds.
|
||||
* The current {@link Timeline} at the time of the event (equivalent to {@link
|
||||
* Player#getCurrentTimeline()}).
|
||||
*/
|
||||
public final Timeline currentTimeline;
|
||||
|
||||
/**
|
||||
* The current window index in {@link #currentTimeline} at the time of the event, or the
|
||||
* prospective window index if the timeline is not yet known and empty (equivalent to {@link
|
||||
* Player#getCurrentWindowIndex()}).
|
||||
*/
|
||||
public final int currentWindowIndex;
|
||||
|
||||
/**
|
||||
* {@link MediaPeriodId Media period identifier} for the currently playing media period at the
|
||||
* time of the event, or {@code null} if no current media period identifier is available.
|
||||
*/
|
||||
@Nullable public final MediaPeriodId currentMediaPeriodId;
|
||||
|
||||
/**
|
||||
* Position in the {@link #currentWindowIndex current timeline window} or the currently playing
|
||||
* ad at the time of the event, in milliseconds.
|
||||
*/
|
||||
public final long currentPlaybackPositionMs;
|
||||
|
||||
|
|
@ -91,19 +110,27 @@ public interface AnalyticsListener {
|
|||
/**
|
||||
* @param realtimeMs Elapsed real-time as returned by {@code SystemClock.elapsedRealtime()} at
|
||||
* the time of the event, in milliseconds.
|
||||
* @param timeline Timeline at the time of the event.
|
||||
* @param windowIndex Window index in the {@link #timeline} this event belongs to, or the
|
||||
* @param timeline Most recent {@link Timeline} that contains the event position.
|
||||
* @param windowIndex Window index in the {@code timeline} this event belongs to, or the
|
||||
* prospective window index if the timeline is not yet known and empty.
|
||||
* @param mediaPeriodId Media period identifier for the media period this event belongs to, or
|
||||
* {@code null} if the event is not associated with a specific media period.
|
||||
* @param mediaPeriodId {@link MediaPeriodId Media period identifier} for the media period this
|
||||
* event belongs to, or {@code null} if the event is not associated with a specific media
|
||||
* period.
|
||||
* @param eventPlaybackPositionMs Position in the window or ad this event belongs to at the time
|
||||
* of the event, in milliseconds.
|
||||
* @param currentPlaybackPositionMs Position in the current timeline window ({@link
|
||||
* Player#getCurrentWindowIndex()}) or the currently playing ad at the time of the event, in
|
||||
* milliseconds.
|
||||
* @param totalBufferedDurationMs Total buffered duration from {@link
|
||||
* #currentPlaybackPositionMs} at the time of the event, in milliseconds. This includes
|
||||
* pre-buffered data for subsequent ads and windows.
|
||||
* @param currentTimeline The current {@link Timeline} at the time of the event (equivalent to
|
||||
* {@link Player#getCurrentTimeline()}).
|
||||
* @param currentWindowIndex The current window index in {@code currentTimeline} at the time of
|
||||
* the event, or the prospective window index if the timeline is not yet known and empty
|
||||
* (equivalent to {@link Player#getCurrentWindowIndex()}).
|
||||
* @param currentMediaPeriodId {@link MediaPeriodId Media period identifier} for the currently
|
||||
* playing media period at the time of the event, or {@code null} if no current media period
|
||||
* identifier is available.
|
||||
* @param currentPlaybackPositionMs Position in the current timeline window or the currently
|
||||
* playing ad at the time of the event, in milliseconds.
|
||||
* @param totalBufferedDurationMs Total buffered duration from {@code currentPlaybackPositionMs}
|
||||
* at the time of the event, in milliseconds. This includes pre-buffered data for subsequent
|
||||
* ads and windows.
|
||||
*/
|
||||
public EventTime(
|
||||
long realtimeMs,
|
||||
|
|
@ -111,6 +138,9 @@ public interface AnalyticsListener {
|
|||
int windowIndex,
|
||||
@Nullable MediaPeriodId mediaPeriodId,
|
||||
long eventPlaybackPositionMs,
|
||||
Timeline currentTimeline,
|
||||
int currentWindowIndex,
|
||||
@Nullable MediaPeriodId currentMediaPeriodId,
|
||||
long currentPlaybackPositionMs,
|
||||
long totalBufferedDurationMs) {
|
||||
this.realtimeMs = realtimeMs;
|
||||
|
|
@ -118,6 +148,9 @@ public interface AnalyticsListener {
|
|||
this.windowIndex = windowIndex;
|
||||
this.mediaPeriodId = mediaPeriodId;
|
||||
this.eventPlaybackPositionMs = eventPlaybackPositionMs;
|
||||
this.currentTimeline = currentTimeline;
|
||||
this.currentWindowIndex = currentWindowIndex;
|
||||
this.currentMediaPeriodId = currentMediaPeriodId;
|
||||
this.currentPlaybackPositionMs = currentPlaybackPositionMs;
|
||||
this.totalBufferedDurationMs = totalBufferedDurationMs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ public final class PlaybackStatsListener
|
|||
/* windowIndex= */ 0,
|
||||
/* mediaPeriodId= */ null,
|
||||
/* eventPlaybackPositionMs= */ 0,
|
||||
Timeline.EMPTY,
|
||||
/* currentWindowIndex= */ 0,
|
||||
/* currentMediaPeriodId= */ null,
|
||||
/* currentPlaybackPositionMs= */ 0,
|
||||
/* totalBufferedDurationMs= */ 0);
|
||||
sessionManager.finishAllSessions(dummyEventTime);
|
||||
|
|
@ -210,6 +213,9 @@ public final class PlaybackStatsListener
|
|||
eventTime.mediaPeriodId.windowSequenceNumber,
|
||||
eventTime.mediaPeriodId.adGroupIndex),
|
||||
/* eventPlaybackPositionMs= */ C.usToMs(contentWindowPositionUs),
|
||||
eventTime.timeline,
|
||||
eventTime.currentWindowIndex,
|
||||
eventTime.currentMediaPeriodId,
|
||||
eventTime.currentPlaybackPositionMs,
|
||||
eventTime.totalBufferedDurationMs);
|
||||
Assertions.checkNotNull(playbackStatsTrackers.get(contentSession))
|
||||
|
|
|
|||
|
|
@ -1092,6 +1092,9 @@ public final class DefaultPlaybackSessionManagerTest {
|
|||
windowIndex,
|
||||
mediaPeriodId,
|
||||
/* eventPlaybackPositionMs= */ 0,
|
||||
timeline,
|
||||
windowIndex,
|
||||
mediaPeriodId,
|
||||
/* currentPlaybackPositionMs= */ 0,
|
||||
/* totalBufferedDurationMs= */ 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,20 +44,27 @@ public final class PlaybackStatsListenerTest {
|
|||
/* windowIndex= */ 0,
|
||||
/* mediaPeriodId= */ null,
|
||||
/* eventPlaybackPositionMs= */ 0,
|
||||
/* currentTimeline= */ Timeline.EMPTY,
|
||||
/* currentWindowIndex= */ 0,
|
||||
/* currentMediaPeriodId= */ null,
|
||||
/* currentPlaybackPositionMs= */ 0,
|
||||
/* totalBufferedDurationMs= */ 0);
|
||||
private static final Timeline TEST_TIMELINE = new FakeTimeline(/* windowCount= */ 1);
|
||||
private static final MediaSource.MediaPeriodId TEST_MEDIA_PERIOD_ID =
|
||||
new MediaSource.MediaPeriodId(
|
||||
TEST_TIMELINE.getPeriod(/* periodIndex= */ 0, new Timeline.Period(), /* setIds= */ true)
|
||||
.uid,
|
||||
/* windowSequenceNumber= */ 42);
|
||||
private static final AnalyticsListener.EventTime TEST_EVENT_TIME =
|
||||
new AnalyticsListener.EventTime(
|
||||
/* realtimeMs= */ 500,
|
||||
TEST_TIMELINE,
|
||||
/* windowIndex= */ 0,
|
||||
new MediaSource.MediaPeriodId(
|
||||
TEST_TIMELINE.getPeriod(
|
||||
/* periodIndex= */ 0, new Timeline.Period(), /* setIds= */ true)
|
||||
.uid,
|
||||
/* windowSequenceNumber= */ 42),
|
||||
TEST_MEDIA_PERIOD_ID,
|
||||
/* eventPlaybackPositionMs= */ 123,
|
||||
TEST_TIMELINE,
|
||||
/* currentWindowIndex= */ 0,
|
||||
TEST_MEDIA_PERIOD_ID,
|
||||
/* currentPlaybackPositionMs= */ 123,
|
||||
/* totalBufferedDurationMs= */ 456);
|
||||
|
||||
|
|
@ -151,6 +158,9 @@ public final class PlaybackStatsListenerTest {
|
|||
/* windowIndex= */ 0,
|
||||
/* mediaPeriodId= */ null,
|
||||
/* eventPlaybackPositionMs= */ 0,
|
||||
Timeline.EMPTY,
|
||||
/* currentWindowIndex= */ 0,
|
||||
/* currentMediaPeriodId= */ null,
|
||||
/* currentPlaybackPositionMs= */ 0,
|
||||
/* totalBufferedDurationMs= */ 0);
|
||||
AnalyticsListener.EventTime eventTimeWindow1 =
|
||||
|
|
@ -160,6 +170,9 @@ public final class PlaybackStatsListenerTest {
|
|||
/* windowIndex= */ 1,
|
||||
/* mediaPeriodId= */ null,
|
||||
/* eventPlaybackPositionMs= */ 0,
|
||||
Timeline.EMPTY,
|
||||
/* currentWindowIndex= */ 1,
|
||||
/* currentMediaPeriodId= */ null,
|
||||
/* currentPlaybackPositionMs= */ 0,
|
||||
/* totalBufferedDurationMs= */ 0);
|
||||
PlaybackStatsListener.Callback callback = mock(PlaybackStatsListener.Callback.class);
|
||||
|
|
|
|||
Loading…
Reference in a new issue