mirror of
https://github.com/samsonjs/media.git
synced 2026-04-13 12:35:48 +00:00
Plumb key-rotation and drm-playlist support
With this change, MediaCodecRenderer acquires a session from its DrmSessionManager whenever the DrmInitData in the format changes. The DrmSessionManager is permitted to return the same session if it can be re-used. This plumbing adds support for: 1. Key-rotation, in the case that a key-rotation-aware DrmSessionManager is used. Such an implementation will return the same DrmSession for every aquisition, but will be making use of multiple MediaDrm instances within that session to enable the rotation. 2. Playlists with mixed clear and protected content. One final piece to this will be to have each MediaPeriod provide its own license URL. We could also allow each MediaPeriod to specify the DRM UUID, but switching from PlayReady to Widevine in a playlist seems like quite a hypothetical thing. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=127816046
This commit is contained in:
parent
ba9a610ac2
commit
9304cb3f8f
5 changed files with 171 additions and 96 deletions
|
|
@ -30,42 +30,50 @@
|
|||
{
|
||||
"name": "WV: HDCP not specified",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:d286538032258a1c:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=d286538032258a1c&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP not required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:48fcc369939ac96c:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=48fcc369939ac96c&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:e06c39f1151da3df:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=e06c39f1151da3df&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure video path required (MP4,H264)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:0894c7c8719b28a0:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure video path required (WebM,VP9)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd",
|
||||
"drm": "widevine:0894c7c8719b28a0:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure video path required (MP4,H265)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd",
|
||||
"drm": "widevine:0894c7c8719b28a0:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=0894c7c8719b28a0&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP + secure video path required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:efd045b1eb61888a:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=efd045b1eb61888a&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: 30s license duration (fails at ~30s)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:f9a34cab7b05881a:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=f9a34cab7b05881a&provider=widevine_test"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -75,32 +83,38 @@
|
|||
{
|
||||
"name": "WV: HDCP: None (not required)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_None:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_None&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP: 1.0 required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_V1:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V1&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP: 2.0 required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_V2:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP: 2.1 required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_V2_1:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2_1&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP: 2.2 required",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_V2_2:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_V2_2&provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: HDCP: No digital output",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine:HDCP_NO_DIGTAL_OUTPUT:widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?video_id=HDCP_NO_DIGTAL_OUTPUT&provider=widevine_test"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -126,22 +140,26 @@
|
|||
{
|
||||
"name": "WV: Secure SD & HD (MP4,H264)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure SD (MP4,H264)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure HD (MP4,H264)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_hd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure UHD (MP4,H264)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_uhd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -167,22 +185,26 @@
|
|||
{
|
||||
"name": "WV: Secure SD & HD (WebM,VP9)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure SD (WebM,VP9)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_sd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure HD (WebM,VP9)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_hd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure UHD (WebM,VP9)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/vp9/tears/tears_uhd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -208,22 +230,26 @@
|
|||
{
|
||||
"name": "WV: Secure SD & HD (MP4,H265)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure SD (MP4,H265)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_sd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure HD (MP4,H265)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_hd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
},
|
||||
{
|
||||
"name": "WV: Secure UHD (MP4,H265)",
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/hevc/tears/tears_uhd.mpd",
|
||||
"drm": "widevine::widevine_test"
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -237,7 +263,8 @@
|
|||
{
|
||||
"name": "Super speed (PlayReady)",
|
||||
"uri": "http://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism",
|
||||
"drm": "playready::"
|
||||
"drm_scheme": "playready",
|
||||
"drm_license_url": "http://playready.directtaps.net/pr/svc/rightsmanager.asmx"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -335,7 +362,7 @@
|
|||
"name": "Playlists",
|
||||
"samples": [
|
||||
{
|
||||
"name": "Cats and dogs",
|
||||
"name": "Cats -> Dogs",
|
||||
"playlist": [
|
||||
{
|
||||
"uri": "http://html5demos.com/assets/dizzy.mp4"
|
||||
|
|
@ -346,7 +373,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "Audio then Video",
|
||||
"name": "Audio -> Video",
|
||||
"playlist": [
|
||||
{
|
||||
"uri": "https://storage.googleapis.com/exoplayer-test-media-1/gen-3/screens/dash-vod-single-segment/audio-141.mp4"
|
||||
|
|
@ -355,6 +382,28 @@
|
|||
"uri": "http://storage.googleapis.com/exoplayer-test-media-1/mkv/android-screens-lavf-56.36.100-aac-avc-main-1280x720.mkv"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Clear -> Enc -> Clear -> Enc -> Enc",
|
||||
"drm_scheme": "widevine",
|
||||
"drm_license_url": "https://proxy.uat.widevine.com/proxy?provider=widevine_test",
|
||||
"playlist": [
|
||||
{
|
||||
"uri": "http://html5demos.com/assets/dizzy.mp4"
|
||||
},
|
||||
{
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"
|
||||
},
|
||||
{
|
||||
"uri": "http://html5demos.com/assets/dizzy.mp4"
|
||||
},
|
||||
{
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"
|
||||
},
|
||||
{
|
||||
"uri": "https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears_sd.mpd"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,8 +99,7 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||
SimpleExoPlayer.Id3MetadataListener, MappingTrackSelector.EventListener {
|
||||
|
||||
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
public static final String DRM_CONTENT_ID_EXTRA = "drm_content_id";
|
||||
public static final String DRM_PROVIDER_EXTRA = "drm_provider";
|
||||
public static final String DRM_LICENSE_URL = "drm_license_url";
|
||||
public static final String PREFER_EXTENSION_DECODERS = "prefer_extension_decoders";
|
||||
|
||||
public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
|
||||
|
|
@ -267,13 +266,13 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||
Intent intent = getIntent();
|
||||
if (player == null) {
|
||||
boolean preferExtensionDecoders = intent.getBooleanExtra(PREFER_EXTENSION_DECODERS, false);
|
||||
UUID drmSchemeUuid = (UUID) intent.getSerializableExtra(DRM_SCHEME_UUID_EXTRA);
|
||||
UUID drmSchemeUuid = intent.hasExtra(DRM_SCHEME_UUID_EXTRA)
|
||||
? UUID.fromString(intent.getStringExtra(DRM_SCHEME_UUID_EXTRA)) : null;
|
||||
DrmSessionManager drmSessionManager = null;
|
||||
if (drmSchemeUuid != null) {
|
||||
String drmContentId = intent.getStringExtra(DRM_CONTENT_ID_EXTRA);
|
||||
String drmProvider = intent.getStringExtra(DRM_PROVIDER_EXTRA);
|
||||
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL);
|
||||
try {
|
||||
drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmContentId, drmProvider);
|
||||
drmSessionManager = buildDrmSessionManager(drmSchemeUuid, drmLicenseUrl);
|
||||
} catch (UnsupportedDrmException e) {
|
||||
onUnsupportedDrmError(e);
|
||||
return;
|
||||
|
|
@ -367,17 +366,17 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
|
|||
}
|
||||
}
|
||||
|
||||
private DrmSessionManager buildDrmSessionManager(UUID uuid, String id, String provider)
|
||||
private DrmSessionManager buildDrmSessionManager(UUID uuid, String licenseUrl)
|
||||
throws UnsupportedDrmException {
|
||||
if (Util.SDK_INT < 18) {
|
||||
return null;
|
||||
}
|
||||
if (C.PLAYREADY_UUID.equals(uuid)) {
|
||||
return StreamingDrmSessionManager.newPlayReadyInstance(
|
||||
TestMediaDrmCallback.newPlayReadyInstance(), null, mainHandler, eventLogger);
|
||||
TestMediaDrmCallback.newPlayReadyInstance(licenseUrl), null, mainHandler, eventLogger);
|
||||
} else if (C.WIDEVINE_UUID.equals(uuid)) {
|
||||
return StreamingDrmSessionManager.newWidevineInstance(
|
||||
TestMediaDrmCallback.newWidevineInstance(id, provider), null, mainHandler, eventLogger);
|
||||
TestMediaDrmCallback.newWidevineInstance(licenseUrl), null, mainHandler, eventLogger);
|
||||
} else {
|
||||
throw new UnsupportedDrmException(UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,8 +162,7 @@ public class SampleChooserActivity extends Activity {
|
|||
String uri = null;
|
||||
String extension = null;
|
||||
UUID drmUuid = null;
|
||||
String drmContentId = null;
|
||||
String drmProvider = null;
|
||||
String drmLicenseUrl = null;
|
||||
boolean preferExtensionDecoders = false;
|
||||
ArrayList<UriSample> playlistSamples = null;
|
||||
|
||||
|
|
@ -180,17 +179,22 @@ public class SampleChooserActivity extends Activity {
|
|||
case "extension":
|
||||
extension = reader.nextString();
|
||||
break;
|
||||
case "drm":
|
||||
String[] drmComponents = reader.nextString().split(":", -1);
|
||||
drmUuid = getDrmUuid(drmComponents[0]);
|
||||
drmContentId = drmComponents[1];
|
||||
drmProvider = drmComponents[2];
|
||||
case "drm_scheme":
|
||||
Assertions.checkState(!insidePlaylist, "Invalid attribute on nested item: drm_scheme");
|
||||
drmUuid = getDrmUuid(reader.nextString());
|
||||
break;
|
||||
case "drm_license_url":
|
||||
Assertions.checkState(!insidePlaylist,
|
||||
"Invalid attribute on nested item: drm_license_url");
|
||||
drmLicenseUrl = reader.nextString();
|
||||
break;
|
||||
case "prefer_extension_decoders":
|
||||
Assertions.checkState(!insidePlaylist,
|
||||
"Invalid attribute on nested item: prefer_extension_decoders");
|
||||
preferExtensionDecoders = reader.nextBoolean();
|
||||
break;
|
||||
case "playlist":
|
||||
Assertions.checkState(!insidePlaylist, "Nested playlists are invalid");
|
||||
Assertions.checkState(!insidePlaylist, "Invalid nesting of playlists");
|
||||
playlistSamples = new ArrayList<>();
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
|
|
@ -207,11 +211,11 @@ public class SampleChooserActivity extends Activity {
|
|||
if (playlistSamples != null) {
|
||||
UriSample[] playlistSamplesArray = playlistSamples.toArray(
|
||||
new UriSample[playlistSamples.size()]);
|
||||
return new PlaylistSample(sampleName, drmUuid, drmContentId, drmProvider,
|
||||
preferExtensionDecoders, playlistSamplesArray);
|
||||
return new PlaylistSample(sampleName, drmUuid, drmLicenseUrl, preferExtensionDecoders,
|
||||
playlistSamplesArray);
|
||||
} else {
|
||||
return new UriSample(sampleName, drmUuid, drmContentId, drmProvider,
|
||||
preferExtensionDecoders, uri, extension);
|
||||
return new UriSample(sampleName, drmUuid, drmLicenseUrl, preferExtensionDecoders, uri,
|
||||
extension);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +237,11 @@ public class SampleChooserActivity extends Activity {
|
|||
case "playready":
|
||||
return C.PLAYREADY_UUID;
|
||||
default:
|
||||
throw new ParserException("Unsupported drm type: " + typeString);
|
||||
try {
|
||||
return UUID.fromString(typeString);
|
||||
} catch (RuntimeException e) {
|
||||
throw new ParserException("Unsupported drm type: " + typeString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -331,24 +339,26 @@ public class SampleChooserActivity extends Activity {
|
|||
|
||||
public final String name;
|
||||
public final boolean preferExtensionDecoders;
|
||||
|
||||
// TODO: DRM properties should be specified on UriSample only. This requires changes to
|
||||
// PlayerActivity and beyond to be able to handle playlists containing multiple DRM protected
|
||||
// items that have different DRM properties.
|
||||
public final UUID drmSchemeUuid;
|
||||
public final String drmContentId;
|
||||
public final String drmProvider;
|
||||
public final String drmLicenseUrl;
|
||||
|
||||
public Sample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
|
||||
public Sample(String name, UUID drmSchemeUuid, String drmLicenseUrl,
|
||||
boolean preferExtensionDecoders) {
|
||||
this.name = name;
|
||||
this.drmSchemeUuid = drmSchemeUuid;
|
||||
this.drmContentId = drmContentId;
|
||||
this.drmProvider = drmProvider;
|
||||
this.drmLicenseUrl = drmLicenseUrl;
|
||||
this.preferExtensionDecoders = preferExtensionDecoders;
|
||||
}
|
||||
|
||||
public abstract Intent buildIntent(Context context);
|
||||
public Intent buildIntent(Context context) {
|
||||
Intent intent = new Intent(context, PlayerActivity.class);
|
||||
intent.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders);
|
||||
if (drmSchemeUuid != null) {
|
||||
intent.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid.toString());
|
||||
intent.putExtra(PlayerActivity.DRM_LICENSE_URL, drmLicenseUrl);
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -357,21 +367,16 @@ public class SampleChooserActivity extends Activity {
|
|||
public final String uri;
|
||||
public final String extension;
|
||||
|
||||
public UriSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
|
||||
public UriSample(String name, UUID drmSchemeUuid, String drmLicenseUrl,
|
||||
boolean preferExtensionDecoders, String uri, String extension) {
|
||||
super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders);
|
||||
super(name, drmSchemeUuid, drmLicenseUrl, preferExtensionDecoders);
|
||||
this.uri = uri;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent buildIntent(Context context) {
|
||||
return new Intent(context, PlayerActivity.class)
|
||||
.setAction(PlayerActivity.ACTION_VIEW)
|
||||
.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid)
|
||||
.putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId)
|
||||
.putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider)
|
||||
.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders)
|
||||
return super.buildIntent(context)
|
||||
.setData(Uri.parse(uri))
|
||||
.putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
|
||||
.setAction(PlayerActivity.ACTION_VIEW);
|
||||
|
|
@ -383,9 +388,9 @@ public class SampleChooserActivity extends Activity {
|
|||
|
||||
public final UriSample[] children;
|
||||
|
||||
public PlaylistSample(String name, UUID drmSchemeUuid, String drmContentId, String drmProvider,
|
||||
public PlaylistSample(String name, UUID drmSchemeUuid, String drmLicenseUrl,
|
||||
boolean preferExtensionDecoders, UriSample... children) {
|
||||
super(name, drmSchemeUuid, drmContentId, drmProvider, preferExtensionDecoders);
|
||||
super(name, drmSchemeUuid, drmLicenseUrl, preferExtensionDecoders);
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
|
|
@ -397,12 +402,7 @@ public class SampleChooserActivity extends Activity {
|
|||
uris[i] = children[i].uri;
|
||||
extensions[i] = children[i].extension;
|
||||
}
|
||||
return new Intent(context, PlayerActivity.class)
|
||||
.setAction(PlayerActivity.ACTION_VIEW)
|
||||
.putExtra(PlayerActivity.DRM_SCHEME_UUID_EXTRA, drmSchemeUuid)
|
||||
.putExtra(PlayerActivity.DRM_CONTENT_ID_EXTRA, drmContentId)
|
||||
.putExtra(PlayerActivity.DRM_PROVIDER_EXTRA, drmProvider)
|
||||
.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS, preferExtensionDecoders)
|
||||
return super.buildIntent(context)
|
||||
.putExtra(PlayerActivity.URI_LIST_EXTRA, uris)
|
||||
.putExtra(PlayerActivity.EXTENSION_LIST_EXTRA, extensions)
|
||||
.setAction(PlayerActivity.ACTION_VIEW_LIST);
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ import java.util.UUID;
|
|||
@TargetApi(18)
|
||||
/* package */ final class TestMediaDrmCallback implements MediaDrmCallback {
|
||||
|
||||
private static final String WIDEVINE_BASE_URL = "https://proxy.uat.widevine.com/proxy";
|
||||
private static final String PLAYREADY_BASE_URL =
|
||||
"http://playready.directtaps.net/pr/svc/rightsmanager.asmx";
|
||||
private static final Map<String, String> PLAYREADY_KEY_REQUEST_PROPERTIES;
|
||||
static {
|
||||
HashMap<String, String> keyRequestProperties = new HashMap<>();
|
||||
|
|
@ -53,13 +50,12 @@ import java.util.UUID;
|
|||
private final String defaultUrl;
|
||||
private final Map<String, String> keyRequestProperties;
|
||||
|
||||
public static TestMediaDrmCallback newWidevineInstance(String contentId, String provider) {
|
||||
String defaultUrl = WIDEVINE_BASE_URL + "?video_id=" + contentId + "&provider=" + provider;
|
||||
public static TestMediaDrmCallback newWidevineInstance(String defaultUrl) {
|
||||
return new TestMediaDrmCallback(defaultUrl, null);
|
||||
}
|
||||
|
||||
public static TestMediaDrmCallback newPlayReadyInstance() {
|
||||
return new TestMediaDrmCallback(PLAYREADY_BASE_URL, PLAYREADY_KEY_REQUEST_PROPERTIES);
|
||||
public static TestMediaDrmCallback newPlayReadyInstance(String defaultUrl) {
|
||||
return new TestMediaDrmCallback(defaultUrl, PLAYREADY_KEY_REQUEST_PROPERTIES);
|
||||
}
|
||||
|
||||
private TestMediaDrmCallback(String defaultUrl, Map<String, String> keyRequestProperties) {
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
private Format format;
|
||||
private MediaCodec codec;
|
||||
private DrmSession drmSession;
|
||||
private DrmSession pendingDrmSession;
|
||||
private boolean codecIsAdaptive;
|
||||
private boolean codecNeedsDiscardToSpsWorkaround;
|
||||
private boolean codecNeedsFlushWorkaround;
|
||||
|
|
@ -287,17 +288,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
return;
|
||||
}
|
||||
|
||||
drmSession = pendingDrmSession;
|
||||
String mimeType = format.sampleMimeType;
|
||||
MediaCrypto mediaCrypto = null;
|
||||
boolean drmSessionRequiresSecureDecoder = false;
|
||||
if (format.drmInitData != null) {
|
||||
if (drmSessionManager == null) {
|
||||
throw ExoPlaybackException.createForRenderer(
|
||||
new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
|
||||
}
|
||||
if (drmSession == null) {
|
||||
drmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData);
|
||||
}
|
||||
if (drmSession != null) {
|
||||
int drmSessionState = drmSession.getState();
|
||||
if (drmSessionState == DrmSession.STATE_ERROR) {
|
||||
throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
|
||||
|
|
@ -400,9 +395,19 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
try {
|
||||
releaseCodec();
|
||||
} finally {
|
||||
if (drmSession != null) {
|
||||
drmSessionManager.releaseSession(drmSession);
|
||||
drmSession = null;
|
||||
try {
|
||||
if (drmSession != null) {
|
||||
drmSessionManager.releaseSession(drmSession);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (pendingDrmSession != null && pendingDrmSession != drmSession) {
|
||||
drmSessionManager.releaseSession(pendingDrmSession);
|
||||
}
|
||||
} finally {
|
||||
drmSession = null;
|
||||
pendingDrmSession = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -439,6 +444,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
codec.release();
|
||||
} finally {
|
||||
codec = null;
|
||||
if (drmSession != null && pendingDrmSession != drmSession) {
|
||||
try {
|
||||
drmSessionManager.releaseSession(drmSession);
|
||||
} finally {
|
||||
drmSession = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -700,7 +712,26 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
|
||||
Format oldFormat = format;
|
||||
format = newFormat;
|
||||
if (codec != null && canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) {
|
||||
|
||||
boolean drmInitDataChanged = !Util.areEqual(format.drmInitData, oldFormat == null ? null
|
||||
: oldFormat.drmInitData);
|
||||
if (drmInitDataChanged) {
|
||||
if (format.drmInitData != null) {
|
||||
if (drmSessionManager == null) {
|
||||
throw ExoPlaybackException.createForRenderer(
|
||||
new IllegalStateException("Media requires a DrmSessionManager"), getIndex());
|
||||
}
|
||||
pendingDrmSession = drmSessionManager.acquireSession(Looper.myLooper(), format.drmInitData);
|
||||
if (pendingDrmSession == drmSession) {
|
||||
drmSessionManager.releaseSession(pendingDrmSession);
|
||||
}
|
||||
} else {
|
||||
pendingDrmSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (pendingDrmSession == drmSession && codec != null
|
||||
&& canReconfigureCodec(codec, codecIsAdaptive, oldFormat, format)) {
|
||||
codecReconfigured = true;
|
||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||
codecNeedsAdaptationWorkaroundBuffer = codecNeedsAdaptationWorkaround
|
||||
|
|
|
|||
Loading…
Reference in a new issue