mirror of
https://github.com/samsonjs/media.git
synced 2026-04-01 10:35:48 +00:00
Move the ownership of MediaMetadata to ExoPlayerImpl.
Add the onMediaMetadataChanged event to onEvents. PiperOrigin-RevId: 370738521
This commit is contained in:
parent
1d96d6b6b0
commit
b336df3ed3
6 changed files with 99 additions and 41 deletions
|
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.util.Util;
|
|||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
|
||||
/** Metadata of a {@link MediaItem} or a playlist. */
|
||||
public final class MediaMetadata implements Bundleable {
|
||||
|
|
@ -68,6 +69,27 @@ public final class MediaMetadata implements Bundleable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all fields supported by the {@link Metadata.Entry entries} within the list of {@link
|
||||
* Metadata}.
|
||||
*
|
||||
* <p>Fields are only set if the {@link Metadata.Entry} has an implementation for {@link
|
||||
* Metadata.Entry#populateMediaMetadata(Builder)}.
|
||||
*
|
||||
* <p>In the event that multiple {@link Metadata.Entry} objects within any of the {@link
|
||||
* Metadata} relate to the same {@link MediaMetadata} field, then the last one will be used.
|
||||
*/
|
||||
public Builder populateFromMetadata(List<Metadata> metadataList) {
|
||||
for (int i = 0; i < metadataList.size(); i++) {
|
||||
Metadata metadata = metadataList.get(i);
|
||||
for (int j = 0; j < metadata.length(); j++) {
|
||||
Metadata.Entry entry = metadata.get(j);
|
||||
entry.populateMediaMetadata(this);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Returns a new {@link MediaMetadata} instance with the current builder values. */
|
||||
public MediaMetadata build() {
|
||||
return new MediaMetadata(/* builder= */ this);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ public interface Player {
|
|||
* and the static and dynamic metadata sourced from {@link
|
||||
* EventListener#onStaticMetadataChanged(List)} and {@link MetadataOutput#onMetadata(Metadata)}.
|
||||
*
|
||||
* <p>{@link #onEvents(Player, Events)} will also be called to report this event along with
|
||||
* other events that happen in the same {@link Looper} message queue iteration.
|
||||
*
|
||||
* @param mediaMetadata The combined {@link MediaMetadata}.
|
||||
*/
|
||||
default void onMediaMetadataChanged(MediaMetadata mediaMetadata) {}
|
||||
|
|
@ -899,7 +902,8 @@ public interface Player {
|
|||
EVENT_PLAYER_ERROR,
|
||||
EVENT_POSITION_DISCONTINUITY,
|
||||
EVENT_PLAYBACK_PARAMETERS_CHANGED,
|
||||
EVENT_AVAILABLE_COMMANDS_CHANGED
|
||||
EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||
EVENT_MEDIA_METADATA_CHANGED
|
||||
})
|
||||
@interface EventFlags {}
|
||||
/** {@link #getCurrentTimeline()} changed. */
|
||||
|
|
@ -935,6 +939,8 @@ public interface Player {
|
|||
int EVENT_PLAYBACK_PARAMETERS_CHANGED = 13;
|
||||
/** {@link #isCommandAvailable(int)} changed for at least one {@link Command}. */
|
||||
int EVENT_AVAILABLE_COMMANDS_CHANGED = 14;
|
||||
/** {@link #getMediaMetadata()} changed. */
|
||||
int EVENT_MEDIA_METADATA_CHANGED = 15;
|
||||
|
||||
/**
|
||||
* Commands that can be executed on a {@code Player}. One of {@link #COMMAND_PLAY_PAUSE}, {@link
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
private ShuffleOrder shuffleOrder;
|
||||
private boolean pauseAtEndOfMediaItems;
|
||||
private Commands availableCommands;
|
||||
private MediaMetadata mediaMetadata;
|
||||
|
||||
// Playback information when there is no pending seek/set source operation.
|
||||
private PlaybackInfo playbackInfo;
|
||||
|
|
@ -208,6 +209,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
.add(COMMAND_SEEK_TO_DEFAULT_POSITION)
|
||||
.add(COMMAND_SEEK_TO_MEDIA_ITEM)
|
||||
.build();
|
||||
mediaMetadata = MediaMetadata.EMPTY;
|
||||
maskingWindowIndex = C.INDEX_UNSET;
|
||||
playbackInfoUpdateHandler = clock.createHandler(applicationLooper, /* callback= */ null);
|
||||
playbackInfoUpdateListener =
|
||||
|
|
@ -983,8 +985,18 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
|
||||
@Override
|
||||
public MediaMetadata getMediaMetadata() {
|
||||
// Unsupported operation.
|
||||
return MediaMetadata.EMPTY;
|
||||
return mediaMetadata;
|
||||
}
|
||||
|
||||
public void onMetadata(Metadata metadata) {
|
||||
MediaMetadata newMediaMetadata =
|
||||
mediaMetadata.buildUpon().populateFromMetadata(metadata).build();
|
||||
if (newMediaMetadata.equals(mediaMetadata)) {
|
||||
return;
|
||||
}
|
||||
mediaMetadata = newMediaMetadata;
|
||||
listeners.sendEvent(
|
||||
EVENT_MEDIA_METADATA_CHANGED, listener -> listener.onMediaMetadataChanged(mediaMetadata));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1194,6 +1206,24 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
!previousPlaybackInfo.timeline.equals(newPlaybackInfo.timeline));
|
||||
boolean mediaItemTransitioned = mediaItemTransitionInfo.first;
|
||||
int mediaItemTransitionReason = mediaItemTransitionInfo.second;
|
||||
MediaMetadata newMediaMetadata = mediaMetadata;
|
||||
@Nullable MediaItem mediaItem = null;
|
||||
if (mediaItemTransitioned) {
|
||||
if (!newPlaybackInfo.timeline.isEmpty()) {
|
||||
int windowIndex =
|
||||
newPlaybackInfo.timeline.getPeriodByUid(newPlaybackInfo.periodId.periodUid, period)
|
||||
.windowIndex;
|
||||
mediaItem = newPlaybackInfo.timeline.getWindow(windowIndex, window).mediaItem;
|
||||
}
|
||||
mediaMetadata = mediaItem != null ? mediaItem.mediaMetadata : MediaMetadata.EMPTY;
|
||||
}
|
||||
if (!previousPlaybackInfo.staticMetadata.equals(newPlaybackInfo.staticMetadata)) {
|
||||
newMediaMetadata =
|
||||
newMediaMetadata.buildUpon().populateFromMetadata(newPlaybackInfo.staticMetadata).build();
|
||||
}
|
||||
boolean metadataChanged = !newMediaMetadata.equals(mediaMetadata);
|
||||
mediaMetadata = newMediaMetadata;
|
||||
|
||||
if (!previousPlaybackInfo.timeline.equals(newPlaybackInfo.timeline)) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_TIMELINE_CHANGED,
|
||||
|
|
@ -1222,18 +1252,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
});
|
||||
}
|
||||
if (mediaItemTransitioned) {
|
||||
@Nullable final MediaItem mediaItem;
|
||||
if (!newPlaybackInfo.timeline.isEmpty()) {
|
||||
int windowIndex =
|
||||
newPlaybackInfo.timeline.getPeriodByUid(newPlaybackInfo.periodId.periodUid, period)
|
||||
.windowIndex;
|
||||
mediaItem = newPlaybackInfo.timeline.getWindow(windowIndex, window).mediaItem;
|
||||
} else {
|
||||
mediaItem = null;
|
||||
}
|
||||
@Nullable final MediaItem finalMediaItem = mediaItem;
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_MEDIA_ITEM_TRANSITION,
|
||||
listener -> listener.onMediaItemTransition(mediaItem, mediaItemTransitionReason));
|
||||
listener -> listener.onMediaItemTransition(finalMediaItem, mediaItemTransitionReason));
|
||||
}
|
||||
if (previousPlaybackInfo.playbackError != newPlaybackInfo.playbackError
|
||||
&& newPlaybackInfo.playbackError != null) {
|
||||
|
|
@ -1254,6 +1276,12 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
Player.EVENT_STATIC_METADATA_CHANGED,
|
||||
listener -> listener.onStaticMetadataChanged(newPlaybackInfo.staticMetadata));
|
||||
}
|
||||
if (metadataChanged) {
|
||||
final MediaMetadata finalMediaMetadata = mediaMetadata;
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_MEDIA_METADATA_CHANGED,
|
||||
listener -> listener.onMediaMetadataChanged(finalMediaMetadata));
|
||||
}
|
||||
if (previousPlaybackInfo.isLoading != newPlaybackInfo.isLoading) {
|
||||
listeners.queueEvent(
|
||||
Player.EVENT_IS_LOADING_CHANGED,
|
||||
|
|
|
|||
|
|
@ -636,7 +636,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
private boolean isPriorityTaskManagerRegistered;
|
||||
private boolean playerReleased;
|
||||
private DeviceInfo deviceInfo;
|
||||
private MediaMetadata currentMediaMetadata;
|
||||
|
||||
/** @deprecated Use the {@link Builder} and pass it to {@link #SimpleExoPlayer(Builder)}. */
|
||||
@Deprecated
|
||||
|
|
@ -749,7 +748,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
wifiLockManager = new WifiLockManager(builder.context);
|
||||
wifiLockManager.setEnabled(builder.wakeMode == C.WAKE_MODE_NETWORK);
|
||||
deviceInfo = createDeviceInfo(streamVolumeManager);
|
||||
currentMediaMetadata = MediaMetadata.EMPTY;
|
||||
|
||||
sendRendererMessage(C.TRACK_TYPE_AUDIO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||
sendRendererMessage(C.TRACK_TYPE_VIDEO, MSG_SET_AUDIO_SESSION_ID, audioSessionId);
|
||||
|
|
@ -1656,7 +1654,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
|
||||
@Override
|
||||
public MediaMetadata getMediaMetadata() {
|
||||
return currentMediaMetadata;
|
||||
return player.getMediaMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2069,14 +2067,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
return keepSessionIdAudioTrack.getAudioSessionId();
|
||||
}
|
||||
|
||||
private void setMediaMetadata(MediaMetadata mediaMetadata) {
|
||||
if (this.currentMediaMetadata.equals(mediaMetadata)) {
|
||||
return;
|
||||
}
|
||||
this.currentMediaMetadata = mediaMetadata;
|
||||
componentListener.onMediaMetadataChanged(this.currentMediaMetadata);
|
||||
}
|
||||
|
||||
private static DeviceInfo createDeviceInfo(StreamVolumeManager streamVolumeManager) {
|
||||
return new DeviceInfo(
|
||||
DeviceInfo.PLAYBACK_TYPE_LOCAL,
|
||||
|
|
@ -2252,7 +2242,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
@Override
|
||||
public void onMetadata(Metadata metadata) {
|
||||
analyticsCollector.onMetadata(metadata);
|
||||
setMediaMetadata(getMediaMetadata().buildUpon().populateFromMetadata(metadata).build());
|
||||
player.onMetadata(metadata);
|
||||
for (MetadataOutput metadataOutput : metadataOutputs) {
|
||||
metadataOutput.onMetadata(metadata);
|
||||
}
|
||||
|
|
@ -2376,22 +2366,6 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaItemTransition(
|
||||
@Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {
|
||||
currentMediaMetadata = mediaItem == null ? MediaMetadata.EMPTY : mediaItem.mediaMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStaticMetadataChanged(List<Metadata> metadataList) {
|
||||
MediaMetadata.Builder metadataBuilder = getMediaMetadata().buildUpon();
|
||||
for (int i = 0; i < metadataList.size(); i++) {
|
||||
metadataBuilder.populateFromMetadata(metadataList.get(i));
|
||||
}
|
||||
|
||||
setMediaMetadata(metadataBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackStateChanged(@State int playbackState) {
|
||||
updateWakeAndWifiLock();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.MediaMetadata;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Player.PlaybackSuppressionReason;
|
||||
|
|
@ -732,6 +733,15 @@ public class AnalyticsCollector
|
|||
listener -> listener.onPlaybackParametersChanged(eventTime, playbackParameters));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaMetadataChanged(MediaMetadata mediaMetadata) {
|
||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||
sendEvent(
|
||||
eventTime,
|
||||
AnalyticsListener.EVENT_MEDIA_METADATA_CHANGED,
|
||||
listener -> listener.onMediaMetadataChanged(eventTime, mediaMetadata));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Implementing and calling deprecated listener method.
|
||||
@Override
|
||||
public final void onSeekProcessed() {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.C;
|
|||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.MediaMetadata;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.Player.DiscontinuityReason;
|
||||
|
|
@ -42,6 +43,7 @@ import com.google.android.exoplayer2.decoder.DecoderException;
|
|||
import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation;
|
||||
import com.google.android.exoplayer2.drm.DrmSession;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataOutput;
|
||||
import com.google.android.exoplayer2.source.LoadEventInfo;
|
||||
import com.google.android.exoplayer2.source.MediaLoadData;
|
||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
|
|
@ -166,6 +168,7 @@ public interface AnalyticsListener {
|
|||
EVENT_PLAYER_ERROR,
|
||||
EVENT_POSITION_DISCONTINUITY,
|
||||
EVENT_PLAYBACK_PARAMETERS_CHANGED,
|
||||
EVENT_MEDIA_METADATA_CHANGED,
|
||||
EVENT_LOAD_STARTED,
|
||||
EVENT_LOAD_COMPLETED,
|
||||
EVENT_LOAD_CANCELED,
|
||||
|
|
@ -242,6 +245,8 @@ public interface AnalyticsListener {
|
|||
int EVENT_POSITION_DISCONTINUITY = Player.EVENT_POSITION_DISCONTINUITY;
|
||||
/** {@link Player#getPlaybackParameters()} changed. */
|
||||
int EVENT_PLAYBACK_PARAMETERS_CHANGED = Player.EVENT_PLAYBACK_PARAMETERS_CHANGED;
|
||||
/** {@link Player#getMediaMetadata()} changed. */
|
||||
int EVENT_MEDIA_METADATA_CHANGED = Player.EVENT_MEDIA_METADATA_CHANGED;
|
||||
/** A source started loading data. */
|
||||
int EVENT_LOAD_STARTED = 1000; // Intentional gap to leave space for new Player events
|
||||
/** A source started completed loading data. */
|
||||
|
|
@ -640,6 +645,19 @@ public interface AnalyticsListener {
|
|||
*/
|
||||
default void onStaticMetadataChanged(EventTime eventTime, List<Metadata> metadataList) {}
|
||||
|
||||
/**
|
||||
* Called when the combined {@link MediaMetadata} changes.
|
||||
*
|
||||
* <p>The provided {@link MediaMetadata} is a combination of the {@link MediaItem#mediaMetadata}
|
||||
* and the static and dynamic metadata sourced from {@link
|
||||
* Player.EventListener#onStaticMetadataChanged(List)} and {@link
|
||||
* MetadataOutput#onMetadata(Metadata)}.
|
||||
*
|
||||
* @param eventTime The event time.
|
||||
* @param mediaMetadata The combined {@link MediaMetadata}.
|
||||
*/
|
||||
default void onMediaMetadataChanged(EventTime eventTime, MediaMetadata mediaMetadata) {}
|
||||
|
||||
/**
|
||||
* Called when a media source started loading data.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue