Add getter and callbacks for static metadata retrieval.
Issue:#7266 PiperOrigin-RevId: 335416280
This commit is contained in:
parent
41192ee046
commit
a552e35f6a
@ -10,6 +10,8 @@
|
||||
still possible until the next major release using
|
||||
`setThrowsWhenUsingWrongThread(false)`
|
||||
([#4463](https://github.com/google/ExoPlayer/issues/4463)).
|
||||
* Add a getter and callback for static metadata to the player
|
||||
([#7266](https://github.com/google/ExoPlayer/issues/7266)).
|
||||
* Track selection:
|
||||
* Add option to specify multiple preferred audio or text languages.
|
||||
* Data sources:
|
||||
|
@ -27,6 +27,7 @@ import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
|
||||
@ -51,6 +52,7 @@ import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.ResultCallback;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@ -561,6 +563,12 @@ public final class CastPlayer extends BasePlayer {
|
||||
return currentTrackGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Metadata> getCurrentStaticMetadata() {
|
||||
// CastPlayer does not currently support metadata.
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
return currentTimeline;
|
||||
|
@ -28,6 +28,7 @@ import android.util.Pair;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.PlayerMessage.Target;
|
||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSourceFactory;
|
||||
@ -43,6 +44,7 @@ import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -861,6 +863,11 @@ import java.util.concurrent.TimeoutException;
|
||||
return playbackInfo.trackSelectorResult.selections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Metadata> getCurrentStaticMetadata() {
|
||||
return playbackInfo.staticMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
return playbackInfo.timeline;
|
||||
@ -1168,7 +1175,8 @@ import java.util.concurrent.TimeoutException;
|
||||
/* requestedContentPositionUs= */ C.msToUs(maskingWindowPositionMs),
|
||||
/* totalBufferedDurationUs= */ 0,
|
||||
TrackGroupArray.EMPTY,
|
||||
emptyTrackSelectorResult);
|
||||
emptyTrackSelectorResult,
|
||||
ImmutableList.of());
|
||||
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(dummyMediaPeriodId);
|
||||
playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
|
||||
return playbackInfo;
|
||||
@ -1195,7 +1203,8 @@ import java.util.concurrent.TimeoutException;
|
||||
/* requestedContentPositionUs= */ newContentPositionUs,
|
||||
/* totalBufferedDurationUs= */ 0,
|
||||
playingPeriodChanged ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
||||
playingPeriodChanged ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult);
|
||||
playingPeriodChanged ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
||||
playingPeriodChanged ? ImmutableList.of() : playbackInfo.staticMetadata);
|
||||
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(newPeriodId);
|
||||
playbackInfo.bufferedPositionUs = newContentPositionUs;
|
||||
} else if (newContentPositionUs == oldContentPositionUs) {
|
||||
@ -1219,7 +1228,8 @@ import java.util.concurrent.TimeoutException;
|
||||
/* requestedContentPositionUs= */ playbackInfo.positionUs,
|
||||
/* totalBufferedDurationUs= */ maskedBufferedPositionUs - playbackInfo.positionUs,
|
||||
playbackInfo.trackGroups,
|
||||
playbackInfo.trackSelectorResult);
|
||||
playbackInfo.trackSelectorResult,
|
||||
playbackInfo.staticMetadata);
|
||||
playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(newPeriodId);
|
||||
playbackInfo.bufferedPositionUs = maskedBufferedPositionUs;
|
||||
}
|
||||
@ -1241,7 +1251,8 @@ import java.util.concurrent.TimeoutException;
|
||||
/* requestedContentPositionUs= */ newContentPositionUs,
|
||||
maskedTotalBufferedDurationUs,
|
||||
playbackInfo.trackGroups,
|
||||
playbackInfo.trackSelectorResult);
|
||||
playbackInfo.trackSelectorResult,
|
||||
playbackInfo.staticMetadata);
|
||||
playbackInfo.bufferedPositionUs = maskedBufferedPositionUs;
|
||||
}
|
||||
return playbackInfo;
|
||||
@ -1348,6 +1359,7 @@ import java.util.concurrent.TimeoutException;
|
||||
private final boolean isLoadingChanged;
|
||||
private final boolean timelineChanged;
|
||||
private final boolean trackSelectorResultChanged;
|
||||
private final boolean staticMetadataChanged;
|
||||
private final boolean playWhenReadyChanged;
|
||||
private final boolean playbackSuppressionReasonChanged;
|
||||
private final boolean isPlayingChanged;
|
||||
@ -1387,6 +1399,8 @@ import java.util.concurrent.TimeoutException;
|
||||
timelineChanged = !previousPlaybackInfo.timeline.equals(playbackInfo.timeline);
|
||||
trackSelectorResultChanged =
|
||||
previousPlaybackInfo.trackSelectorResult != playbackInfo.trackSelectorResult;
|
||||
staticMetadataChanged =
|
||||
!previousPlaybackInfo.staticMetadata.equals(playbackInfo.staticMetadata);
|
||||
playWhenReadyChanged = previousPlaybackInfo.playWhenReady != playbackInfo.playWhenReady;
|
||||
playbackSuppressionReasonChanged =
|
||||
previousPlaybackInfo.playbackSuppressionReason != playbackInfo.playbackSuppressionReason;
|
||||
@ -1428,6 +1442,11 @@ import java.util.concurrent.TimeoutException;
|
||||
listener.onTracksChanged(
|
||||
playbackInfo.trackGroups, playbackInfo.trackSelectorResult.selections));
|
||||
}
|
||||
if (staticMetadataChanged) {
|
||||
invokeAll(
|
||||
listenerSnapshot,
|
||||
listener -> listener.onStaticMetadataChanged(playbackInfo.staticMetadata));
|
||||
}
|
||||
if (isLoadingChanged) {
|
||||
invokeAll(
|
||||
listenerSnapshot, listener -> listener.onIsLoadingChanged(playbackInfo.isLoading));
|
||||
|
@ -33,12 +33,14 @@ import com.google.android.exoplayer2.Player.PlayWhenReadyChangeReason;
|
||||
import com.google.android.exoplayer2.Player.PlaybackSuppressionReason;
|
||||
import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
@ -49,6 +51,7 @@ import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.TraceUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -1338,6 +1341,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
/* isLoading= */ false,
|
||||
resetTrackInfo ? TrackGroupArray.EMPTY : playbackInfo.trackGroups,
|
||||
resetTrackInfo ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult,
|
||||
resetTrackInfo ? ImmutableList.of() : playbackInfo.staticMetadata,
|
||||
mediaPeriodId,
|
||||
playbackInfo.playWhenReady,
|
||||
playbackInfo.playbackSuppressionReason,
|
||||
@ -2096,6 +2100,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
resetPendingPauseAtEndOfPeriod();
|
||||
TrackGroupArray trackGroupArray = playbackInfo.trackGroups;
|
||||
TrackSelectorResult trackSelectorResult = playbackInfo.trackSelectorResult;
|
||||
List<Metadata> staticMetadata = playbackInfo.staticMetadata;
|
||||
if (mediaSourceList.isPrepared()) {
|
||||
@Nullable MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
|
||||
trackGroupArray =
|
||||
@ -2106,18 +2111,35 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
playingPeriodHolder == null
|
||||
? emptyTrackSelectorResult
|
||||
: playingPeriodHolder.getTrackSelectorResult();
|
||||
staticMetadata = extractMetadataFromTrackSelectionArray(trackSelectorResult.selections);
|
||||
} else if (!mediaPeriodId.equals(playbackInfo.periodId)) {
|
||||
// Reset previously kept track info if unprepared and the period changes.
|
||||
trackGroupArray = TrackGroupArray.EMPTY;
|
||||
trackSelectorResult = emptyTrackSelectorResult;
|
||||
staticMetadata = ImmutableList.of();
|
||||
}
|
||||
|
||||
return playbackInfo.copyWithNewPosition(
|
||||
mediaPeriodId,
|
||||
positionUs,
|
||||
contentPositionUs,
|
||||
getTotalBufferedDurationUs(),
|
||||
trackGroupArray,
|
||||
trackSelectorResult);
|
||||
trackSelectorResult,
|
||||
staticMetadata);
|
||||
}
|
||||
|
||||
private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray(
|
||||
TrackSelectionArray trackSelectionArray) {
|
||||
ImmutableList.Builder<Metadata> builder = new ImmutableList.Builder<>();
|
||||
for (int i = 0; i < trackSelectionArray.length; i++) {
|
||||
@Nullable TrackSelection trackSelection = trackSelectionArray.get(i);
|
||||
if (trackSelection != null) {
|
||||
Format format = trackSelection.getFormat(0);
|
||||
builder.add(format.metadata == null ? new Metadata() : format.metadata);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void enableRenderers() throws ExoPlaybackException {
|
||||
|
@ -18,9 +18,12 @@ package com.google.android.exoplayer2;
|
||||
import androidx.annotation.CheckResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Player.PlaybackSuppressionReason;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Information about an ongoing playback.
|
||||
@ -57,6 +60,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
public final TrackGroupArray trackGroups;
|
||||
/** The result of the current track selection. */
|
||||
public final TrackSelectorResult trackSelectorResult;
|
||||
/** The current static metadata of the track selections. */
|
||||
public final List<Metadata> staticMetadata;
|
||||
/** The {@link MediaPeriodId} of the currently loading media period in the {@link #timeline}. */
|
||||
public final MediaPeriodId loadingMediaPeriodId;
|
||||
/** Whether playback should proceed when {@link #playbackState} == {@link Player#STATE_READY}. */
|
||||
@ -104,6 +109,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
/* isLoading= */ false,
|
||||
TrackGroupArray.EMPTY,
|
||||
emptyTrackSelectorResult,
|
||||
/* staticMetadata= */ ImmutableList.of(),
|
||||
PLACEHOLDER_MEDIA_PERIOD_ID,
|
||||
/* playWhenReady= */ false,
|
||||
Player.PLAYBACK_SUPPRESSION_REASON_NONE,
|
||||
@ -126,6 +132,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
* @param isLoading See {@link #isLoading}.
|
||||
* @param trackGroups See {@link #trackGroups}.
|
||||
* @param trackSelectorResult See {@link #trackSelectorResult}.
|
||||
* @param staticMetadata See {@link #staticMetadata}.
|
||||
* @param loadingMediaPeriodId See {@link #loadingMediaPeriodId}.
|
||||
* @param playWhenReady See {@link #playWhenReady}.
|
||||
* @param playbackSuppressionReason See {@link #playbackSuppressionReason}.
|
||||
@ -145,6 +152,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
boolean isLoading,
|
||||
TrackGroupArray trackGroups,
|
||||
TrackSelectorResult trackSelectorResult,
|
||||
List<Metadata> staticMetadata,
|
||||
MediaPeriodId loadingMediaPeriodId,
|
||||
boolean playWhenReady,
|
||||
@PlaybackSuppressionReason int playbackSuppressionReason,
|
||||
@ -162,6 +170,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
this.isLoading = isLoading;
|
||||
this.trackGroups = trackGroups;
|
||||
this.trackSelectorResult = trackSelectorResult;
|
||||
this.staticMetadata = staticMetadata;
|
||||
this.loadingMediaPeriodId = loadingMediaPeriodId;
|
||||
this.playWhenReady = playWhenReady;
|
||||
this.playbackSuppressionReason = playbackSuppressionReason;
|
||||
@ -189,6 +198,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
* @param trackGroups The track groups for the new position. See {@link #trackGroups}.
|
||||
* @param trackSelectorResult The track selector result for the new position. See {@link
|
||||
* #trackSelectorResult}.
|
||||
* @param staticMetadata The static metadata for the track selections. See {@link
|
||||
* #staticMetadata}.
|
||||
* @return Copied playback info with new playing position.
|
||||
*/
|
||||
@CheckResult
|
||||
@ -198,7 +209,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
long requestedContentPositionUs,
|
||||
long totalBufferedDurationUs,
|
||||
TrackGroupArray trackGroups,
|
||||
TrackSelectorResult trackSelectorResult) {
|
||||
TrackSelectorResult trackSelectorResult,
|
||||
List<Metadata> staticMetadata) {
|
||||
return new PlaybackInfo(
|
||||
timeline,
|
||||
periodId,
|
||||
@ -208,6 +220,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -236,6 +249,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -264,6 +278,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -292,6 +307,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -320,6 +336,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -348,6 +365,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -380,6 +398,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -408,6 +427,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -437,6 +457,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
@ -465,6 +486,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
|
||||
isLoading,
|
||||
trackGroups,
|
||||
trackSelectorResult,
|
||||
staticMetadata,
|
||||
loadingMediaPeriodId,
|
||||
playWhenReady,
|
||||
playbackSuppressionReason,
|
||||
|
@ -28,12 +28,14 @@ import com.google.android.exoplayer2.audio.AudioListener;
|
||||
import com.google.android.exoplayer2.audio.AuxEffectInfo;
|
||||
import com.google.android.exoplayer2.device.DeviceInfo;
|
||||
import com.google.android.exoplayer2.device.DeviceListener;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataOutput;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||
import com.google.android.exoplayer2.util.StableApiCandidate;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.android.exoplayer2.video.VideoDecoderOutputBufferRenderer;
|
||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||
@ -491,6 +493,22 @@ public interface Player {
|
||||
default void onTracksChanged(
|
||||
TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
|
||||
|
||||
/**
|
||||
* Called when the static metadata changes.
|
||||
*
|
||||
* <p>The provided {@code metadataList} is an immutable list of {@link Metadata} instances,
|
||||
* 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
|
||||
* support metadata.
|
||||
*
|
||||
* <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 track.
|
||||
*
|
||||
* @param metadataList The static metadata.
|
||||
*/
|
||||
default void onStaticMetadataChanged(List<Metadata> metadataList) {}
|
||||
|
||||
/**
|
||||
* Called when the player starts or stops loading the source.
|
||||
*
|
||||
@ -1226,16 +1244,25 @@ public interface Player {
|
||||
@Nullable
|
||||
TrackSelector getTrackSelector();
|
||||
|
||||
/**
|
||||
* Returns the available track groups.
|
||||
*/
|
||||
/** Returns the available track groups. */
|
||||
TrackGroupArray getCurrentTrackGroups();
|
||||
|
||||
/**
|
||||
* Returns the current track selections for each renderer.
|
||||
*/
|
||||
/** Returns the current track selections for each renderer. */
|
||||
TrackSelectionArray getCurrentTrackSelections();
|
||||
|
||||
/**
|
||||
* Returns the current static metadata for the track selections.
|
||||
*
|
||||
* <p>The returned {@code metadataList} is an immutable list of {@link Metadata} instances, 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 support
|
||||
* metadata.
|
||||
*
|
||||
* <p>This metadata is considered static in that it comes from the tracks' declared Formats,
|
||||
* rather than being timed (or dynamic) metadata, which is represented within a metadata track.
|
||||
*/
|
||||
List<Metadata> getCurrentStaticMetadata();
|
||||
|
||||
/**
|
||||
* Returns the current manifest. The type depends on the type of media being played. May be null.
|
||||
*/
|
||||
|
@ -1761,6 +1761,12 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
return player.getCurrentTrackSelections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Metadata> getCurrentStaticMetadata() {
|
||||
verifyApplicationThread();
|
||||
return player.getCurrentStaticMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
verifyApplicationThread();
|
||||
|
@ -470,6 +470,14 @@ public class AnalyticsCollector
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onStaticMetadataChanged(List<Metadata> metadataList) {
|
||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||
for (AnalyticsListener listener : listeners) {
|
||||
listener.onStaticMetadataChanged(eventTime, metadataList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onIsLoadingChanged(boolean isLoading) {
|
||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||
|
@ -38,6 +38,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.common.base.Objects;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A listener for analytics events.
|
||||
@ -337,6 +338,23 @@ public interface AnalyticsListener {
|
||||
default void onTracksChanged(
|
||||
EventTime eventTime, TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {}
|
||||
|
||||
/**
|
||||
* Called when the static metadata changes.
|
||||
*
|
||||
* <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
|
||||
* #onTracksChanged(EventTime, TrackGroupArray, TrackSelectionArray)}, or an empty list if there
|
||||
* are no track selections or the implementation does not support metadata.
|
||||
*
|
||||
* <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
|
||||
* track.
|
||||
*
|
||||
* @param eventTime The event time.
|
||||
* @param metadataList The static metadata.
|
||||
*/
|
||||
default void onStaticMetadataChanged(EventTime eventTime, List<Metadata> metadataList) {}
|
||||
|
||||
/**
|
||||
* Called when a media source started loading data.
|
||||
*
|
||||
|
@ -45,6 +45,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import java.io.IOException;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/** Logs events from {@link Player} and other core components using {@link Log}. */
|
||||
@ -295,6 +296,16 @@ public class EventLogger implements AnalyticsListener {
|
||||
logd("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStaticMetadataChanged(EventTime eventTime, List<Metadata> metadataList) {
|
||||
logd("staticMetadata [" + getEventTimeString(eventTime));
|
||||
for (int i = 0; i < metadataList.size(); i++) {
|
||||
logd(" " + i);
|
||||
printMetadata(metadataList.get(i), " ");
|
||||
}
|
||||
logd("]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetadata(EventTime eventTime, Metadata metadata) {
|
||||
logd("metadata [" + getEventTimeString(eventTime));
|
||||
|
@ -56,6 +56,8 @@ import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
||||
import com.google.android.exoplayer2.audio.AudioAttributes;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
|
||||
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
||||
import com.google.android.exoplayer2.source.CompositeMediaSource;
|
||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||
@ -104,6 +106,7 @@ import com.google.android.exoplayer2.upstream.Loader;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Clock;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -8309,6 +8312,54 @@ public final class ExoPlayerTest {
|
||||
runUntilPlaybackState(player, Player.STATE_ENDED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void staticMetadata_callbackIsCalledCorrectlyAndMatchesGetter() throws Exception {
|
||||
Format videoFormat =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(MimeTypes.VIDEO_H264)
|
||||
.setWidth(1920)
|
||||
.setHeight(720)
|
||||
.setMetadata(
|
||||
new Metadata(
|
||||
new TextInformationFrame(
|
||||
/* id= */ "TT2",
|
||||
/* description= */ "Video",
|
||||
/* value= */ "Video track name")))
|
||||
.build();
|
||||
|
||||
Format audioFormat =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(MimeTypes.AUDIO_AAC)
|
||||
.setSampleRate(44_000)
|
||||
.setMetadata(
|
||||
new Metadata(
|
||||
new TextInformationFrame(
|
||||
/* id= */ "TT2",
|
||||
/* description= */ "Audio",
|
||||
/* value= */ "Audio track name")))
|
||||
.build();
|
||||
|
||||
EventListener eventListener = mock(EventListener.class);
|
||||
|
||||
Timeline fakeTimeline =
|
||||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(
|
||||
/* isSeekable= */ true, /* isDynamic= */ false, /* durationUs= */ 100000));
|
||||
SimpleExoPlayer player = new TestExoPlayer.Builder(context).build();
|
||||
|
||||
player.setMediaSource(new FakeMediaSource(fakeTimeline, videoFormat, audioFormat));
|
||||
player.addListener(eventListener);
|
||||
player.prepare();
|
||||
player.play();
|
||||
runUntilPlaybackState(player, Player.STATE_ENDED);
|
||||
|
||||
assertThat(player.getCurrentStaticMetadata())
|
||||
.containsExactly(videoFormat.metadata, audioFormat.metadata)
|
||||
.inOrder();
|
||||
verify(eventListener)
|
||||
.onStaticMetadataChanged(ImmutableList.of(videoFormat.metadata, audioFormat.metadata));
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private static ActionSchedule.Builder addSurfaceSwitch(ActionSchedule.Builder builder) {
|
||||
|
@ -432,6 +432,7 @@ public final class MediaPeriodQueueTest {
|
||||
/* isLoading= */ false,
|
||||
/* trackGroups= */ null,
|
||||
/* trackSelectorResult= */ null,
|
||||
/* staticMetadata= */ ImmutableList.of(),
|
||||
/* loadingMediaPeriodId= */ null,
|
||||
/* playWhenReady= */ false,
|
||||
Player.PLAYBACK_SUPPRESSION_REASON_NONE,
|
||||
|
@ -58,7 +58,6 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextOutput;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||
import com.google.android.exoplayer2.ui.spherical.SingleTapListener;
|
||||
@ -1369,17 +1368,11 @@ public class StyledPlayerView extends FrameLayout implements AdsLoader.AdViewPro
|
||||
closeShutter();
|
||||
// Display artwork if enabled and available, else hide it.
|
||||
if (useArtwork()) {
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
@Nullable TrackSelection selection = selections.get(i);
|
||||
if (selection != null) {
|
||||
for (int j = 0; j < selection.length(); j++) {
|
||||
@Nullable Metadata metadata = selection.getFormat(j).metadata;
|
||||
if (metadata != null && setArtworkFromMetadata(metadata)) {
|
||||
for (Metadata metadata : player.getCurrentStaticMetadata()) {
|
||||
if (setArtworkFromMetadata(metadata)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setDrawableArtwork(defaultArtwork)) {
|
||||
return;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.PlayerMessage;
|
||||
import com.google.android.exoplayer2.SeekParameters;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ShuffleOrder;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
@ -375,6 +376,11 @@ public abstract class StubExoPlayer extends BasePlayer implements ExoPlayer {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Metadata> getCurrentStaticMetadata() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timeline getCurrentTimeline() {
|
||||
throw new UnsupportedOperationException();
|
||||
|
Loading…
x
Reference in New Issue
Block a user