mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
Cast: Add JSON serialization/deserialization for MediaItem
This will allow the Cast extension to reconstruct MediaItems from MediaQueueItems obtained from the receiver's queue. PiperOrigin-RevId: 260554381
This commit is contained in:
parent
46855884f5
commit
8be78d47ac
3 changed files with 181 additions and 23 deletions
|
|
@ -15,41 +15,132 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.ext.cast;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ext.cast.MediaItem.DrmConfiguration;
|
||||
import com.google.android.gms.cast.MediaInfo;
|
||||
import com.google.android.gms.cast.MediaMetadata;
|
||||
import com.google.android.gms.cast.MediaQueueItem;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.UUID;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/** Default {@link MediaItemConverter} implementation. */
|
||||
public final class DefaultMediaItemConverter implements MediaItemConverter {
|
||||
|
||||
private static final String KEY_MEDIA_ITEM = "mediaItem";
|
||||
private static final String KEY_PLAYER_CONFIG = "exoPlayerConfig";
|
||||
private static final String KEY_URI = "uri";
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_MIME_TYPE = "mimeType";
|
||||
private static final String KEY_DRM_CONFIGURATION = "drmConfiguration";
|
||||
private static final String KEY_UUID = "uuid";
|
||||
private static final String KEY_LICENSE_URI = "licenseUri";
|
||||
private static final String KEY_REQUEST_HEADERS = "requestHeaders";
|
||||
|
||||
@Override
|
||||
public MediaItem toMediaItem(MediaQueueItem item) {
|
||||
return getMediaItem(item.getMedia().getCustomData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaQueueItem toMediaQueueItem(MediaItem item) {
|
||||
if (item.mimeType == null) {
|
||||
throw new IllegalArgumentException("The item must specify its mimeType");
|
||||
}
|
||||
MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
|
||||
MediaMetadata metadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
|
||||
if (item.title != null) {
|
||||
movieMetadata.putString(MediaMetadata.KEY_TITLE, item.title);
|
||||
metadata.putString(MediaMetadata.KEY_TITLE, item.title);
|
||||
}
|
||||
MediaInfo mediaInfo =
|
||||
new MediaInfo.Builder(item.uri.toString())
|
||||
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
|
||||
.setContentType(item.mimeType)
|
||||
.setMetadata(movieMetadata)
|
||||
.setMetadata(metadata)
|
||||
.setCustomData(getCustomData(item))
|
||||
.build();
|
||||
return new MediaQueueItem.Builder(mediaInfo).build();
|
||||
}
|
||||
|
||||
private static JSONObject getCustomData(MediaItem item) {
|
||||
JSONObject customData = new JSONObject();
|
||||
// Deserialization.
|
||||
|
||||
MediaItem.DrmConfiguration drmConfiguration = item.drmConfiguration;
|
||||
private static MediaItem getMediaItem(JSONObject customData) {
|
||||
try {
|
||||
JSONObject mediaItemJson = customData.getJSONObject(KEY_MEDIA_ITEM);
|
||||
MediaItem.Builder builder = new MediaItem.Builder();
|
||||
builder.setUri(Uri.parse(mediaItemJson.getString(KEY_URI)));
|
||||
if (mediaItemJson.has(KEY_TITLE)) {
|
||||
builder.setTitle(mediaItemJson.getString(KEY_TITLE));
|
||||
}
|
||||
if (mediaItemJson.has(KEY_MIME_TYPE)) {
|
||||
builder.setMimeType(mediaItemJson.getString(KEY_MIME_TYPE));
|
||||
}
|
||||
if (mediaItemJson.has(KEY_DRM_CONFIGURATION)) {
|
||||
builder.setDrmConfiguration(
|
||||
getDrmConfiguration(mediaItemJson.getJSONObject(KEY_DRM_CONFIGURATION)));
|
||||
}
|
||||
return builder.build();
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static DrmConfiguration getDrmConfiguration(JSONObject json) throws JSONException {
|
||||
UUID uuid = UUID.fromString(json.getString(KEY_UUID));
|
||||
Uri licenseUri = Uri.parse(json.getString(KEY_LICENSE_URI));
|
||||
JSONObject requestHeadersJson = json.getJSONObject(KEY_REQUEST_HEADERS);
|
||||
HashMap<String, String> requestHeaders = new HashMap<>();
|
||||
for (Iterator<String> iterator = requestHeadersJson.keys(); iterator.hasNext(); ) {
|
||||
String key = iterator.next();
|
||||
requestHeaders.put(key, requestHeadersJson.getString(key));
|
||||
}
|
||||
return new DrmConfiguration(uuid, licenseUri, requestHeaders);
|
||||
}
|
||||
|
||||
// Serialization.
|
||||
|
||||
private static JSONObject getCustomData(MediaItem item) {
|
||||
JSONObject json = new JSONObject();
|
||||
try {
|
||||
json.put(KEY_MEDIA_ITEM, getMediaItemJson(item));
|
||||
JSONObject playerConfigJson = getPlayerConfigJson(item);
|
||||
if (playerConfigJson != null) {
|
||||
json.put(KEY_PLAYER_CONFIG, playerConfigJson);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static JSONObject getMediaItemJson(MediaItem item) throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put(KEY_URI, item.uri.toString());
|
||||
json.put(KEY_TITLE, item.title);
|
||||
json.put(KEY_MIME_TYPE, item.mimeType);
|
||||
if (item.drmConfiguration != null) {
|
||||
json.put(KEY_DRM_CONFIGURATION, getDrmConfigurationJson(item.drmConfiguration));
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
private static JSONObject getDrmConfigurationJson(DrmConfiguration drmConfiguration)
|
||||
throws JSONException {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put(KEY_UUID, drmConfiguration.uuid);
|
||||
json.put(KEY_LICENSE_URI, drmConfiguration.licenseUri);
|
||||
json.put(KEY_REQUEST_HEADERS, new JSONObject(drmConfiguration.requestHeaders));
|
||||
return json;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JSONObject getPlayerConfigJson(MediaItem item) throws JSONException {
|
||||
DrmConfiguration drmConfiguration = item.drmConfiguration;
|
||||
if (drmConfiguration == null) {
|
||||
return customData;
|
||||
return null;
|
||||
}
|
||||
|
||||
String drmScheme;
|
||||
|
|
@ -58,24 +149,19 @@ public final class DefaultMediaItemConverter implements MediaItemConverter {
|
|||
} else if (C.PLAYREADY_UUID.equals(drmConfiguration.uuid)) {
|
||||
drmScheme = "playready";
|
||||
} else {
|
||||
return customData;
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject exoPlayerConfig = new JSONObject();
|
||||
try {
|
||||
exoPlayerConfig.put("withCredentials", false);
|
||||
exoPlayerConfig.put("protectionSystem", drmScheme);
|
||||
if (drmConfiguration.licenseUri != null) {
|
||||
exoPlayerConfig.put("licenseUrl", drmConfiguration.licenseUri);
|
||||
}
|
||||
if (!drmConfiguration.requestHeaders.isEmpty()) {
|
||||
exoPlayerConfig.put("headers", new JSONObject(drmConfiguration.requestHeaders));
|
||||
}
|
||||
customData.put("exoPlayerConfig", exoPlayerConfig);
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
JSONObject exoPlayerConfigJson = new JSONObject();
|
||||
exoPlayerConfigJson.put("withCredentials", false);
|
||||
exoPlayerConfigJson.put("protectionSystem", drmScheme);
|
||||
if (drmConfiguration.licenseUri != null) {
|
||||
exoPlayerConfigJson.put("licenseUrl", drmConfiguration.licenseUri);
|
||||
}
|
||||
if (!drmConfiguration.requestHeaders.isEmpty()) {
|
||||
exoPlayerConfigJson.put("headers", new JSONObject(drmConfiguration.requestHeaders));
|
||||
}
|
||||
|
||||
return customData;
|
||||
return exoPlayerConfigJson;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,5 +28,11 @@ public interface MediaItemConverter {
|
|||
*/
|
||||
MediaQueueItem toMediaQueueItem(MediaItem mediaItem);
|
||||
|
||||
// TODO: Add toMediaItem to convert in the opposite direction.
|
||||
/**
|
||||
* Converts a {@link MediaQueueItem} to a {@link MediaItem}.
|
||||
*
|
||||
* @param mediaQueueItem The {@link MediaQueueItem}.
|
||||
* @return The equivalent {@link MediaItem}.
|
||||
*/
|
||||
MediaItem toMediaItem(MediaQueueItem mediaQueueItem);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2019 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.ext.cast.MediaItem.DrmConfiguration;
|
||||
import com.google.android.gms.cast.MediaQueueItem;
|
||||
import java.util.Collections;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Test for {@link DefaultMediaItemConverter}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DefaultMediaItemConverterTest {
|
||||
|
||||
@Test
|
||||
public void serialize_deserialize_minimal() {
|
||||
MediaItem.Builder builder = new MediaItem.Builder();
|
||||
MediaItem item = builder.setUri(Uri.parse("http://example.com")).setMimeType("mime").build();
|
||||
|
||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
||||
MediaQueueItem queueItem = converter.toMediaQueueItem(item);
|
||||
MediaItem reconstructedItem = converter.toMediaItem(queueItem);
|
||||
|
||||
assertThat(reconstructedItem).isEqualTo(item);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serialize_deserialize_complete() {
|
||||
MediaItem.Builder builder = new MediaItem.Builder();
|
||||
MediaItem item =
|
||||
builder
|
||||
.setUri(Uri.parse("http://example.com"))
|
||||
.setTitle("title")
|
||||
.setMimeType("mime")
|
||||
.setDrmConfiguration(
|
||||
new DrmConfiguration(
|
||||
C.WIDEVINE_UUID,
|
||||
Uri.parse("http://license.com"),
|
||||
Collections.singletonMap("key", "value")))
|
||||
.build();
|
||||
|
||||
DefaultMediaItemConverter converter = new DefaultMediaItemConverter();
|
||||
MediaQueueItem queueItem = converter.toMediaQueueItem(item);
|
||||
MediaItem reconstructedItem = converter.toMediaItem(queueItem);
|
||||
|
||||
assertThat(reconstructedItem).isEqualTo(item);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue