Remove cast media item
PiperOrigin-RevId: 301224632
This commit is contained in:
parent
5f8cc71d1b
commit
510f5edd1d
@ -17,8 +17,8 @@ package com.google.android.exoplayer2.castdemo;
|
|||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem.DrmConfiguration;
|
import com.google.android.exoplayer2.MediaMetadata;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -41,60 +41,53 @@ import java.util.List;
|
|||||||
// Clear content.
|
// Clear content.
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri("https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd")
|
.setSourceUri("https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd")
|
||||||
.setTitle("Clear DASH: Tears")
|
.setMediaMetadata(new MediaMetadata.Builder().setTitle("Clear DASH: Tears").build())
|
||||||
.setMimeType(MIME_TYPE_DASH)
|
.setMimeType(MIME_TYPE_DASH)
|
||||||
.build());
|
.build());
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri("https://storage.googleapis.com/shaka-demo-assets/angel-one-hls/hls.m3u8")
|
.setSourceUri("https://storage.googleapis.com/shaka-demo-assets/angel-one-hls/hls.m3u8")
|
||||||
.setTitle("Clear HLS: Angel one")
|
.setMediaMetadata(new MediaMetadata.Builder().setTitle("Clear HLS: Angel one").build())
|
||||||
.setMimeType(MIME_TYPE_HLS)
|
.setMimeType(MIME_TYPE_HLS)
|
||||||
.build());
|
.build());
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri("https://html5demos.com/assets/dizzy.mp4")
|
.setSourceUri("https://html5demos.com/assets/dizzy.mp4")
|
||||||
.setTitle("Clear MP4: Dizzy")
|
.setMediaMetadata(new MediaMetadata.Builder().setTitle("Clear MP4: Dizzy").build())
|
||||||
.setMimeType(MIME_TYPE_VIDEO_MP4)
|
.setMimeType(MIME_TYPE_VIDEO_MP4)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
// DRM content.
|
// DRM content.
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(Uri.parse("https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd"))
|
.setSourceUri(
|
||||||
.setTitle("Widevine DASH cenc: Tears")
|
Uri.parse("https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd"))
|
||||||
|
.setMediaMetadata(
|
||||||
|
new MediaMetadata.Builder().setTitle("Widevine DASH cenc: Tears").build())
|
||||||
.setMimeType(MIME_TYPE_DASH)
|
.setMimeType(MIME_TYPE_DASH)
|
||||||
.setDrmConfiguration(
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
new DrmConfiguration(
|
.setDrmLicenseUri("https://proxy.uat.widevine.com/proxy?provider=widevine_test")
|
||||||
C.WIDEVINE_UUID,
|
|
||||||
Uri.parse("https://proxy.uat.widevine.com/proxy?provider=widevine_test"),
|
|
||||||
Collections.emptyMap()))
|
|
||||||
.build());
|
.build());
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(
|
.setSourceUri(
|
||||||
Uri.parse(
|
"https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1.mpd")
|
||||||
"https://storage.googleapis.com/wvmedia/cbc1/h264/tears/tears_aes_cbc1.mpd"))
|
.setMediaMetadata(
|
||||||
.setTitle("Widevine DASH cbc1: Tears")
|
new MediaMetadata.Builder().setTitle("Widevine DASH cbc1: Tears").build())
|
||||||
.setMimeType(MIME_TYPE_DASH)
|
.setMimeType(MIME_TYPE_DASH)
|
||||||
.setDrmConfiguration(
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
new DrmConfiguration(
|
.setDrmLicenseUri("https://proxy.uat.widevine.com/proxy?provider=widevine_test")
|
||||||
C.WIDEVINE_UUID,
|
|
||||||
Uri.parse("https://proxy.uat.widevine.com/proxy?provider=widevine_test"),
|
|
||||||
Collections.emptyMap()))
|
|
||||||
.build());
|
.build());
|
||||||
samples.add(
|
samples.add(
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(
|
.setSourceUri(
|
||||||
Uri.parse(
|
"https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd")
|
||||||
"https://storage.googleapis.com/wvmedia/cbcs/h264/tears/tears_aes_cbcs.mpd"))
|
.setMediaMetadata(
|
||||||
.setTitle("Widevine DASH cbcs: Tears")
|
new MediaMetadata.Builder().setTitle("Widevine DASH cbcs: Tears").build())
|
||||||
.setMimeType(MIME_TYPE_DASH)
|
.setMimeType(MIME_TYPE_DASH)
|
||||||
.setDrmConfiguration(
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
new DrmConfiguration(
|
.setDrmLicenseUri("https://proxy.uat.widevine.com/proxy?provider=widevine_test")
|
||||||
C.WIDEVINE_UUID,
|
|
||||||
Uri.parse("https://proxy.uat.widevine.com/proxy?provider=widevine_test"),
|
|
||||||
Collections.emptyMap()))
|
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
SAMPLES = Collections.unmodifiableList(samples);
|
SAMPLES = Collections.unmodifiableList(samples);
|
||||||
|
@ -37,10 +37,12 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem;
|
|
||||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||||
import com.google.android.exoplayer2.ui.PlayerView;
|
import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.gms.cast.framework.CastButtonFactory;
|
import com.google.android.gms.cast.framework.CastButtonFactory;
|
||||||
import com.google.android.gms.cast.framework.CastContext;
|
import com.google.android.gms.cast.framework.CastContext;
|
||||||
import com.google.android.gms.dynamite.DynamiteModule;
|
import com.google.android.gms.dynamite.DynamiteModule;
|
||||||
@ -206,9 +208,10 @@ public class MainActivity extends AppCompatActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(QueueItemViewHolder holder, int position) {
|
public void onBindViewHolder(QueueItemViewHolder holder, int position) {
|
||||||
holder.item = playerManager.getItem(position);
|
holder.item = Assertions.checkNotNull(playerManager.getItem(position));
|
||||||
|
|
||||||
TextView view = holder.textView;
|
TextView view = holder.textView;
|
||||||
view.setText(holder.item.title);
|
view.setText(holder.item.mediaMetadata.title);
|
||||||
// TODO: Solve coloring using the theme's ColorStateList.
|
// TODO: Solve coloring using the theme's ColorStateList.
|
||||||
view.setTextColor(
|
view.setTextColor(
|
||||||
ColorUtils.setAlphaComponent(
|
ColorUtils.setAlphaComponent(
|
||||||
@ -305,7 +308,7 @@ public class MainActivity extends AppCompatActivity
|
|||||||
@NonNull
|
@NonNull
|
||||||
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
View view = super.getView(position, convertView, parent);
|
View view = super.getView(position, convertView, parent);
|
||||||
((TextView) view).setText(getItem(position).title);
|
((TextView) view).setText(Util.castNonNull(getItem(position)).mediaMetadata.title);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
package com.google.android.exoplayer2.castdemo;
|
package com.google.android.exoplayer2.castdemo;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.Player.DiscontinuityReason;
|
import com.google.android.exoplayer2.Player.DiscontinuityReason;
|
||||||
import com.google.android.exoplayer2.Player.EventListener;
|
import com.google.android.exoplayer2.Player.EventListener;
|
||||||
@ -28,34 +28,22 @@ import com.google.android.exoplayer2.Player.TimelineChangeReason;
|
|||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
import com.google.android.exoplayer2.Timeline.Period;
|
import com.google.android.exoplayer2.Timeline.Period;
|
||||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|
||||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
|
||||||
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
|
|
||||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
|
||||||
import com.google.android.exoplayer2.ext.cast.CastPlayer;
|
import com.google.android.exoplayer2.ext.cast.CastPlayer;
|
||||||
import com.google.android.exoplayer2.ext.cast.DefaultMediaItemConverter;
|
import com.google.android.exoplayer2.ext.cast.DefaultMediaItemConverter;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem;
|
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItemConverter;
|
import com.google.android.exoplayer2.ext.cast.MediaItemConverter;
|
||||||
import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener;
|
import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener;
|
||||||
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
||||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
|
||||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.ui.PlayerControlView;
|
import com.google.android.exoplayer2.ui.PlayerControlView;
|
||||||
import com.google.android.exoplayer2.ui.PlayerView;
|
import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
|
||||||
import com.google.android.gms.cast.MediaQueueItem;
|
import com.google.android.gms.cast.MediaQueueItem;
|
||||||
import com.google.android.gms.cast.framework.CastContext;
|
import com.google.android.gms.cast.framework.CastContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** Manages players and an internal media queue for the demo app. */
|
/** Manages players and an internal media queue for the demo app. */
|
||||||
/* package */ class PlayerManager implements EventListener, SessionAvailabilityListener {
|
/* package */ class PlayerManager implements EventListener, SessionAvailabilityListener {
|
||||||
@ -78,6 +66,7 @@ import java.util.Map;
|
|||||||
private static final DefaultHttpDataSourceFactory DATA_SOURCE_FACTORY =
|
private static final DefaultHttpDataSourceFactory DATA_SOURCE_FACTORY =
|
||||||
new DefaultHttpDataSourceFactory(USER_AGENT);
|
new DefaultHttpDataSourceFactory(USER_AGENT);
|
||||||
|
|
||||||
|
private final DefaultMediaSourceFactory defaultMediaSourceFactory;
|
||||||
private final PlayerView localPlayerView;
|
private final PlayerView localPlayerView;
|
||||||
private final PlayerControlView castControlView;
|
private final PlayerControlView castControlView;
|
||||||
private final DefaultTrackSelector trackSelector;
|
private final DefaultTrackSelector trackSelector;
|
||||||
@ -117,6 +106,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
trackSelector = new DefaultTrackSelector(context);
|
trackSelector = new DefaultTrackSelector(context);
|
||||||
exoPlayer = new SimpleExoPlayer.Builder(context).setTrackSelector(trackSelector).build();
|
exoPlayer = new SimpleExoPlayer.Builder(context).setTrackSelector(trackSelector).build();
|
||||||
|
defaultMediaSourceFactory = DefaultMediaSourceFactory.newInstance(context, DATA_SOURCE_FACTORY);
|
||||||
exoPlayer.addListener(this);
|
exoPlayer.addListener(this);
|
||||||
localPlayerView.setPlayer(exoPlayer);
|
localPlayerView.setPlayer(exoPlayer);
|
||||||
|
|
||||||
@ -151,7 +141,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public void addItem(MediaItem item) {
|
public void addItem(MediaItem item) {
|
||||||
mediaQueue.add(item);
|
mediaQueue.add(item);
|
||||||
concatenatingMediaSource.addMediaSource(buildMediaSource(item));
|
concatenatingMediaSource.addMediaSource(defaultMediaSourceFactory.createMediaSource(item));
|
||||||
if (currentPlayer == castPlayer) {
|
if (currentPlayer == castPlayer) {
|
||||||
castPlayer.addItems(mediaItemConverter.toMediaQueueItem(item));
|
castPlayer.addItems(mediaItemConverter.toMediaQueueItem(item));
|
||||||
}
|
}
|
||||||
@ -400,62 +390,4 @@ import java.util.Map;
|
|||||||
listener.onQueuePositionChanged(oldIndex, currentItemIndex);
|
listener.onQueuePositionChanged(oldIndex, currentItemIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MediaSource buildMediaSource(MediaItem item) {
|
|
||||||
Uri uri = item.uri;
|
|
||||||
String mimeType = item.mimeType;
|
|
||||||
if (mimeType == null) {
|
|
||||||
throw new IllegalArgumentException("mimeType is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
DrmSessionManager<ExoMediaCrypto> drmSessionManager =
|
|
||||||
DrmSessionManager.getDummyDrmSessionManager();
|
|
||||||
MediaItem.DrmConfiguration drmConfiguration = item.drmConfiguration;
|
|
||||||
if (drmConfiguration != null && Util.SDK_INT >= 18) {
|
|
||||||
String licenseServerUrl =
|
|
||||||
drmConfiguration.licenseUri != null ? drmConfiguration.licenseUri.toString() : "";
|
|
||||||
HttpMediaDrmCallback drmCallback =
|
|
||||||
new HttpMediaDrmCallback(licenseServerUrl, DATA_SOURCE_FACTORY);
|
|
||||||
for (Map.Entry<String, String> requestHeader : drmConfiguration.requestHeaders.entrySet()) {
|
|
||||||
drmCallback.setKeyRequestProperty(requestHeader.getKey(), requestHeader.getValue());
|
|
||||||
}
|
|
||||||
drmSessionManager =
|
|
||||||
new DefaultDrmSessionManager.Builder()
|
|
||||||
.setMultiSession(/* multiSession= */ true)
|
|
||||||
.setUuidAndExoMediaDrmProvider(
|
|
||||||
drmConfiguration.uuid, FrameworkMediaDrm.DEFAULT_PROVIDER)
|
|
||||||
.build(drmCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
MediaSource createdMediaSource;
|
|
||||||
switch (mimeType) {
|
|
||||||
case DemoUtil.MIME_TYPE_SS:
|
|
||||||
createdMediaSource =
|
|
||||||
new SsMediaSource.Factory(DATA_SOURCE_FACTORY)
|
|
||||||
.setDrmSessionManager(drmSessionManager)
|
|
||||||
.createMediaSource(uri);
|
|
||||||
break;
|
|
||||||
case DemoUtil.MIME_TYPE_DASH:
|
|
||||||
createdMediaSource =
|
|
||||||
new DashMediaSource.Factory(DATA_SOURCE_FACTORY)
|
|
||||||
.setDrmSessionManager(drmSessionManager)
|
|
||||||
.createMediaSource(uri);
|
|
||||||
break;
|
|
||||||
case DemoUtil.MIME_TYPE_HLS:
|
|
||||||
createdMediaSource =
|
|
||||||
new HlsMediaSource.Factory(DATA_SOURCE_FACTORY)
|
|
||||||
.setDrmSessionManager(drmSessionManager)
|
|
||||||
.createMediaSource(uri);
|
|
||||||
break;
|
|
||||||
case DemoUtil.MIME_TYPE_VIDEO_MP4:
|
|
||||||
createdMediaSource =
|
|
||||||
new ProgressiveMediaSource.Factory(DATA_SOURCE_FACTORY)
|
|
||||||
.setDrmSessionManager(drmSessionManager)
|
|
||||||
.createMediaSource(uri);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("mimeType is unsupported: " + mimeType);
|
|
||||||
}
|
|
||||||
return createdMediaSource;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ package com.google.android.exoplayer2.ext.cast;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem.DrmConfiguration;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.gms.cast.MediaInfo;
|
import com.google.android.gms.cast.MediaInfo;
|
||||||
import com.google.android.gms.cast.MediaMetadata;
|
import com.google.android.gms.cast.MediaMetadata;
|
||||||
import com.google.android.gms.cast.MediaQueueItem;
|
import com.google.android.gms.cast.MediaQueueItem;
|
||||||
@ -48,17 +49,18 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaQueueItem toMediaQueueItem(MediaItem item) {
|
public MediaQueueItem toMediaQueueItem(MediaItem item) {
|
||||||
if (item.mimeType == null) {
|
Assertions.checkNotNull(item.playbackProperties);
|
||||||
|
if (item.playbackProperties.mimeType == null) {
|
||||||
throw new IllegalArgumentException("The item must specify its mimeType");
|
throw new IllegalArgumentException("The item must specify its mimeType");
|
||||||
}
|
}
|
||||||
MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
|
MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
|
||||||
if (item.title != null) {
|
if (item.mediaMetadata.title != null) {
|
||||||
metadata.putString(MediaMetadata.KEY_TITLE, item.title);
|
metadata.putString(MediaMetadata.KEY_TITLE, item.mediaMetadata.title);
|
||||||
}
|
}
|
||||||
MediaInfo mediaInfo =
|
MediaInfo mediaInfo =
|
||||||
new MediaInfo.Builder(item.uri.toString())
|
new MediaInfo.Builder(item.playbackProperties.sourceUri.toString())
|
||||||
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
||||||
.setContentType(item.mimeType)
|
.setContentType(item.playbackProperties.mimeType)
|
||||||
.setMetadata(metadata)
|
.setMetadata(metadata)
|
||||||
.setCustomData(getCustomData(item))
|
.setCustomData(getCustomData(item))
|
||||||
.build();
|
.build();
|
||||||
@ -71,16 +73,19 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||||||
try {
|
try {
|
||||||
JSONObject mediaItemJson = customData.getJSONObject(KEY_MEDIA_ITEM);
|
JSONObject mediaItemJson = customData.getJSONObject(KEY_MEDIA_ITEM);
|
||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
MediaItem.Builder builder = new MediaItem.Builder();
|
||||||
builder.setUri(Uri.parse(mediaItemJson.getString(KEY_URI)));
|
builder.setSourceUri(Uri.parse(mediaItemJson.getString(KEY_URI)));
|
||||||
if (mediaItemJson.has(KEY_TITLE)) {
|
if (mediaItemJson.has(KEY_TITLE)) {
|
||||||
builder.setTitle(mediaItemJson.getString(KEY_TITLE));
|
com.google.android.exoplayer2.MediaMetadata mediaMetadata =
|
||||||
|
new com.google.android.exoplayer2.MediaMetadata.Builder()
|
||||||
|
.setTitle(mediaItemJson.getString(KEY_TITLE))
|
||||||
|
.build();
|
||||||
|
builder.setMediaMetadata(mediaMetadata);
|
||||||
}
|
}
|
||||||
if (mediaItemJson.has(KEY_MIME_TYPE)) {
|
if (mediaItemJson.has(KEY_MIME_TYPE)) {
|
||||||
builder.setMimeType(mediaItemJson.getString(KEY_MIME_TYPE));
|
builder.setMimeType(mediaItemJson.getString(KEY_MIME_TYPE));
|
||||||
}
|
}
|
||||||
if (mediaItemJson.has(KEY_DRM_CONFIGURATION)) {
|
if (mediaItemJson.has(KEY_DRM_CONFIGURATION)) {
|
||||||
builder.setDrmConfiguration(
|
populateDrmConfiguration(mediaItemJson.getJSONObject(KEY_DRM_CONFIGURATION), builder);
|
||||||
getDrmConfiguration(mediaItemJson.getJSONObject(KEY_DRM_CONFIGURATION)));
|
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
@ -88,25 +93,26 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DrmConfiguration getDrmConfiguration(JSONObject json) throws JSONException {
|
private static void populateDrmConfiguration(JSONObject json, MediaItem.Builder builder)
|
||||||
UUID uuid = UUID.fromString(json.getString(KEY_UUID));
|
throws JSONException {
|
||||||
Uri licenseUri = Uri.parse(json.getString(KEY_LICENSE_URI));
|
builder.setDrmUuid(UUID.fromString(json.getString(KEY_UUID)));
|
||||||
|
builder.setDrmLicenseUri(json.getString(KEY_LICENSE_URI));
|
||||||
JSONObject requestHeadersJson = json.getJSONObject(KEY_REQUEST_HEADERS);
|
JSONObject requestHeadersJson = json.getJSONObject(KEY_REQUEST_HEADERS);
|
||||||
HashMap<String, String> requestHeaders = new HashMap<>();
|
HashMap<String, String> requestHeaders = new HashMap<>();
|
||||||
for (Iterator<String> iterator = requestHeadersJson.keys(); iterator.hasNext(); ) {
|
for (Iterator<String> iterator = requestHeadersJson.keys(); iterator.hasNext(); ) {
|
||||||
String key = iterator.next();
|
String key = iterator.next();
|
||||||
requestHeaders.put(key, requestHeadersJson.getString(key));
|
requestHeaders.put(key, requestHeadersJson.getString(key));
|
||||||
}
|
}
|
||||||
return new DrmConfiguration(uuid, licenseUri, requestHeaders);
|
builder.setDrmLicenseRequestHeaders(requestHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialization.
|
// Serialization.
|
||||||
|
|
||||||
private static JSONObject getCustomData(MediaItem item) {
|
private static JSONObject getCustomData(MediaItem mediaItem) {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
try {
|
try {
|
||||||
json.put(KEY_MEDIA_ITEM, getMediaItemJson(item));
|
json.put(KEY_MEDIA_ITEM, getMediaItemJson(mediaItem));
|
||||||
JSONObject playerConfigJson = getPlayerConfigJson(item);
|
@Nullable JSONObject playerConfigJson = getPlayerConfigJson(mediaItem);
|
||||||
if (playerConfigJson != null) {
|
if (playerConfigJson != null) {
|
||||||
json.put(KEY_PLAYER_CONFIG, playerConfigJson);
|
json.put(KEY_PLAYER_CONFIG, playerConfigJson);
|
||||||
}
|
}
|
||||||
@ -116,18 +122,21 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JSONObject getMediaItemJson(MediaItem item) throws JSONException {
|
private static JSONObject getMediaItemJson(MediaItem mediaItem) throws JSONException {
|
||||||
|
Assertions.checkNotNull(mediaItem.playbackProperties);
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
json.put(KEY_URI, item.uri.toString());
|
json.put(KEY_TITLE, mediaItem.mediaMetadata.title);
|
||||||
json.put(KEY_TITLE, item.title);
|
json.put(KEY_URI, mediaItem.playbackProperties.sourceUri.toString());
|
||||||
json.put(KEY_MIME_TYPE, item.mimeType);
|
json.put(KEY_MIME_TYPE, mediaItem.playbackProperties.mimeType);
|
||||||
if (item.drmConfiguration != null) {
|
if (mediaItem.playbackProperties.drmConfiguration != null) {
|
||||||
json.put(KEY_DRM_CONFIGURATION, getDrmConfigurationJson(item.drmConfiguration));
|
json.put(
|
||||||
|
KEY_DRM_CONFIGURATION,
|
||||||
|
getDrmConfigurationJson(mediaItem.playbackProperties.drmConfiguration));
|
||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JSONObject getDrmConfigurationJson(DrmConfiguration drmConfiguration)
|
private static JSONObject getDrmConfigurationJson(MediaItem.DrmConfiguration drmConfiguration)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
json.put(KEY_UUID, drmConfiguration.uuid);
|
json.put(KEY_UUID, drmConfiguration.uuid);
|
||||||
@ -137,11 +146,12 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static JSONObject getPlayerConfigJson(MediaItem item) throws JSONException {
|
private static JSONObject getPlayerConfigJson(MediaItem mediaItem) throws JSONException {
|
||||||
DrmConfiguration drmConfiguration = item.drmConfiguration;
|
if (mediaItem.playbackProperties == null
|
||||||
if (drmConfiguration == null) {
|
|| mediaItem.playbackProperties.drmConfiguration == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
MediaItem.DrmConfiguration drmConfiguration = mediaItem.playbackProperties.drmConfiguration;
|
||||||
|
|
||||||
String drmScheme;
|
String drmScheme;
|
||||||
if (C.WIDEVINE_UUID.equals(drmConfiguration.uuid)) {
|
if (C.WIDEVINE_UUID.equals(drmConfiguration.uuid)) {
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer2.ext.cast;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
|
||||||
import com.google.android.exoplayer2.util.Util;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/** Representation of a media item. */
|
|
||||||
public final class MediaItem {
|
|
||||||
|
|
||||||
/** A builder for {@link MediaItem} instances. */
|
|
||||||
public static final class Builder {
|
|
||||||
|
|
||||||
@Nullable private Uri uri;
|
|
||||||
@Nullable private String title;
|
|
||||||
@Nullable private String mimeType;
|
|
||||||
@Nullable private DrmConfiguration drmConfiguration;
|
|
||||||
|
|
||||||
/** See {@link MediaItem#uri}. */
|
|
||||||
public Builder setUri(String uri) {
|
|
||||||
return setUri(Uri.parse(uri));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See {@link MediaItem#uri}. */
|
|
||||||
public Builder setUri(Uri uri) {
|
|
||||||
this.uri = uri;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See {@link MediaItem#title}. */
|
|
||||||
public Builder setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See {@link MediaItem#mimeType}. */
|
|
||||||
public Builder setMimeType(String mimeType) {
|
|
||||||
this.mimeType = mimeType;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** See {@link MediaItem#drmConfiguration}. */
|
|
||||||
public Builder setDrmConfiguration(DrmConfiguration drmConfiguration) {
|
|
||||||
this.drmConfiguration = drmConfiguration;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a new {@link MediaItem} instance with the current builder values. */
|
|
||||||
public MediaItem build() {
|
|
||||||
Assertions.checkNotNull(uri);
|
|
||||||
return new MediaItem(uri, title, mimeType, drmConfiguration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DRM configuration for a media item. */
|
|
||||||
public static final class DrmConfiguration {
|
|
||||||
|
|
||||||
/** The UUID of the protection scheme. */
|
|
||||||
public final UUID uuid;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional license server {@link Uri}. If {@code null} then the license server must be
|
|
||||||
* specified by the media.
|
|
||||||
*/
|
|
||||||
@Nullable public final Uri licenseUri;
|
|
||||||
|
|
||||||
/** Headers that should be attached to any license requests. */
|
|
||||||
public final Map<String, String> requestHeaders;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance.
|
|
||||||
*
|
|
||||||
* @param uuid See {@link #uuid}.
|
|
||||||
* @param licenseUri See {@link #licenseUri}.
|
|
||||||
* @param requestHeaders See {@link #requestHeaders}.
|
|
||||||
*/
|
|
||||||
public DrmConfiguration(
|
|
||||||
UUID uuid, @Nullable Uri licenseUri, @Nullable Map<String, String> requestHeaders) {
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.licenseUri = licenseUri;
|
|
||||||
this.requestHeaders =
|
|
||||||
requestHeaders == null
|
|
||||||
? Collections.emptyMap()
|
|
||||||
: Collections.unmodifiableMap(requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@Nullable Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null || getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrmConfiguration other = (DrmConfiguration) obj;
|
|
||||||
return uuid.equals(other.uuid)
|
|
||||||
&& Util.areEqual(licenseUri, other.licenseUri)
|
|
||||||
&& requestHeaders.equals(other.requestHeaders);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = uuid.hashCode();
|
|
||||||
result = 31 * result + (licenseUri != null ? licenseUri.hashCode() : 0);
|
|
||||||
result = 31 * result + requestHeaders.hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The media {@link Uri}. */
|
|
||||||
public final Uri uri;
|
|
||||||
|
|
||||||
/** The title of the item, or {@code null} if unspecified. */
|
|
||||||
@Nullable public final String title;
|
|
||||||
|
|
||||||
/** The mime type for the media, or {@code null} if unspecified. */
|
|
||||||
@Nullable public final String mimeType;
|
|
||||||
|
|
||||||
/** Optional {@link DrmConfiguration} for the media. */
|
|
||||||
@Nullable public final DrmConfiguration drmConfiguration;
|
|
||||||
|
|
||||||
private MediaItem(
|
|
||||||
Uri uri,
|
|
||||||
@Nullable String title,
|
|
||||||
@Nullable String mimeType,
|
|
||||||
@Nullable DrmConfiguration drmConfiguration) {
|
|
||||||
this.uri = uri;
|
|
||||||
this.title = title;
|
|
||||||
this.mimeType = mimeType;
|
|
||||||
this.drmConfiguration = drmConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@Nullable Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj == null || getClass() != obj.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
MediaItem other = (MediaItem) obj;
|
|
||||||
return uri.equals(other.uri)
|
|
||||||
&& Util.areEqual(title, other.title)
|
|
||||||
&& Util.areEqual(mimeType, other.mimeType)
|
|
||||||
&& Util.areEqual(drmConfiguration, other.drmConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = uri.hashCode();
|
|
||||||
result = 31 * result + (title == null ? 0 : title.hashCode());
|
|
||||||
result = 31 * result + (drmConfiguration == null ? 0 : drmConfiguration.hashCode());
|
|
||||||
result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ext.cast;
|
package com.google.android.exoplayer2.ext.cast;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.gms.cast.MediaQueueItem;
|
import com.google.android.gms.cast.MediaQueueItem;
|
||||||
|
|
||||||
/** Converts between {@link MediaItem} and the Cast SDK's {@link MediaQueueItem}. */
|
/** Converts between {@link MediaItem} and the Cast SDK's {@link MediaQueueItem}. */
|
||||||
|
@ -20,7 +20,9 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ext.cast.MediaItem.DrmConfiguration;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
|
import com.google.android.exoplayer2.MediaMetadata;
|
||||||
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.gms.cast.MediaQueueItem;
|
import com.google.android.gms.cast.MediaQueueItem;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -33,7 +35,8 @@ public class DefaultMediaItemConverterTest {
|
|||||||
@Test
|
@Test
|
||||||
public void serialize_deserialize_minimal() {
|
public void serialize_deserialize_minimal() {
|
||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
MediaItem.Builder builder = new MediaItem.Builder();
|
||||||
MediaItem item = builder.setUri(Uri.parse("http://example.com")).setMimeType("mime").build();
|
MediaItem item =
|
||||||
|
builder.setSourceUri("http://example.com").setMimeType(MimeTypes.APPLICATION_MPD).build();
|
||||||
|
|
||||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
||||||
MediaQueueItem queueItem = converter.toMediaQueueItem(item);
|
MediaQueueItem queueItem = converter.toMediaQueueItem(item);
|
||||||
@ -47,14 +50,12 @@ public class DefaultMediaItemConverterTest {
|
|||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
MediaItem.Builder builder = new MediaItem.Builder();
|
||||||
MediaItem item =
|
MediaItem item =
|
||||||
builder
|
builder
|
||||||
.setUri(Uri.parse("http://example.com"))
|
.setSourceUri(Uri.parse("http://example.com"))
|
||||||
.setTitle("title")
|
.setMediaMetadata(new MediaMetadata.Builder().build())
|
||||||
.setMimeType("mime")
|
.setMimeType(MimeTypes.APPLICATION_MPD)
|
||||||
.setDrmConfiguration(
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
new DrmConfiguration(
|
.setDrmLicenseUri("http://license.com")
|
||||||
C.WIDEVINE_UUID,
|
.setDrmLicenseRequestHeaders(Collections.singletonMap("key", "value"))
|
||||||
Uri.parse("http://license.com"),
|
|
||||||
Collections.singletonMap("key", "value")))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.google.android.exoplayer2.ext.cast;
|
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
/** Test for {@link MediaItem}. */
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
|
||||||
public class MediaItemTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void buildMediaItem_doesNotChangeState() {
|
|
||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
|
||||||
MediaItem item1 =
|
|
||||||
builder
|
|
||||||
.setUri(Uri.parse("http://example.com"))
|
|
||||||
.setTitle("title")
|
|
||||||
.setMimeType(MimeTypes.AUDIO_MP4)
|
|
||||||
.build();
|
|
||||||
MediaItem item2 = builder.build();
|
|
||||||
assertThat(item1).isEqualTo(item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void equals_withEqualDrmSchemes_returnsTrue() {
|
|
||||||
MediaItem.Builder builder1 = new MediaItem.Builder();
|
|
||||||
MediaItem mediaItem1 =
|
|
||||||
builder1
|
|
||||||
.setUri(Uri.parse("www.google.com"))
|
|
||||||
.setDrmConfiguration(buildDrmConfiguration(1))
|
|
||||||
.build();
|
|
||||||
MediaItem.Builder builder2 = new MediaItem.Builder();
|
|
||||||
MediaItem mediaItem2 =
|
|
||||||
builder2
|
|
||||||
.setUri(Uri.parse("www.google.com"))
|
|
||||||
.setDrmConfiguration(buildDrmConfiguration(1))
|
|
||||||
.build();
|
|
||||||
assertThat(mediaItem1).isEqualTo(mediaItem2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void equals_withDifferentDrmRequestHeaders_returnsFalse() {
|
|
||||||
MediaItem.Builder builder1 = new MediaItem.Builder();
|
|
||||||
MediaItem mediaItem1 =
|
|
||||||
builder1
|
|
||||||
.setUri(Uri.parse("www.google.com"))
|
|
||||||
.setDrmConfiguration(buildDrmConfiguration(1))
|
|
||||||
.build();
|
|
||||||
MediaItem.Builder builder2 = new MediaItem.Builder();
|
|
||||||
MediaItem mediaItem2 =
|
|
||||||
builder2
|
|
||||||
.setUri(Uri.parse("www.google.com"))
|
|
||||||
.setDrmConfiguration(buildDrmConfiguration(2))
|
|
||||||
.build();
|
|
||||||
assertThat(mediaItem1).isNotEqualTo(mediaItem2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MediaItem.DrmConfiguration buildDrmConfiguration(int seed) {
|
|
||||||
HashMap<String, String> requestHeaders = new HashMap<>();
|
|
||||||
requestHeaders.put("key1", "value1");
|
|
||||||
requestHeaders.put("key2", "value2" + seed);
|
|
||||||
return new MediaItem.DrmConfiguration(
|
|
||||||
C.WIDEVINE_UUID, Uri.parse("www.uri1.com"), requestHeaders);
|
|
||||||
}
|
|
||||||
}
|
|
@ -62,6 +62,7 @@ public final class MediaItem {
|
|||||||
private boolean drmMultiSession;
|
private boolean drmMultiSession;
|
||||||
private List<StreamKey> streamKeys;
|
private List<StreamKey> streamKeys;
|
||||||
@Nullable private Object tag;
|
@Nullable private Object tag;
|
||||||
|
@Nullable private MediaMetadata mediaMetadata;
|
||||||
|
|
||||||
/** Creates a builder. */
|
/** Creates a builder. */
|
||||||
public Builder() {
|
public Builder() {
|
||||||
@ -199,6 +200,12 @@ public final class MediaItem {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the media metadata. */
|
||||||
|
public Builder setMediaMetadata(MediaMetadata mediaMetadata) {
|
||||||
|
this.mediaMetadata = mediaMetadata;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@link MediaItem} instance with the current builder values.
|
* Returns a new {@link MediaItem} instance with the current builder values.
|
||||||
*/
|
*/
|
||||||
@ -218,7 +225,10 @@ public final class MediaItem {
|
|||||||
tag);
|
tag);
|
||||||
mediaId = mediaId != null ? mediaId : sourceUri.toString();
|
mediaId = mediaId != null ? mediaId : sourceUri.toString();
|
||||||
}
|
}
|
||||||
return new MediaItem(Assertions.checkNotNull(mediaId), playbackProperties);
|
return new MediaItem(
|
||||||
|
Assertions.checkNotNull(mediaId),
|
||||||
|
playbackProperties,
|
||||||
|
mediaMetadata != null ? mediaMetadata : new MediaMetadata.Builder().build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,15 +250,7 @@ public final class MediaItem {
|
|||||||
/** Whether the drm configuration is multi session enabled. */
|
/** Whether the drm configuration is multi session enabled. */
|
||||||
public final boolean multiSession;
|
public final boolean multiSession;
|
||||||
|
|
||||||
/**
|
private DrmConfiguration(
|
||||||
* Creates an instance.
|
|
||||||
*
|
|
||||||
* @param uuid See {@link #uuid}.
|
|
||||||
* @param licenseUri See {@link #licenseUri}.
|
|
||||||
* @param requestHeaders See {@link #requestHeaders}.
|
|
||||||
* @param multiSession See {@link #multiSession}.
|
|
||||||
*/
|
|
||||||
public DrmConfiguration(
|
|
||||||
UUID uuid,
|
UUID uuid,
|
||||||
@Nullable Uri licenseUri,
|
@Nullable Uri licenseUri,
|
||||||
Map<String, String> requestHeaders,
|
Map<String, String> requestHeaders,
|
||||||
@ -312,7 +314,7 @@ public final class MediaItem {
|
|||||||
*/
|
*/
|
||||||
@Nullable public final Object tag;
|
@Nullable public final Object tag;
|
||||||
|
|
||||||
public PlaybackProperties(
|
private PlaybackProperties(
|
||||||
Uri sourceUri,
|
Uri sourceUri,
|
||||||
@Nullable String mimeType,
|
@Nullable String mimeType,
|
||||||
@Nullable DrmConfiguration drmConfiguration,
|
@Nullable DrmConfiguration drmConfiguration,
|
||||||
@ -356,12 +358,19 @@ public final class MediaItem {
|
|||||||
/** Identifies the media item. */
|
/** Identifies the media item. */
|
||||||
public final String mediaId;
|
public final String mediaId;
|
||||||
|
|
||||||
/** Optional playback properties. */
|
/** Optional playback properties. Maybe be {@code null} if shared over process boundaries. */
|
||||||
@Nullable public final PlaybackProperties playbackProperties;
|
@Nullable public final PlaybackProperties playbackProperties;
|
||||||
|
|
||||||
private MediaItem(String mediaId, @Nullable PlaybackProperties playbackProperties) {
|
/** The media metadata. */
|
||||||
|
public final MediaMetadata mediaMetadata;
|
||||||
|
|
||||||
|
private MediaItem(
|
||||||
|
String mediaId,
|
||||||
|
@Nullable PlaybackProperties playbackProperties,
|
||||||
|
MediaMetadata mediaMetadata) {
|
||||||
this.mediaId = mediaId;
|
this.mediaId = mediaId;
|
||||||
this.playbackProperties = playbackProperties;
|
this.playbackProperties = playbackProperties;
|
||||||
|
this.mediaMetadata = mediaMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -376,13 +385,15 @@ public final class MediaItem {
|
|||||||
MediaItem other = (MediaItem) o;
|
MediaItem other = (MediaItem) o;
|
||||||
|
|
||||||
return Util.areEqual(mediaId, other.mediaId)
|
return Util.areEqual(mediaId, other.mediaId)
|
||||||
&& Util.areEqual(playbackProperties, other.playbackProperties);
|
&& Util.areEqual(playbackProperties, other.playbackProperties)
|
||||||
|
&& Util.areEqual(mediaMetadata, other.mediaMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = mediaId.hashCode();
|
int result = mediaId.hashCode();
|
||||||
result = 31 * result + (playbackProperties != null ? playbackProperties.hashCode() : 0);
|
result = 31 * result + (playbackProperties != null ? playbackProperties.hashCode() : 0);
|
||||||
|
result = 31 * result + mediaMetadata.hashCode();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
|
||||||
|
/** Metadata of the {@link MediaItem}. */
|
||||||
|
public final class MediaMetadata {
|
||||||
|
|
||||||
|
/** A builder for {@link MediaMetadata} instances. */
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
@Nullable private String title;
|
||||||
|
|
||||||
|
/** Sets the optional title. */
|
||||||
|
public Builder setTitle(@Nullable String title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a new {@link MediaMetadata} instance with the current builder values. */
|
||||||
|
public MediaMetadata build() {
|
||||||
|
return new MediaMetadata(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optional title. */
|
||||||
|
@Nullable public final String title;
|
||||||
|
|
||||||
|
private MediaMetadata(@Nullable String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MediaMetadata other = (MediaMetadata) obj;
|
||||||
|
|
||||||
|
return Util.areEqual(title, other.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return title == null ? 0 : title.hashCode();
|
||||||
|
}
|
||||||
|
}
|
@ -48,6 +48,7 @@ public class MediaItemTest {
|
|||||||
|
|
||||||
assertThat(mediaItem.playbackProperties.sourceUri.toString()).isEqualTo(URI_STRING);
|
assertThat(mediaItem.playbackProperties.sourceUri.toString()).isEqualTo(URI_STRING);
|
||||||
assertThat(mediaItem.mediaId).isEqualTo(URI_STRING);
|
assertThat(mediaItem.mediaId).isEqualTo(URI_STRING);
|
||||||
|
assertThat(mediaItem.mediaMetadata).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -144,4 +145,14 @@ public class MediaItemTest {
|
|||||||
|
|
||||||
assertThat(mediaItem.playbackProperties.tag).isEqualTo(tag);
|
assertThat(mediaItem.playbackProperties.tag).isEqualTo(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builderSetMediaMetadata_setsMetadata() {
|
||||||
|
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setTitle("title").build();
|
||||||
|
|
||||||
|
MediaItem mediaItem =
|
||||||
|
new MediaItem.Builder().setSourceUri(URI_STRING).setMediaMetadata(mediaMetadata).build();
|
||||||
|
|
||||||
|
assertThat(mediaItem.mediaMetadata).isEqualTo(mediaMetadata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
/** Unit test for {@link MediaMetadata}. */
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class MediaMetadataTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builder_minimal_correctDefaults() {
|
||||||
|
MediaMetadata mediaMetadata = new MediaMetadata.Builder().build();
|
||||||
|
|
||||||
|
assertThat(mediaMetadata.title).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builderSetTitle_setsTitle() {
|
||||||
|
String title = "title";
|
||||||
|
|
||||||
|
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setTitle(title).build();
|
||||||
|
|
||||||
|
assertThat(mediaMetadata.title).isEqualTo(title);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user