mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Merge pull request #2235 from MGaetan89:add_CastPlayer_playlistMetadata
PiperOrigin-RevId: 738455260 (cherry picked from commit 2d1bcc77be3acd0a8297220f7564483c12db32b3)
This commit is contained in:
parent
dcb67102b9
commit
963bae9dd8
@ -1,5 +1,83 @@
|
||||
# Release notes
|
||||
|
||||
* Cast extension:
|
||||
* Add support for playlist metadata
|
||||
([#2235](https://github.com/androidx/media/pull/2235)).
|
||||
|
||||
### Unreleased changes
|
||||
|
||||
* Common Library:
|
||||
* ExoPlayer:
|
||||
* Transformer:
|
||||
* Track Selection:
|
||||
* Extractors:
|
||||
* MP3: Use duration and data size from unseekable Xing, VBRI and similar
|
||||
variable bitrate metadata when falling back to constant bitrate seeking
|
||||
due to `FLAG_ENABLE_CONSTANT_BITRATE_SEEKING(_ALWAYS)`
|
||||
([#2194](https://github.com/androidx/media/issues/2194)).
|
||||
* DataSource:
|
||||
* Audio:
|
||||
* Allow constant power upmixing/downmixing in DefaultAudioMixer.
|
||||
* Video:
|
||||
* Add experimental `ExoPlayer` API to include the
|
||||
`MediaCodec.BUFFER_FLAG_DECODE_ONLY` flag when queuing decode-only input
|
||||
buffers. This flag will signal the decoder to skip the decode-only
|
||||
buffers thereby resulting in faster seeking. Enable it with
|
||||
`DefaultRenderersFactory.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag`.
|
||||
* Text:
|
||||
* Metadata:
|
||||
* Image:
|
||||
* DataSource:
|
||||
* DRM:
|
||||
* Effect:
|
||||
* Add `Presentation.createForShortSide(int)` that creates a `Presentation`
|
||||
that ensures the shortest side always matches the given value,
|
||||
regardless of input orientation.
|
||||
* Muxers:
|
||||
* `writeSampleData()` API now uses muxer specific `BufferInfo` class
|
||||
instead of `MediaCodec.BufferInfo`.
|
||||
* IMA extension:
|
||||
* Session:
|
||||
* UI:
|
||||
* Downloads:
|
||||
* Add partial download support for progressive streams. Apps can prepare a
|
||||
progressive stream with `DownloadHelper`, and request a
|
||||
`DownloadRequest` from the helper with specifying the time-based media
|
||||
start and end positions that the download should cover. The returned
|
||||
`DownloadRequest` carries the resolved byte range, with which a
|
||||
`ProgressiveDownloader` can be created and download the content
|
||||
correspondingly.
|
||||
* OkHttp extension:
|
||||
* Cronet extension:
|
||||
* RTMP extension:
|
||||
* HLS extension:
|
||||
* DASH extension:
|
||||
* Smooth Streaming extension:
|
||||
* RTSP extension:
|
||||
* Decoder extensions (FFmpeg, VP9, AV1, etc.):
|
||||
* MIDI extension:
|
||||
* Leanback extension:
|
||||
* Cast extension:
|
||||
* Test Utilities:
|
||||
* Demo app:
|
||||
* Add `PlaybackSpeedPopUpButton` Composable UI element to be part of
|
||||
`ExtraControls` in `demo-compose`.
|
||||
* Remove deprecated symbols:
|
||||
* Removed deprecated `SegmentDownloader` constructor
|
||||
`SegmentDownloader(MediaItem, Parser<M>, CacheDataSource.Factory,
|
||||
Executor)` and the corresponding constructors in its subclasses
|
||||
`DashDownloader`, `HlsDownloader` and `SsDownloader`.
|
||||
* Removed deprecated `Player.hasNext()`, `Player.hasNextWindow()`. Use
|
||||
`Player.hasNextMediaItem()` instead.
|
||||
* Removed deprecated `Player.next()`. Use `Player.seekToNextMediaItem()`
|
||||
instead.
|
||||
* Removed deprecated `Player.seekToPreviousWindow()`. Use
|
||||
`Player.seekToPreviousMediaItem()` instead.
|
||||
* Removed deprecated `Player.seekToNextWindow()`. Use
|
||||
`Player.seekToNextMediaItem()` instead.
|
||||
* Removed deprecated `BaseAudioProcessor` in `exoplayer` module. Use
|
||||
`BaseAudioProcessor` under `common` module.
|
||||
|
||||
## 1.6
|
||||
|
||||
### 1.6.0 (2025-03-26)
|
||||
|
@ -16,6 +16,7 @@
|
||||
package androidx.media3.cast;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static androidx.media3.common.util.Util.SDK_INT;
|
||||
import static androidx.media3.common.util.Util.castNonNull;
|
||||
import static java.lang.Math.min;
|
||||
@ -166,6 +167,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
private long pendingSeekPositionMs;
|
||||
@Nullable private PositionInfo pendingMediaItemRemovalPosition;
|
||||
private MediaMetadata mediaMetadata;
|
||||
private MediaMetadata playlistMetadata;
|
||||
private DeviceInfo deviceInfo;
|
||||
|
||||
/**
|
||||
@ -268,6 +270,7 @@ public final class CastPlayer extends BasePlayer {
|
||||
playbackState = STATE_IDLE;
|
||||
currentTimeline = CastTimeline.EMPTY_CAST_TIMELINE;
|
||||
mediaMetadata = MediaMetadata.EMPTY;
|
||||
playlistMetadata = MediaMetadata.EMPTY;
|
||||
currentTracks = Tracks.EMPTY;
|
||||
availableCommands = new Commands.Builder().addAll(PERMANENT_AVAILABLE_COMMANDS).build();
|
||||
pendingSeekWindowIndex = C.INDEX_UNSET;
|
||||
@ -656,14 +659,19 @@ public final class CastPlayer extends BasePlayer {
|
||||
|
||||
@Override
|
||||
public MediaMetadata getPlaylistMetadata() {
|
||||
// CastPlayer does not currently support metadata.
|
||||
return MediaMetadata.EMPTY;
|
||||
return playlistMetadata;
|
||||
}
|
||||
|
||||
/** This method is not supported and does nothing. */
|
||||
@Override
|
||||
public void setPlaylistMetadata(MediaMetadata mediaMetadata) {
|
||||
// CastPlayer does not currently support metadata.
|
||||
public void setPlaylistMetadata(MediaMetadata playlistMetadata) {
|
||||
checkNotNull(playlistMetadata);
|
||||
if (playlistMetadata.equals(this.playlistMetadata)) {
|
||||
return;
|
||||
}
|
||||
this.playlistMetadata = playlistMetadata;
|
||||
listeners.sendEvent(
|
||||
EVENT_PLAYLIST_METADATA_CHANGED,
|
||||
listener -> listener.onPlaylistMetadataChanged(this.playlistMetadata));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1800,7 +1800,7 @@ public class CastPlayerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMediaItems_doesNotifyOnMetadataChanged() {
|
||||
public void setMediaItems_doesNotifyOnMediaMetadataChanged() {
|
||||
when(mockRemoteMediaClient.queueJumpToItem(anyInt(), anyLong(), eq(null)))
|
||||
.thenReturn(mockPendingResult);
|
||||
ArgumentCaptor<MediaMetadata> metadataCaptor = ArgumentCaptor.forClass(MediaMetadata.class);
|
||||
@ -1827,7 +1827,7 @@ public class CastPlayerTest {
|
||||
.build());
|
||||
castPlayer.addListener(mockListener);
|
||||
|
||||
MediaMetadata intitalMetadata = castPlayer.getMediaMetadata();
|
||||
MediaMetadata initialMetadata = castPlayer.getMediaMetadata();
|
||||
castPlayer.setMediaItems(firstPlaylist, /* startIndex= */ 0, /* startPositionMs= */ 2000L);
|
||||
updateTimeLine(firstPlaylist, /* mediaQueueItemIds= */ new int[] {1}, /* currentItemId= */ 1);
|
||||
MediaMetadata firstMetadata = castPlayer.getMediaMetadata();
|
||||
@ -1850,7 +1850,7 @@ public class CastPlayerTest {
|
||||
secondPlaylist.get(1).mediaMetadata,
|
||||
secondPlaylist.get(0).mediaMetadata)
|
||||
.inOrder();
|
||||
assertThat(intitalMetadata).isEqualTo(MediaMetadata.EMPTY);
|
||||
assertThat(initialMetadata).isEqualTo(MediaMetadata.EMPTY);
|
||||
assertThat(ImmutableList.of(firstMetadata, secondMetadata, thirdMetadata))
|
||||
.containsExactly(
|
||||
firstPlaylist.get(0).mediaMetadata,
|
||||
@ -1898,6 +1898,35 @@ public class CastPlayerTest {
|
||||
verify(mockListener, never()).onMediaMetadataChanged(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPlaylistMetadata_doesNotifyOnPlaylistMetadataChanged() {
|
||||
castPlayer.addListener(mockListener);
|
||||
|
||||
MediaMetadata metadata = new MediaMetadata.Builder().setArtist("foo").build();
|
||||
|
||||
assertThat(castPlayer.getPlaylistMetadata()).isEqualTo(MediaMetadata.EMPTY);
|
||||
|
||||
castPlayer.setPlaylistMetadata(metadata);
|
||||
|
||||
assertThat(castPlayer.getPlaylistMetadata()).isEqualTo(metadata);
|
||||
|
||||
verify(mockListener).onPlaylistMetadataChanged(metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPlaylistMetadata_equalMetadata_doesNotNotifyOnPlaylistMetadataChanged() {
|
||||
castPlayer.addListener(mockListener);
|
||||
|
||||
MediaMetadata metadata = new MediaMetadata.Builder().setArtist("foo").build();
|
||||
|
||||
castPlayer.setPlaylistMetadata(metadata);
|
||||
castPlayer.setPlaylistMetadata(metadata);
|
||||
|
||||
assertThat(castPlayer.getPlaylistMetadata()).isEqualTo(metadata);
|
||||
|
||||
verify(mockListener, times(1)).onPlaylistMetadataChanged(metadata);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDeviceInfo_returnsCorrectDeviceInfoWithPlaybackTypeRemote() {
|
||||
DeviceInfo deviceInfo = castPlayer.getDeviceInfo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user