mirror of
https://github.com/androidx/media.git
synced 2025-05-10 09:12:16 +08:00
Make sure we use the correct mimeType with DRM initialization data.
We were previously using the container format of the media being played as the mimeType generating key requests, but this is not always correct. As an example, where a manifest contains webm streams but specifies initialization data using cenc:pssh elements in the manifest, the media has a webm mimeType, but the DRM initialization data has an mp4 mimeType.
This commit is contained in:
parent
ad7237b5d0
commit
7e2fffe74d
@ -21,6 +21,7 @@ import com.google.android.exoplayer.C;
|
|||||||
import com.google.android.exoplayer.MediaFormat;
|
import com.google.android.exoplayer.MediaFormat;
|
||||||
import com.google.android.exoplayer.ParserException;
|
import com.google.android.exoplayer.ParserException;
|
||||||
import com.google.android.exoplayer.drm.DrmInitData;
|
import com.google.android.exoplayer.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.ChunkIndex;
|
import com.google.android.exoplayer.extractor.ChunkIndex;
|
||||||
import com.google.android.exoplayer.extractor.SeekMap;
|
import com.google.android.exoplayer.extractor.SeekMap;
|
||||||
import com.google.android.exoplayer.extractor.webm.StreamBuilder.ContentEncodingSettings;
|
import com.google.android.exoplayer.extractor.webm.StreamBuilder.ContentEncodingSettings;
|
||||||
@ -237,8 +238,12 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
|
|||||||
assertIndex(DEFAULT_TIMECODE_SCALE, 1);
|
assertIndex(DEFAULT_TIMECODE_SCALE, 1);
|
||||||
DrmInitData drmInitData = extractorOutput.drmInitData;
|
DrmInitData drmInitData = extractorOutput.drmInitData;
|
||||||
assertNotNull(drmInitData);
|
assertNotNull(drmInitData);
|
||||||
android.test.MoreAsserts.assertEquals(TEST_ENCRYPTION_KEY_ID, drmInitData.get(WIDEVINE_UUID));
|
SchemeInitData widevineInitData = drmInitData.get(WIDEVINE_UUID);
|
||||||
android.test.MoreAsserts.assertEquals(TEST_ENCRYPTION_KEY_ID, drmInitData.get(ZERO_UUID));
|
assertEquals(MimeTypes.VIDEO_WEBM, widevineInitData.mimeType);
|
||||||
|
android.test.MoreAsserts.assertEquals(TEST_ENCRYPTION_KEY_ID, widevineInitData.data);
|
||||||
|
SchemeInitData zeroInitData = drmInitData.get(ZERO_UUID);
|
||||||
|
assertEquals(MimeTypes.VIDEO_WEBM, zeroInitData.mimeType);
|
||||||
|
android.test.MoreAsserts.assertEquals(TEST_ENCRYPTION_KEY_ID, zeroInitData.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPrepareThreeCuePoints() throws IOException, InterruptedException {
|
public void testPrepareThreeCuePoints() throws IOException, InterruptedException {
|
||||||
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer;
|
|||||||
|
|
||||||
import com.google.android.exoplayer.SampleSource.SampleSourceReader;
|
import com.google.android.exoplayer.SampleSource.SampleSourceReader;
|
||||||
import com.google.android.exoplayer.drm.DrmInitData;
|
import com.google.android.exoplayer.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
|
||||||
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
@ -273,10 +274,10 @@ public final class FrameworkSampleSource implements SampleSource, SampleSourceRe
|
|||||||
if (psshInfo == null || psshInfo.isEmpty()) {
|
if (psshInfo == null || psshInfo.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
DrmInitData.Mapped drmInitData = new DrmInitData.Mapped(MimeTypes.VIDEO_MP4);
|
DrmInitData.Mapped drmInitData = new DrmInitData.Mapped();
|
||||||
for (UUID uuid : psshInfo.keySet()) {
|
for (UUID uuid : psshInfo.keySet()) {
|
||||||
byte[] psshAtom = PsshAtomUtil.buildPsshAtom(uuid, psshInfo.get(uuid));
|
byte[] psshAtom = PsshAtomUtil.buildPsshAtom(uuid, psshInfo.get(uuid));
|
||||||
drmInitData.put(uuid, psshAtom);
|
drmInitData.put(uuid, new SchemeInitData(MimeTypes.VIDEO_MP4, psshAtom));
|
||||||
}
|
}
|
||||||
return drmInitData;
|
return drmInitData;
|
||||||
}
|
}
|
||||||
|
@ -1054,8 +1054,6 @@ public class DashChunkSource implements ChunkSource, Output {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static DrmInitData getDrmInitData(AdaptationSet adaptationSet) {
|
private static DrmInitData getDrmInitData(AdaptationSet adaptationSet) {
|
||||||
String drmInitMimeType = mimeTypeIsWebm(adaptationSet.representations.get(0).format.mimeType)
|
|
||||||
? MimeTypes.VIDEO_WEBM : MimeTypes.VIDEO_MP4;
|
|
||||||
if (adaptationSet.contentProtections.isEmpty()) {
|
if (adaptationSet.contentProtections.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -1064,7 +1062,7 @@ public class DashChunkSource implements ChunkSource, Output {
|
|||||||
ContentProtection contentProtection = adaptationSet.contentProtections.get(i);
|
ContentProtection contentProtection = adaptationSet.contentProtections.get(i);
|
||||||
if (contentProtection.uuid != null && contentProtection.data != null) {
|
if (contentProtection.uuid != null && contentProtection.data != null) {
|
||||||
if (drmInitData == null) {
|
if (drmInitData == null) {
|
||||||
drmInitData = new DrmInitData.Mapped(drmInitMimeType);
|
drmInitData = new DrmInitData.Mapped();
|
||||||
}
|
}
|
||||||
drmInitData.put(contentProtection.uuid, contentProtection.data);
|
drmInitData.put(contentProtection.uuid, contentProtection.data);
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.dash.mpd;
|
package com.google.android.exoplayer.dash.mpd;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,16 +37,16 @@ public class ContentProtection {
|
|||||||
public final UUID uuid;
|
public final UUID uuid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protection scheme specific data. May be null.
|
* Protection scheme specific initialization data. May be null.
|
||||||
*/
|
*/
|
||||||
public final byte[] data;
|
public final SchemeInitData data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param schemeUriId Identifies the content protection scheme.
|
* @param schemeUriId Identifies the content protection scheme.
|
||||||
* @param uuid The UUID of the protection scheme, if known. May be null.
|
* @param uuid The UUID of the protection scheme, if known. May be null.
|
||||||
* @param data Protection scheme specific initialization data. May be null.
|
* @param data Protection scheme specific initialization data. May be null.
|
||||||
*/
|
*/
|
||||||
public ContentProtection(String schemeUriId, UUID uuid, byte[] data) {
|
public ContentProtection(String schemeUriId, UUID uuid, SchemeInitData data) {
|
||||||
this.schemeUriId = Assertions.checkNotNull(schemeUriId);
|
this.schemeUriId = Assertions.checkNotNull(schemeUriId);
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
@ -64,20 +64,14 @@ public class ContentProtection {
|
|||||||
ContentProtection other = (ContentProtection) obj;
|
ContentProtection other = (ContentProtection) obj;
|
||||||
return schemeUriId.equals(other.schemeUriId)
|
return schemeUriId.equals(other.schemeUriId)
|
||||||
&& Util.areEqual(uuid, other.uuid)
|
&& Util.areEqual(uuid, other.uuid)
|
||||||
&& Arrays.equals(data, other.data);
|
&& Util.areEqual(data, other.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hashCode = 1;
|
int hashCode = schemeUriId.hashCode();
|
||||||
|
hashCode = (37 * hashCode) + (uuid != null ? uuid.hashCode() : 0);
|
||||||
hashCode = hashCode * 37 + schemeUriId.hashCode();
|
hashCode = (37 * hashCode) + (data != null ? data.hashCode() : 0);
|
||||||
if (uuid != null) {
|
|
||||||
hashCode = hashCode * 37 + uuid.hashCode();
|
|
||||||
}
|
|
||||||
if (data != null) {
|
|
||||||
hashCode = hashCode * 37 + Arrays.hashCode(data);
|
|
||||||
}
|
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import com.google.android.exoplayer.dash.mpd.SegmentBase.SegmentList;
|
|||||||
import com.google.android.exoplayer.dash.mpd.SegmentBase.SegmentTemplate;
|
import com.google.android.exoplayer.dash.mpd.SegmentBase.SegmentTemplate;
|
||||||
import com.google.android.exoplayer.dash.mpd.SegmentBase.SegmentTimelineElement;
|
import com.google.android.exoplayer.dash.mpd.SegmentBase.SegmentTimelineElement;
|
||||||
import com.google.android.exoplayer.dash.mpd.SegmentBase.SingleSegmentBase;
|
import com.google.android.exoplayer.dash.mpd.SegmentBase.SingleSegmentBase;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
||||||
import com.google.android.exoplayer.upstream.UriLoadable;
|
import com.google.android.exoplayer.upstream.UriLoadable;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
@ -317,23 +318,24 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
|
|||||||
throws XmlPullParserException, IOException {
|
throws XmlPullParserException, IOException {
|
||||||
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
|
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
|
||||||
UUID uuid = null;
|
UUID uuid = null;
|
||||||
byte[] psshAtom = null;
|
SchemeInitData data = null;
|
||||||
do {
|
do {
|
||||||
xpp.next();
|
xpp.next();
|
||||||
// The cenc:pssh element is defined in 23001-7:2015
|
// The cenc:pssh element is defined in 23001-7:2015
|
||||||
if (ParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) {
|
if (ParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) {
|
||||||
psshAtom = Base64.decode(xpp.getText(), Base64.DEFAULT);
|
data = new SchemeInitData(MimeTypes.VIDEO_MP4,
|
||||||
uuid = PsshAtomUtil.parseUuid(psshAtom);
|
Base64.decode(xpp.getText(), Base64.DEFAULT));
|
||||||
|
uuid = PsshAtomUtil.parseUuid(data.data);
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
throw new ParserException("Invalid pssh atom in cenc:pssh element");
|
throw new ParserException("Invalid pssh atom in cenc:pssh element");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!ParserUtil.isEndTag(xpp, "ContentProtection"));
|
} while (!ParserUtil.isEndTag(xpp, "ContentProtection"));
|
||||||
|
return buildContentProtection(schemeIdUri, uuid, data);
|
||||||
return buildContentProtection(schemeIdUri, uuid, psshAtom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ContentProtection buildContentProtection(String schemeIdUri, UUID uuid, byte[] data) {
|
protected ContentProtection buildContentProtection(String schemeIdUri, UUID uuid,
|
||||||
|
SchemeInitData data) {
|
||||||
return new ContentProtection(schemeIdUri, uuid, data);
|
return new ContentProtection(schemeIdUri, uuid, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,25 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.drm;
|
package com.google.android.exoplayer.drm;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
|
|
||||||
import android.media.MediaDrm;
|
import android.media.MediaDrm;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates initialization data required by a {@link MediaDrm} instance.
|
* Encapsulates initialization data required by a {@link MediaDrm} instances.
|
||||||
*/
|
*/
|
||||||
public abstract class DrmInitData {
|
public interface DrmInitData {
|
||||||
|
|
||||||
/**
|
|
||||||
* The container mime type.
|
|
||||||
*/
|
|
||||||
public final String mimeType;
|
|
||||||
|
|
||||||
public DrmInitData(String mimeType) {
|
|
||||||
this.mimeType = mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves initialization data for a given DRM scheme, specified by its UUID.
|
* Retrieves initialization data for a given DRM scheme, specified by its UUID.
|
||||||
@ -41,22 +35,21 @@ public abstract class DrmInitData {
|
|||||||
* @param schemeUuid The DRM scheme's UUID.
|
* @param schemeUuid The DRM scheme's UUID.
|
||||||
* @return The initialization data for the scheme, or null if the scheme is not supported.
|
* @return The initialization data for the scheme, or null if the scheme is not supported.
|
||||||
*/
|
*/
|
||||||
public abstract byte[] get(UUID schemeUuid);
|
public abstract SchemeInitData get(UUID schemeUuid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link DrmInitData} implementation that maps UUID onto scheme specific data.
|
* A {@link DrmInitData} implementation that maps UUID onto scheme specific data.
|
||||||
*/
|
*/
|
||||||
public static final class Mapped extends DrmInitData {
|
public static final class Mapped implements DrmInitData {
|
||||||
|
|
||||||
private final Map<UUID, byte[]> schemeData;
|
private final Map<UUID, SchemeInitData> schemeData;
|
||||||
|
|
||||||
public Mapped(String mimeType) {
|
public Mapped() {
|
||||||
super(mimeType);
|
|
||||||
schemeData = new HashMap<>();
|
schemeData = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(UUID schemeUuid) {
|
public SchemeInitData get(UUID schemeUuid) {
|
||||||
return schemeData.get(schemeUuid);
|
return schemeData.get(schemeUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,10 +57,10 @@ public abstract class DrmInitData {
|
|||||||
* Inserts scheme specific initialization data.
|
* Inserts scheme specific initialization data.
|
||||||
*
|
*
|
||||||
* @param schemeUuid The scheme UUID.
|
* @param schemeUuid The scheme UUID.
|
||||||
* @param data The corresponding initialization data.
|
* @param schemeInitData The corresponding initialization data.
|
||||||
*/
|
*/
|
||||||
public void put(UUID schemeUuid, byte[] data) {
|
public void put(UUID schemeUuid, SchemeInitData schemeInitData) {
|
||||||
schemeData.put(schemeUuid, data);
|
schemeData.put(schemeUuid, schemeInitData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -75,20 +68,62 @@ public abstract class DrmInitData {
|
|||||||
/**
|
/**
|
||||||
* A {@link DrmInitData} implementation that returns the same initialization data for all schemes.
|
* A {@link DrmInitData} implementation that returns the same initialization data for all schemes.
|
||||||
*/
|
*/
|
||||||
public static final class Universal extends DrmInitData {
|
public static final class Universal implements DrmInitData {
|
||||||
|
|
||||||
private byte[] data;
|
private SchemeInitData data;
|
||||||
|
|
||||||
public Universal(String mimeType, byte[] data) {
|
public Universal(SchemeInitData data) {
|
||||||
super(mimeType);
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] get(UUID schemeUuid) {
|
public SchemeInitData get(UUID schemeUuid) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scheme initialization data.
|
||||||
|
*/
|
||||||
|
public static final class SchemeInitData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mimeType of {@link #data}.
|
||||||
|
*/
|
||||||
|
public final String mimeType;
|
||||||
|
/**
|
||||||
|
* The initialization data.
|
||||||
|
*/
|
||||||
|
public final byte[] data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mimeType The mimeType of the initialization data.
|
||||||
|
* @param data The initialization data.
|
||||||
|
*/
|
||||||
|
public SchemeInitData(String mimeType, byte[] data) {
|
||||||
|
this.mimeType = Assertions.checkNotNull(mimeType);
|
||||||
|
this.data = Assertions.checkNotNull(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof SchemeInitData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SchemeInitData other = (SchemeInitData) obj;
|
||||||
|
return mimeType.equals(other.mimeType) && Arrays.equals(data, other.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mimeType.hashCode() + 31 * Arrays.hashCode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.drm;
|
package com.google.android.exoplayer.drm;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
import com.google.android.exoplayer.extractor.mp4.PsshAtomUtil;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
@ -103,8 +104,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
|
|||||||
private int state;
|
private int state;
|
||||||
private MediaCrypto mediaCrypto;
|
private MediaCrypto mediaCrypto;
|
||||||
private Exception lastException;
|
private Exception lastException;
|
||||||
private String mimeType;
|
private SchemeInitData schemeInitData;
|
||||||
private byte[] schemeData;
|
|
||||||
private byte[] sessionId;
|
private byte[] sessionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -273,20 +273,19 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
|
|||||||
requestHandlerThread.start();
|
requestHandlerThread.start();
|
||||||
postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper());
|
postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper());
|
||||||
}
|
}
|
||||||
if (schemeData == null) {
|
if (schemeInitData == null) {
|
||||||
mimeType = drmInitData.mimeType;
|
schemeInitData = drmInitData.get(uuid);
|
||||||
schemeData = drmInitData.get(uuid);
|
if (schemeInitData == null) {
|
||||||
if (schemeData == null) {
|
|
||||||
onError(new IllegalStateException("Media does not support uuid: " + uuid));
|
onError(new IllegalStateException("Media does not support uuid: " + uuid));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Util.SDK_INT < 21) {
|
if (Util.SDK_INT < 21) {
|
||||||
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
|
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
|
||||||
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeData, WIDEVINE_UUID);
|
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData.data, WIDEVINE_UUID);
|
||||||
if (psshData == null) {
|
if (psshData == null) {
|
||||||
// Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
|
// Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
|
||||||
} else {
|
} else {
|
||||||
schemeData = psshData;
|
schemeInitData = new SchemeInitData(schemeInitData.mimeType, psshData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,7 +306,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
|
|||||||
postRequestHandler = null;
|
postRequestHandler = null;
|
||||||
requestHandlerThread.quit();
|
requestHandlerThread.quit();
|
||||||
requestHandlerThread = null;
|
requestHandlerThread = null;
|
||||||
schemeData = null;
|
schemeInitData = null;
|
||||||
mediaCrypto = null;
|
mediaCrypto = null;
|
||||||
lastException = null;
|
lastException = null;
|
||||||
if (sessionId != null) {
|
if (sessionId != null) {
|
||||||
@ -369,7 +368,7 @@ public class StreamingDrmSessionManager implements DrmSessionManager {
|
|||||||
private void postKeyRequest() {
|
private void postKeyRequest() {
|
||||||
KeyRequest keyRequest;
|
KeyRequest keyRequest;
|
||||||
try {
|
try {
|
||||||
keyRequest = mediaDrm.getKeyRequest(sessionId, schemeData, mimeType,
|
keyRequest = mediaDrm.getKeyRequest(sessionId, schemeInitData.data, schemeInitData.mimeType,
|
||||||
MediaDrm.KEY_TYPE_STREAMING, optionalKeyRequestParameters);
|
MediaDrm.KEY_TYPE_STREAMING, optionalKeyRequestParameters);
|
||||||
postRequestHandler.obtainMessage(MSG_KEYS, keyRequest).sendToTarget();
|
postRequestHandler.obtainMessage(MSG_KEYS, keyRequest).sendToTarget();
|
||||||
} catch (NotProvisionedException e) {
|
} catch (NotProvisionedException e) {
|
||||||
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer.extractor.mp4;
|
|||||||
import com.google.android.exoplayer.C;
|
import com.google.android.exoplayer.C;
|
||||||
import com.google.android.exoplayer.ParserException;
|
import com.google.android.exoplayer.ParserException;
|
||||||
import com.google.android.exoplayer.drm.DrmInitData;
|
import com.google.android.exoplayer.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.ChunkIndex;
|
import com.google.android.exoplayer.extractor.ChunkIndex;
|
||||||
import com.google.android.exoplayer.extractor.Extractor;
|
import com.google.android.exoplayer.extractor.Extractor;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||||
@ -292,10 +293,11 @@ public final class FragmentedMp4Extractor implements Extractor {
|
|||||||
LeafAtom child = moovChildren.get(i);
|
LeafAtom child = moovChildren.get(i);
|
||||||
if (child.type == Atom.TYPE_pssh) {
|
if (child.type == Atom.TYPE_pssh) {
|
||||||
if (drmInitData == null) {
|
if (drmInitData == null) {
|
||||||
drmInitData = new DrmInitData.Mapped(MimeTypes.VIDEO_MP4);
|
drmInitData = new DrmInitData.Mapped();
|
||||||
}
|
}
|
||||||
byte[] psshData = child.data.data;
|
byte[] psshData = child.data.data;
|
||||||
drmInitData.put(PsshAtomUtil.parseUuid(psshData), psshData);
|
drmInitData.put(PsshAtomUtil.parseUuid(psshData),
|
||||||
|
new SchemeInitData(MimeTypes.VIDEO_MP4, psshData));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (drmInitData != null) {
|
if (drmInitData != null) {
|
||||||
|
@ -19,6 +19,7 @@ import com.google.android.exoplayer.C;
|
|||||||
import com.google.android.exoplayer.MediaFormat;
|
import com.google.android.exoplayer.MediaFormat;
|
||||||
import com.google.android.exoplayer.ParserException;
|
import com.google.android.exoplayer.ParserException;
|
||||||
import com.google.android.exoplayer.drm.DrmInitData;
|
import com.google.android.exoplayer.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.ChunkIndex;
|
import com.google.android.exoplayer.extractor.ChunkIndex;
|
||||||
import com.google.android.exoplayer.extractor.Extractor;
|
import com.google.android.exoplayer.extractor.Extractor;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||||
@ -450,8 +451,8 @@ public final class WebmExtractor implements Extractor {
|
|||||||
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
|
throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
|
||||||
}
|
}
|
||||||
if (!sentDrmInitData) {
|
if (!sentDrmInitData) {
|
||||||
extractorOutput.drmInitData(
|
extractorOutput.drmInitData(new DrmInitData.Universal(
|
||||||
new DrmInitData.Universal(MimeTypes.VIDEO_WEBM, currentTrack.encryptionKeyId));
|
new SchemeInitData(MimeTypes.VIDEO_WEBM, currentTrack.encryptionKeyId)));
|
||||||
sentDrmInitData = true;
|
sentDrmInitData = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer.chunk.FormatEvaluator;
|
|||||||
import com.google.android.exoplayer.chunk.FormatEvaluator.Evaluation;
|
import com.google.android.exoplayer.chunk.FormatEvaluator.Evaluation;
|
||||||
import com.google.android.exoplayer.chunk.MediaChunk;
|
import com.google.android.exoplayer.chunk.MediaChunk;
|
||||||
import com.google.android.exoplayer.drm.DrmInitData;
|
import com.google.android.exoplayer.drm.DrmInitData;
|
||||||
|
import com.google.android.exoplayer.drm.DrmInitData.SchemeInitData;
|
||||||
import com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor;
|
import com.google.android.exoplayer.extractor.mp4.FragmentedMp4Extractor;
|
||||||
import com.google.android.exoplayer.extractor.mp4.Track;
|
import com.google.android.exoplayer.extractor.mp4.Track;
|
||||||
import com.google.android.exoplayer.extractor.mp4.TrackEncryptionBox;
|
import com.google.android.exoplayer.extractor.mp4.TrackEncryptionBox;
|
||||||
@ -144,8 +145,9 @@ public class SmoothStreamingChunkSource implements ChunkSource,
|
|||||||
byte[] keyId = getProtectionElementKeyId(protectionElement.data);
|
byte[] keyId = getProtectionElementKeyId(protectionElement.data);
|
||||||
trackEncryptionBoxes = new TrackEncryptionBox[1];
|
trackEncryptionBoxes = new TrackEncryptionBox[1];
|
||||||
trackEncryptionBoxes[0] = new TrackEncryptionBox(true, INITIALIZATION_VECTOR_SIZE, keyId);
|
trackEncryptionBoxes[0] = new TrackEncryptionBox(true, INITIALIZATION_VECTOR_SIZE, keyId);
|
||||||
drmInitData = new DrmInitData.Mapped(MimeTypes.VIDEO_MP4);
|
drmInitData = new DrmInitData.Mapped();
|
||||||
drmInitData.put(protectionElement.uuid, protectionElement.data);
|
drmInitData.put(protectionElement.uuid,
|
||||||
|
new SchemeInitData(MimeTypes.VIDEO_MP4, protectionElement.data));
|
||||||
} else {
|
} else {
|
||||||
trackEncryptionBoxes = null;
|
trackEncryptionBoxes = null;
|
||||||
drmInitData = null;
|
drmInitData = null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user