Commit 06bd3a65 by tonihei Committed by Andrew Lewis

Don't inform of static metadata changes if they are all empty.

The current code creates placeholder metadata elements if there is no
static metadata. This causes onStaticMetadataChanged callbacks even
if there is no metadata.

Instead, we can keep the empty list as the static metadata is already
documented to be an empty list if the metadata is unavailable.

#exofixit

PiperOrigin-RevId: 344071639
parent 58e01671
...@@ -1259,7 +1259,7 @@ import java.util.concurrent.TimeoutException; ...@@ -1259,7 +1259,7 @@ import java.util.concurrent.TimeoutException;
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
TrackGroupArray.EMPTY, TrackGroupArray.EMPTY,
emptyTrackSelectorResult, emptyTrackSelectorResult,
ImmutableList.of()); /* staticMetadata= */ ImmutableList.of());
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(dummyMediaPeriodId); playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(dummyMediaPeriodId);
playbackInfo.bufferedPositionUs = playbackInfo.positionUs; playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
return playbackInfo; return playbackInfo;
......
...@@ -2247,14 +2247,20 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2247,14 +2247,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray( private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray(
TrackSelectionArray trackSelectionArray) { TrackSelectionArray trackSelectionArray) {
ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>(); ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>();
boolean seenNonEmptyMetadata = false;
for (int i = 0; i < trackSelectionArray.length; i++) { for (int i = 0; i < trackSelectionArray.length; i++) {
@Nullable TrackSelection trackSelection = trackSelectionArray.get(i); @Nullable TrackSelection trackSelection = trackSelectionArray.get(i);
if (trackSelection != null) { if (trackSelection != null) {
Format format = trackSelection.getFormat(/* index= */ 0); Format format = trackSelection.getFormat(/* index= */ 0);
result.add(format.metadata == null ? new Metadata() : format.metadata); if (format.metadata == null) {
result.add(new Metadata());
} else {
result.add(format.metadata);
seenNonEmptyMetadata = true;
}
} }
} }
return result.build(); return seenNonEmptyMetadata ? result.build() : ImmutableList.of();
} }
private void enableRenderers() throws ExoPlaybackException { private void enableRenderers() throws ExoPlaybackException {
......
...@@ -512,8 +512,8 @@ public interface Player { ...@@ -512,8 +512,8 @@ public interface Player {
* *
* <p>The provided {@code metadataList} is an immutable list of {@link Metadata} instances, * <p>The provided {@code metadataList} is an immutable list of {@link Metadata} instances,
* where the elements correspond to the {@link #getCurrentTrackSelections() current track * where the elements correspond to the {@link #getCurrentTrackSelections() current track
* selections}, or an empty list if there are no track selections or the implementation does not * selections}, or an empty list if there are no track selections or the selected tracks contain
* support metadata. * no static metadata.
* *
* <p>The metadata is considered static in the sense that it comes from the tracks' declared * <p>The metadata is considered static in the sense that it comes from the tracks' declared
* Formats, rather than being timed (or dynamic) metadata, which is represented within a * Formats, rather than being timed (or dynamic) metadata, which is represented within a
...@@ -1433,7 +1433,7 @@ public interface Player { ...@@ -1433,7 +1433,7 @@ public interface Player {
* *
* <p>The returned {@code metadataList} is an immutable list of {@link Metadata} instances, where * <p>The returned {@code metadataList} is an immutable list of {@link Metadata} instances, where
* the elements correspond to the {@link #getCurrentTrackSelections() current track selections}, * the elements correspond to the {@link #getCurrentTrackSelections() current track selections},
* or an empty list if there are no track selections or the implementation does not support * or an empty list if there are no track selections or the selected tracks contain no static
* metadata. * metadata.
* *
* <p>This metadata is considered static in that it comes from the tracks' declared Formats, * <p>This metadata is considered static in that it comes from the tracks' declared Formats,
......
...@@ -604,7 +604,7 @@ public interface AnalyticsListener { ...@@ -604,7 +604,7 @@ public interface AnalyticsListener {
* <p>The provided {@code metadataList} is an immutable list of {@link Metadata} instances, where * <p>The provided {@code metadataList} is an immutable list of {@link Metadata} instances, where
* the elements correspond to the current track selections (as returned by {@link * the elements correspond to the current track selections (as returned by {@link
* #onTracksChanged(EventTime, TrackGroupArray, TrackSelectionArray)}, or an empty list if there * #onTracksChanged(EventTime, TrackGroupArray, TrackSelectionArray)}, or an empty list if there
* are no track selections or the implementation does not support metadata. * are no track selections or the selected tracks contain no static metadata.
* *
* <p>The metadata is considered static in the sense that it comes from the tracks' declared * <p>The metadata is considered static in the sense that it comes from the tracks' declared
* Formats, rather than being timed (or dynamic) metadata, which is represented within a metadata * Formats, rather than being timed (or dynamic) metadata, which is represented within a metadata
......
...@@ -8260,8 +8260,6 @@ public final class ExoPlayerTest { ...@@ -8260,8 +8260,6 @@ public final class ExoPlayerTest {
Format videoFormat = Format videoFormat =
new Format.Builder() new Format.Builder()
.setSampleMimeType(MimeTypes.VIDEO_H264) .setSampleMimeType(MimeTypes.VIDEO_H264)
.setWidth(1920)
.setHeight(720)
.setMetadata( .setMetadata(
new Metadata( new Metadata(
new TextInformationFrame( new TextInformationFrame(
...@@ -8269,11 +8267,9 @@ public final class ExoPlayerTest { ...@@ -8269,11 +8267,9 @@ public final class ExoPlayerTest {
/* description= */ "Video", /* description= */ "Video",
/* value= */ "Video track name"))) /* value= */ "Video track name")))
.build(); .build();
Format audioFormat = Format audioFormat =
new Format.Builder() new Format.Builder()
.setSampleMimeType(MimeTypes.AUDIO_AAC) .setSampleMimeType(MimeTypes.AUDIO_AAC)
.setSampleRate(44_000)
.setMetadata( .setMetadata(
new Metadata( new Metadata(
new TextInformationFrame( new TextInformationFrame(
...@@ -8281,9 +8277,7 @@ public final class ExoPlayerTest { ...@@ -8281,9 +8277,7 @@ public final class ExoPlayerTest {
/* description= */ "Audio", /* description= */ "Audio",
/* value= */ "Audio track name"))) /* value= */ "Audio track name")))
.build(); .build();
EventListener eventListener = mock(EventListener.class); EventListener eventListener = mock(EventListener.class);
Timeline fakeTimeline = Timeline fakeTimeline =
new FakeTimeline( new FakeTimeline(
new TimelineWindowDefinition( new TimelineWindowDefinition(
...@@ -8295,15 +8289,39 @@ public final class ExoPlayerTest { ...@@ -8295,15 +8289,39 @@ public final class ExoPlayerTest {
player.prepare(); player.prepare();
player.play(); player.play();
runUntilPlaybackState(player, Player.STATE_ENDED); runUntilPlaybackState(player, Player.STATE_ENDED);
List<Metadata> metadata = player.getCurrentStaticMetadata();
player.release();
assertThat(player.getCurrentStaticMetadata()) assertThat(metadata).containsExactly(videoFormat.metadata, audioFormat.metadata).inOrder();
.containsExactly(videoFormat.metadata, audioFormat.metadata)
.inOrder();
verify(eventListener) verify(eventListener)
.onStaticMetadataChanged(ImmutableList.of(videoFormat.metadata, audioFormat.metadata)); .onStaticMetadataChanged(ImmutableList.of(videoFormat.metadata, audioFormat.metadata));
} }
@Test @Test
public void staticMetadata_callbackIsNotCalledWhenMetadataEmptyAndGetterReturnsEmptyList()
throws Exception {
Format videoFormat = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build();
Format audioFormat = new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build();
EventListener eventListener = mock(EventListener.class);
Timeline fakeTimeline =
new FakeTimeline(
new TimelineWindowDefinition(
/* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 100000));
SimpleExoPlayer player = new TestExoPlayerBuilder(context).build();
player.setMediaSource(new FakeMediaSource(fakeTimeline, videoFormat, audioFormat));
player.addListener(eventListener);
player.prepare();
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
List<Metadata> metadata = player.getCurrentStaticMetadata();
player.release();
assertThat(metadata).isEmpty();
verify(eventListener, never()).onStaticMetadataChanged(any());
}
@Test
public void targetLiveOffsetInMedia_adjustsLiveOffsetToTargetOffset() throws Exception { public void targetLiveOffsetInMedia_adjustsLiveOffsetToTargetOffset() throws Exception {
long windowStartUnixTimeMs = 987_654_321_000L; long windowStartUnixTimeMs = 987_654_321_000L;
long nowUnixTimeMs = windowStartUnixTimeMs + 20_000; long nowUnixTimeMs = windowStartUnixTimeMs + 20_000;
......
...@@ -40,7 +40,6 @@ import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_PL ...@@ -40,7 +40,6 @@ import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_PL
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_PLAY_WHEN_READY_CHANGED; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_PLAY_WHEN_READY_CHANGED;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_POSITION_DISCONTINUITY; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_POSITION_DISCONTINUITY;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_RENDERED_FIRST_FRAME; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_RENDERED_FIRST_FRAME;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_STATIC_METADATA_CHANGED;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_TIMELINE_CHANGED; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_TIMELINE_CHANGED;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_TRACKS_CHANGED; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_TRACKS_CHANGED;
import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_VIDEO_DECODER_INITIALIZED; import static com.google.android.exoplayer2.analytics.AnalyticsListener.EVENT_VIDEO_DECODER_INITIALIZED;
...@@ -1714,10 +1713,6 @@ public final class AnalyticsCollectorTest { ...@@ -1714,10 +1713,6 @@ public final class AnalyticsCollectorTest {
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
.onAudioEnabled(individualAudioEnabledEventTimes.capture(), any()); .onAudioEnabled(individualAudioEnabledEventTimes.capture(), any());
ArgumentCaptor<AnalyticsListener.EventTime> individualStaticMetadataChangedEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce())
.onStaticMetadataChanged(individualStaticMetadataChangedEventTimes.capture(), any());
ArgumentCaptor<AnalyticsListener.EventTime> individualDownstreamFormatChangedEventTimes = ArgumentCaptor<AnalyticsListener.EventTime> individualDownstreamFormatChangedEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
...@@ -1839,9 +1834,6 @@ public final class AnalyticsCollectorTest { ...@@ -1839,9 +1834,6 @@ public final class AnalyticsCollectorTest {
assertThat(individualAudioEnabledEventTimes.getAllValues()) assertThat(individualAudioEnabledEventTimes.getAllValues())
.containsAtLeastElementsIn(onEventsEventTimes.get(EVENT_AUDIO_ENABLED)) .containsAtLeastElementsIn(onEventsEventTimes.get(EVENT_AUDIO_ENABLED))
.inOrder(); .inOrder();
assertThat(individualStaticMetadataChangedEventTimes.getAllValues())
.containsAtLeastElementsIn(onEventsEventTimes.get(EVENT_STATIC_METADATA_CHANGED))
.inOrder();
assertThat(individualDownstreamFormatChangedEventTimes.getAllValues()) assertThat(individualDownstreamFormatChangedEventTimes.getAllValues())
.containsAtLeastElementsIn(onEventsEventTimes.get(EVENT_DOWNSTREAM_FORMAT_CHANGED)) .containsAtLeastElementsIn(onEventsEventTimes.get(EVENT_DOWNSTREAM_FORMAT_CHANGED))
.inOrder(); .inOrder();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment