com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil Java Examples

The following examples show how to use com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DefaultDrmSessionManager.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Extracts {@link SchemeData} suitable for the given DRM scheme {@link UUID}.
 *
 * @param drmInitData The {@link DrmInitData} from which to extract the {@link SchemeData}.
 * @param uuid The UUID.
 * @param allowMissingData Whether a {@link SchemeData} with null {@link SchemeData#data} may be
 *     returned.
 * @return The extracted {@link SchemeData}, or null if no suitable data is present.
 */
private static SchemeData getSchemeData(DrmInitData drmInitData, UUID uuid,
    boolean allowMissingData) {
  // Look for matching scheme data (matching the Common PSSH box for ClearKey).
  List<SchemeData> matchingSchemeDatas = new ArrayList<>(drmInitData.schemeDataCount);
  for (int i = 0; i < drmInitData.schemeDataCount; i++) {
    SchemeData schemeData = drmInitData.get(i);
    boolean uuidMatches = schemeData.matches(uuid)
        || (C.CLEARKEY_UUID.equals(uuid) && schemeData.matches(C.COMMON_PSSH_UUID));
    if (uuidMatches && (schemeData.data != null || allowMissingData)) {
      matchingSchemeDatas.add(schemeData);
    }
  }

  if (matchingSchemeDatas.isEmpty()) {
    return null;
  }

  // For Widevine PSSH boxes, prefer V1 boxes from API 23 and V0 before.
  if (C.WIDEVINE_UUID.equals(uuid)) {
    for (int i = 0; i < matchingSchemeDatas.size(); i++) {
      SchemeData matchingSchemeData = matchingSchemeDatas.get(i);
      int version = matchingSchemeData.hasData()
          ? PsshAtomUtil.parseVersion(matchingSchemeData.data) : -1;
      if (Util.SDK_INT < 23 && version == 0) {
        return matchingSchemeData;
      } else if (Util.SDK_INT >= 23 && version == 1) {
        return matchingSchemeData;
      }
    }
  }

  // If we don't have any special handling, prefer the first matching scheme data.
  return matchingSchemeDatas.get(0);
}
 
Example #2
Source File: FrameworkMediaDrm.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
    HashMap<String, String> optionalParameters) throws NotProvisionedException {

  // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
  // devices also required data to be extracted from the PSSH atom for PlayReady.
  if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
      || (C.PLAYREADY_UUID.equals(uuid)
          && "Amazon".equals(Util.MANUFACTURER)
          && ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
              || "AFTS".equals(Util.MODEL) // Fire TV Gen 2
              || "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
    byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(init, uuid);
    if (psshData == null) {
      // Extraction failed. schemeData isn't a PSSH atom, so leave it unchanged.
    } else {
      init = psshData;
    }
  }

  // Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
  if (Util.SDK_INT < 26
      && C.CLEARKEY_UUID.equals(uuid)
      && (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
    mimeType = CENC_SCHEME_MIME_TYPE;
  }

  final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
      optionalParameters);

  byte[] requestData = request.getData();
  if (C.CLEARKEY_UUID.equals(uuid)) {
    requestData = ClearKeyUtil.adjustRequestData(requestData);
  }

  return new DefaultKeyRequest(requestData, request.getDefaultUrl());
}
 
Example #3
Source File: FrameworkMediaDrm.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private static byte[] adjustRequestInitData(UUID uuid, byte[] initData) {
  // TODO: Add API level check once [Internal ref: b/112142048] is fixed.
  if (C.PLAYREADY_UUID.equals(uuid)) {
    byte[] schemeSpecificData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (schemeSpecificData == null) {
      // The init data is not contained in a pssh box.
      schemeSpecificData = initData;
    }
    initData =
        PsshAtomUtil.buildPsshAtom(
            C.PLAYREADY_UUID, addLaUrlAttributeIfMissing(schemeSpecificData));
  }

  // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
  // devices also required data to be extracted from the PSSH atom for PlayReady.
  if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
      || (C.PLAYREADY_UUID.equals(uuid)
          && "Amazon".equals(Util.MANUFACTURER)
          && ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
              || "AFTS".equals(Util.MODEL) // Fire TV Gen 2
              || "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
    byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (psshData != null) {
      // Extraction succeeded, so return the extracted data.
      return psshData;
    }
  }
  return initData;
}
 
Example #4
Source File: DefaultDrmSessionManager.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Extracts {@link SchemeData} suitable for the given DRM scheme {@link UUID}.
 *
 * @param drmInitData The {@link DrmInitData} from which to extract the {@link SchemeData}.
 * @param uuid The UUID.
 * @param allowMissingData Whether a {@link SchemeData} with null {@link SchemeData#data} may be
 *     returned.
 * @return The extracted {@link SchemeData}, or null if no suitable data is present.
 */
private static SchemeData getSchemeData(DrmInitData drmInitData, UUID uuid,
    boolean allowMissingData) {
  // Look for matching scheme data (matching the Common PSSH box for ClearKey).
  List<SchemeData> matchingSchemeDatas = new ArrayList<>(drmInitData.schemeDataCount);
  for (int i = 0; i < drmInitData.schemeDataCount; i++) {
    SchemeData schemeData = drmInitData.get(i);
    boolean uuidMatches = schemeData.matches(uuid)
        || (C.CLEARKEY_UUID.equals(uuid) && schemeData.matches(C.COMMON_PSSH_UUID));
    if (uuidMatches && (schemeData.data != null || allowMissingData)) {
      matchingSchemeDatas.add(schemeData);
    }
  }

  if (matchingSchemeDatas.isEmpty()) {
    return null;
  }

  // For Widevine PSSH boxes, prefer V1 boxes from API 23 and V0 before.
  if (C.WIDEVINE_UUID.equals(uuid)) {
    for (int i = 0; i < matchingSchemeDatas.size(); i++) {
      SchemeData matchingSchemeData = matchingSchemeDatas.get(i);
      int version = matchingSchemeData.hasData()
          ? PsshAtomUtil.parseVersion(matchingSchemeData.data) : -1;
      if (Util.SDK_INT < 23 && version == 0) {
        return matchingSchemeData;
      } else if (Util.SDK_INT >= 23 && version == 1) {
        return matchingSchemeData;
      }
    }
  }

  // If we don't have any special handling, prefer the first matching scheme data.
  return matchingSchemeDatas.get(0);
}
 
Example #5
Source File: FrameworkMediaDrm.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public KeyRequest getKeyRequest(byte[] scope, byte[] init, String mimeType, int keyType,
    HashMap<String, String> optionalParameters) throws NotProvisionedException {

  // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
  // devices also required data to be extracted from the PSSH atom for PlayReady.
  if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
      || (C.PLAYREADY_UUID.equals(uuid)
          && "Amazon".equals(Util.MANUFACTURER)
          && ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
              || "AFTS".equals(Util.MODEL) // Fire TV Gen 2
              || "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
    byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(init, uuid);
    if (psshData == null) {
      // Extraction failed. schemeData isn't a PSSH atom, so leave it unchanged.
    } else {
      init = psshData;
    }
  }

  // Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
  if (Util.SDK_INT < 26
      && C.CLEARKEY_UUID.equals(uuid)
      && (MimeTypes.VIDEO_MP4.equals(mimeType) || MimeTypes.AUDIO_MP4.equals(mimeType))) {
    mimeType = CENC_SCHEME_MIME_TYPE;
  }

  final MediaDrm.KeyRequest request = mediaDrm.getKeyRequest(scope, init, mimeType, keyType,
      optionalParameters);

  byte[] requestData = request.getData();
  if (C.CLEARKEY_UUID.equals(uuid)) {
    requestData = ClearKeyUtil.adjustRequestData(requestData);
  }

  return new DefaultKeyRequest(requestData, request.getDefaultUrl());
}
 
Example #6
Source File: FrameworkMediaDrm.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static byte[] adjustRequestInitData(UUID uuid, byte[] initData) {
  // TODO: Add API level check once [Internal ref: b/112142048] is fixed.
  if (C.PLAYREADY_UUID.equals(uuid)) {
    byte[] schemeSpecificData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (schemeSpecificData == null) {
      // The init data is not contained in a pssh box.
      schemeSpecificData = initData;
    }
    initData =
        PsshAtomUtil.buildPsshAtom(
            C.PLAYREADY_UUID, addLaUrlAttributeIfMissing(schemeSpecificData));
  }

  // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
  // devices also required data to be extracted from the PSSH atom for PlayReady.
  if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
      || (C.PLAYREADY_UUID.equals(uuid)
          && "Amazon".equals(Util.MANUFACTURER)
          && ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
              || "AFTS".equals(Util.MODEL) // Fire TV Gen 2
              || "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
    byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (psshData != null) {
      // Extraction succeeded, so return the extracted data.
      return psshData;
    }
  }
  return initData;
}
 
Example #7
Source File: FrameworkMediaDrm.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private static byte[] adjustRequestInitData(UUID uuid, byte[] initData) {
  // TODO: Add API level check once [Internal ref: b/112142048] is fixed.
  if (C.PLAYREADY_UUID.equals(uuid)) {
    byte[] schemeSpecificData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (schemeSpecificData == null) {
      // The init data is not contained in a pssh box.
      schemeSpecificData = initData;
    }
    initData =
        PsshAtomUtil.buildPsshAtom(
            C.PLAYREADY_UUID, addLaUrlAttributeIfMissing(schemeSpecificData));
  }

  // Prior to L the Widevine CDM required data to be extracted from the PSSH atom. Some Amazon
  // devices also required data to be extracted from the PSSH atom for PlayReady.
  if ((Util.SDK_INT < 21 && C.WIDEVINE_UUID.equals(uuid))
      || (C.PLAYREADY_UUID.equals(uuid)
          && "Amazon".equals(Util.MANUFACTURER)
          && ("AFTB".equals(Util.MODEL) // Fire TV Gen 1
              || "AFTS".equals(Util.MODEL) // Fire TV Gen 2
              || "AFTM".equals(Util.MODEL)))) { // Fire TV Stick Gen 1
    byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(initData, uuid);
    if (psshData != null) {
      // Extraction succeeded, so return the extracted data.
      return psshData;
    }
  }
  return initData;
}
 
Example #8
Source File: DashManifestParser.java    From K-Sonic with MIT License 5 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return {@link SchemeData} parsed from the ContentProtection element, or null if the element is
 *     unsupported.
 */
protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullParserException,
    IOException {
  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  boolean isPlayReady = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95".equals(schemeIdUri);
  byte[] data = null;
  UUID uuid = null;
  boolean requiresSecureDecoder = false;
  do {
    xpp.next();
    if (data == null && XmlPullParserUtil.isStartTag(xpp, "cenc:pssh")
        && xpp.next() == XmlPullParser.TEXT) {
      // The cenc:pssh element is defined in 23001-7:2015.
      data = Base64.decode(xpp.getText(), Base64.DEFAULT);
      uuid = PsshAtomUtil.parseUuid(data);
      if (uuid == null) {
        Log.w(TAG, "Skipping malformed cenc:pssh data");
        data = null;
      }
    } else if (data == null && isPlayReady && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
        && xpp.next() == XmlPullParser.TEXT) {
      // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
      data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID,
          Base64.decode(xpp.getText(), Base64.DEFAULT));
      uuid = C.PLAYREADY_UUID;
    } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
      String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
      requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  return data != null ? new SchemeData(uuid, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
      : null;
}
 
Example #9
Source File: SsManifestParser.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(uuid, PsshAtomUtil.buildPsshAtom(uuid, initData));
}
 
Example #10
Source File: SsManifestParser.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(
      uuid, PsshAtomUtil.buildPsshAtom(uuid, initData), buildTrackEncryptionBoxes(initData));
}
 
Example #11
Source File: DashManifestParser.java    From Telegram with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
 *     Either or both may be null, depending on the ContentProtection element being parsed.
 */
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
    throws XmlPullParserException, IOException {
  String schemeType = null;
  String licenseServerUrl = null;
  byte[] data = null;
  UUID uuid = null;
  boolean requiresSecureDecoder = false;

  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  if (schemeIdUri != null) {
    switch (Util.toLowerInvariant(schemeIdUri)) {
      case "urn:mpeg:dash:mp4protection:2011":
        schemeType = xpp.getAttributeValue(null, "value");
        String defaultKid = XmlPullParserUtil.getAttributeValueIgnorePrefix(xpp, "default_KID");
        if (!TextUtils.isEmpty(defaultKid)
            && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
          String[] defaultKidStrings = defaultKid.split("\\s+");
          UUID[] defaultKids = new UUID[defaultKidStrings.length];
          for (int i = 0; i < defaultKidStrings.length; i++) {
            defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
          }
          data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
          uuid = C.COMMON_PSSH_UUID;
        }
        break;
      case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
        uuid = C.PLAYREADY_UUID;
        break;
      case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
        uuid = C.WIDEVINE_UUID;
        break;
      default:
        break;
    }
  }

  do {
    xpp.next();
    if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
      licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
    } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
      String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
      requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
    } else if (data == null
        && XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh")
        && xpp.next() == XmlPullParser.TEXT) {
      // The cenc:pssh element is defined in 23001-7:2015.
      data = Base64.decode(xpp.getText(), Base64.DEFAULT);
      uuid = PsshAtomUtil.parseUuid(data);
      if (uuid == null) {
        Log.w(TAG, "Skipping malformed cenc:pssh data");
        data = null;
      }
    } else if (data == null
        && C.PLAYREADY_UUID.equals(uuid)
        && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
        && xpp.next() == XmlPullParser.TEXT) {
      // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
      data =
          PsshAtomUtil.buildPsshAtom(
              C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT));
    } else {
      maybeSkipTag(xpp);
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  SchemeData schemeData =
      uuid != null
          ? new SchemeData(
              uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
          : null;
  return Pair.create(schemeType, schemeData);
}
 
Example #12
Source File: SsManifestParser.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(
      uuid, PsshAtomUtil.buildPsshAtom(uuid, initData), buildTrackEncryptionBoxes(initData));
}
 
Example #13
Source File: DashManifestParser.java    From Telegram-FOSS with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
 *     Either or both may be null, depending on the ContentProtection element being parsed.
 */
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
    throws XmlPullParserException, IOException {
  String schemeType = null;
  String licenseServerUrl = null;
  byte[] data = null;
  UUID uuid = null;
  boolean requiresSecureDecoder = false;

  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  if (schemeIdUri != null) {
    switch (Util.toLowerInvariant(schemeIdUri)) {
      case "urn:mpeg:dash:mp4protection:2011":
        schemeType = xpp.getAttributeValue(null, "value");
        String defaultKid = XmlPullParserUtil.getAttributeValueIgnorePrefix(xpp, "default_KID");
        if (!TextUtils.isEmpty(defaultKid)
            && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
          String[] defaultKidStrings = defaultKid.split("\\s+");
          UUID[] defaultKids = new UUID[defaultKidStrings.length];
          for (int i = 0; i < defaultKidStrings.length; i++) {
            defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
          }
          data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
          uuid = C.COMMON_PSSH_UUID;
        }
        break;
      case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
        uuid = C.PLAYREADY_UUID;
        break;
      case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
        uuid = C.WIDEVINE_UUID;
        break;
      default:
        break;
    }
  }

  do {
    xpp.next();
    if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
      licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
    } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
      String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
      requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
    } else if (data == null
        && XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh")
        && xpp.next() == XmlPullParser.TEXT) {
      // The cenc:pssh element is defined in 23001-7:2015.
      data = Base64.decode(xpp.getText(), Base64.DEFAULT);
      uuid = PsshAtomUtil.parseUuid(data);
      if (uuid == null) {
        Log.w(TAG, "Skipping malformed cenc:pssh data");
        data = null;
      }
    } else if (data == null
        && C.PLAYREADY_UUID.equals(uuid)
        && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
        && xpp.next() == XmlPullParser.TEXT) {
      // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
      data =
          PsshAtomUtil.buildPsshAtom(
              C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT));
    } else {
      maybeSkipTag(xpp);
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  SchemeData schemeData =
      uuid != null
          ? new SchemeData(
              uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
          : null;
  return Pair.create(schemeType, schemeData);
}
 
Example #14
Source File: SsManifestParser.java    From K-Sonic with MIT License 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(uuid, PsshAtomUtil.buildPsshAtom(uuid, initData));
}
 
Example #15
Source File: DefaultDrmSessionManager.java    From K-Sonic with MIT License 4 votes vote down vote up
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
  Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
  if (++openCount != 1) {
    return this;
  }

  if (this.playbackLooper == null) {
    this.playbackLooper = playbackLooper;
    mediaDrmHandler = new MediaDrmHandler(playbackLooper);
    postResponseHandler = new PostResponseHandler(playbackLooper);
  }

  requestHandlerThread = new HandlerThread("DrmRequestHandler");
  requestHandlerThread.start();
  postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper());

  if (offlineLicenseKeySetId == null) {
    SchemeData schemeData = drmInitData.get(uuid);
    if (schemeData == null) {
      onError(new IllegalStateException("Media does not support uuid: " + uuid));
      return this;
    }
    schemeInitData = schemeData.data;
    schemeMimeType = schemeData.mimeType;
    if (Util.SDK_INT < 21) {
      // Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
      byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData, C.WIDEVINE_UUID);
      if (psshData == null) {
        // Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
      } else {
        schemeInitData = psshData;
      }
    }
    if (Util.SDK_INT < 26 && C.CLEARKEY_UUID.equals(uuid)
        && (MimeTypes.VIDEO_MP4.equals(schemeMimeType)
        || MimeTypes.AUDIO_MP4.equals(schemeMimeType))) {
      // Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
      schemeMimeType = CENC_SCHEME_MIME_TYPE;
    }
  }
  state = STATE_OPENING;
  openInternal(true);
  return this;
}
 
Example #16
Source File: DashManifestParser.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
 *     Either or both may be null, depending on the ContentProtection element being parsed.
 */
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
    throws XmlPullParserException, IOException {
  String schemeType = null;
  String licenseServerUrl = null;
  byte[] data = null;
  UUID uuid = null;
  boolean requiresSecureDecoder = false;

  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  if (schemeIdUri != null) {
    switch (Util.toLowerInvariant(schemeIdUri)) {
      case "urn:mpeg:dash:mp4protection:2011":
        schemeType = xpp.getAttributeValue(null, "value");
        String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID");
        if (!TextUtils.isEmpty(defaultKid)
            && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
          String[] defaultKidStrings = defaultKid.split("\\s+");
          UUID[] defaultKids = new UUID[defaultKidStrings.length];
          for (int i = 0; i < defaultKidStrings.length; i++) {
            defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
          }
          data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
          uuid = C.COMMON_PSSH_UUID;
        }
        break;
      case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
        uuid = C.PLAYREADY_UUID;
        break;
      case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
        uuid = C.WIDEVINE_UUID;
        break;
      default:
        break;
    }
  }

  do {
    xpp.next();
    if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
      licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
    } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
      String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
      requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
    } else if (data == null) {
      if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) {
        // The cenc:pssh element is defined in 23001-7:2015.
        data = Base64.decode(xpp.getText(), Base64.DEFAULT);
        uuid = PsshAtomUtil.parseUuid(data);
        if (uuid == null) {
          Log.w(TAG, "Skipping malformed cenc:pssh data");
          data = null;
        }
      } else if (C.PLAYREADY_UUID.equals(uuid) && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
          && xpp.next() == XmlPullParser.TEXT) {
        // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
        data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID,
            Base64.decode(xpp.getText(), Base64.DEFAULT));
      }
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  SchemeData schemeData =
      uuid != null
          ? new SchemeData(
              uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
          : null;
  return Pair.create(schemeType, schemeData);
}
 
Example #17
Source File: SsManifestParser.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(uuid, PsshAtomUtil.buildPsshAtom(uuid, initData));
}
 
Example #18
Source File: DashManifestParser.java    From TelePlus-Android with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
 *     Either or both may be null, depending on the ContentProtection element being parsed.
 */
protected Pair<String, SchemeData> parseContentProtection(XmlPullParser xpp)
    throws XmlPullParserException, IOException {
  String schemeType = null;
  String licenseServerUrl = null;
  byte[] data = null;
  UUID uuid = null;
  boolean requiresSecureDecoder = false;

  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  if (schemeIdUri != null) {
    switch (Util.toLowerInvariant(schemeIdUri)) {
      case "urn:mpeg:dash:mp4protection:2011":
        schemeType = xpp.getAttributeValue(null, "value");
        String defaultKid = xpp.getAttributeValue(null, "cenc:default_KID");
        if (!TextUtils.isEmpty(defaultKid)
            && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
          String[] defaultKidStrings = defaultKid.split("\\s+");
          UUID[] defaultKids = new UUID[defaultKidStrings.length];
          for (int i = 0; i < defaultKidStrings.length; i++) {
            defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
          }
          data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
          uuid = C.COMMON_PSSH_UUID;
        }
        break;
      case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
        uuid = C.PLAYREADY_UUID;
        break;
      case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
        uuid = C.WIDEVINE_UUID;
        break;
      default:
        break;
    }
  }

  do {
    xpp.next();
    if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
      licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
    } else if (XmlPullParserUtil.isStartTag(xpp, "widevine:license")) {
      String robustnessLevel = xpp.getAttributeValue(null, "robustness_level");
      requiresSecureDecoder = robustnessLevel != null && robustnessLevel.startsWith("HW");
    } else if (data == null) {
      if (XmlPullParserUtil.isStartTag(xpp, "cenc:pssh") && xpp.next() == XmlPullParser.TEXT) {
        // The cenc:pssh element is defined in 23001-7:2015.
        data = Base64.decode(xpp.getText(), Base64.DEFAULT);
        uuid = PsshAtomUtil.parseUuid(data);
        if (uuid == null) {
          Log.w(TAG, "Skipping malformed cenc:pssh data");
          data = null;
        }
      } else if (C.PLAYREADY_UUID.equals(uuid) && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
          && xpp.next() == XmlPullParser.TEXT) {
        // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
        data = PsshAtomUtil.buildPsshAtom(C.PLAYREADY_UUID,
            Base64.decode(xpp.getText(), Base64.DEFAULT));
      }
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  SchemeData schemeData =
      uuid != null
          ? new SchemeData(
              uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data, requiresSecureDecoder)
          : null;
  return Pair.create(schemeType, schemeData);
}
 
Example #19
Source File: SsManifestParser.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
@Override
public Object build() {
  return new ProtectionElement(
      uuid, PsshAtomUtil.buildPsshAtom(uuid, initData), buildTrackEncryptionBoxes(initData));
}
 
Example #20
Source File: DashManifestParser.java    From MediaSDK with Apache License 2.0 4 votes vote down vote up
/**
 * Parses a ContentProtection element.
 *
 * @param xpp The parser from which to read.
 * @throws XmlPullParserException If an error occurs parsing the element.
 * @throws IOException If an error occurs reading the element.
 * @return The scheme type and/or {@link SchemeData} parsed from the ContentProtection element.
 *     Either or both may be null, depending on the ContentProtection element being parsed.
 */
protected Pair<@NullableType String, @NullableType SchemeData> parseContentProtection(
    XmlPullParser xpp) throws XmlPullParserException, IOException {
  String schemeType = null;
  String licenseServerUrl = null;
  byte[] data = null;
  UUID uuid = null;

  String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
  if (schemeIdUri != null) {
    switch (Util.toLowerInvariant(schemeIdUri)) {
      case "urn:mpeg:dash:mp4protection:2011":
        schemeType = xpp.getAttributeValue(null, "value");
        String defaultKid = XmlPullParserUtil.getAttributeValueIgnorePrefix(xpp, "default_KID");
        if (!TextUtils.isEmpty(defaultKid)
            && !"00000000-0000-0000-0000-000000000000".equals(defaultKid)) {
          String[] defaultKidStrings = defaultKid.split("\\s+");
          UUID[] defaultKids = new UUID[defaultKidStrings.length];
          for (int i = 0; i < defaultKidStrings.length; i++) {
            defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
          }
          data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
          uuid = C.COMMON_PSSH_UUID;
        }
        break;
      case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
        uuid = C.PLAYREADY_UUID;
        break;
      case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
        uuid = C.WIDEVINE_UUID;
        break;
      default:
        break;
    }
  }

  do {
    xpp.next();
    if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
      licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
    } else if (data == null
        && XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh")
        && xpp.next() == XmlPullParser.TEXT) {
      // The cenc:pssh element is defined in 23001-7:2015.
      data = Base64.decode(xpp.getText(), Base64.DEFAULT);
      uuid = PsshAtomUtil.parseUuid(data);
      if (uuid == null) {
        Log.w(TAG, "Skipping malformed cenc:pssh data");
        data = null;
      }
    } else if (data == null
        && C.PLAYREADY_UUID.equals(uuid)
        && XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
        && xpp.next() == XmlPullParser.TEXT) {
      // The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
      data =
          PsshAtomUtil.buildPsshAtom(
              C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT));
    } else {
      maybeSkipTag(xpp);
    }
  } while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
  SchemeData schemeData =
      uuid != null ? new SchemeData(uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data) : null;
  return Pair.create(schemeType, schemeData);
}