Search in sources :

Example 1 with SchemeData

use of com.google.android.exoplayer2.drm.DrmInitData.SchemeData in project ExoPlayer by google.

the class FragmentedMp4Extractor method getDrmInitDataFromAtoms.

/** Returns DrmInitData from leaf atoms. */
private static DrmInitData getDrmInitDataFromAtoms(List<Atom.LeafAtom> leafChildren) {
    ArrayList<SchemeData> schemeDatas = null;
    int leafChildrenSize = leafChildren.size();
    for (int i = 0; i < leafChildrenSize; i++) {
        LeafAtom child = leafChildren.get(i);
        if (child.type == Atom.TYPE_pssh) {
            if (schemeDatas == null) {
                schemeDatas = new ArrayList<>();
            }
            byte[] psshData = child.data.data;
            UUID uuid = PsshAtomUtil.parseUuid(psshData);
            if (uuid == null) {
                Log.w(TAG, "Skipped pssh atom (failed to extract uuid)");
            } else {
                schemeDatas.add(new SchemeData(uuid, MimeTypes.VIDEO_MP4, psshData));
            }
        }
    }
    return schemeDatas == null ? null : new DrmInitData(schemeDatas);
}
Also used : DrmInitData(com.google.android.exoplayer2.drm.DrmInitData) SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData) UUID(java.util.UUID) LeafAtom(com.google.android.exoplayer2.extractor.mp4.Atom.LeafAtom)

Example 2 with SchemeData

use of com.google.android.exoplayer2.drm.DrmInitData.SchemeData in project ExoPlayer by google.

the class MatroskaExtractor method endMasterElement.

/* package */
void endMasterElement(int id) throws ParserException {
    switch(id) {
        case ID_SEGMENT_INFO:
            if (timecodeScale == C.TIME_UNSET) {
                // timecodeScale was omitted. Use the default value.
                timecodeScale = 1000000;
            }
            if (durationTimecode != C.TIME_UNSET) {
                durationUs = scaleTimecodeToUs(durationTimecode);
            }
            break;
        case ID_SEEK:
            if (seekEntryId == UNSET_ENTRY_ID || seekEntryPosition == C.POSITION_UNSET) {
                throw new ParserException("Mandatory element SeekID or SeekPosition not found");
            }
            if (seekEntryId == ID_CUES) {
                cuesContentPosition = seekEntryPosition;
            }
            break;
        case ID_CUES:
            if (!sentSeekMap) {
                extractorOutput.seekMap(buildSeekMap());
                sentSeekMap = true;
            } else {
            // We have already built the cues. Ignore.
            }
            break;
        case ID_BLOCK_GROUP:
            if (blockState != BLOCK_STATE_DATA) {
                // We've skipped this block (due to incompatible track number).
                return;
            }
            // If the ReferenceBlock element was not found for this sample, then it is a keyframe.
            if (!sampleSeenReferenceBlock) {
                blockFlags |= C.BUFFER_FLAG_KEY_FRAME;
            }
            commitSampleToOutput(tracks.get(blockTrackNumber), blockTimeUs);
            blockState = BLOCK_STATE_START;
            break;
        case ID_CONTENT_ENCODING:
            if (currentTrack.hasContentEncryption) {
                if (currentTrack.encryptionKeyId == null) {
                    throw new ParserException("Encrypted Track found but ContentEncKeyID was not found");
                }
                currentTrack.drmInitData = new DrmInitData(new SchemeData(C.UUID_NIL, MimeTypes.VIDEO_WEBM, currentTrack.encryptionKeyId));
            }
            break;
        case ID_CONTENT_ENCODINGS:
            if (currentTrack.hasContentEncryption && currentTrack.sampleStrippedBytes != null) {
                throw new ParserException("Combining encryption and compression is not supported");
            }
            break;
        case ID_TRACK_ENTRY:
            if (isCodecSupported(currentTrack.codecId)) {
                currentTrack.initializeOutput(extractorOutput, currentTrack.number);
                tracks.put(currentTrack.number, currentTrack);
            }
            currentTrack = null;
            break;
        case ID_TRACKS:
            if (tracks.size() == 0) {
                throw new ParserException("No valid tracks were found");
            }
            extractorOutput.endTracks();
            break;
        default:
            break;
    }
}
Also used : ParserException(com.google.android.exoplayer2.ParserException) DrmInitData(com.google.android.exoplayer2.drm.DrmInitData) SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData)

Example 3 with SchemeData

use of com.google.android.exoplayer2.drm.DrmInitData.SchemeData in project ExoPlayer by google.

the class DashManifestParser method parseRepresentation.

// Representation parsing.
protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseUrl, String adaptationSetMimeType, String adaptationSetCodecs, int adaptationSetWidth, int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels, int adaptationSetAudioSamplingRate, String adaptationSetLanguage, @C.SelectionFlags int adaptationSetSelectionFlags, List<SchemeValuePair> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase) throws XmlPullParserException, IOException {
    String id = xpp.getAttributeValue(null, "id");
    int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
    String mimeType = parseString(xpp, "mimeType", adaptationSetMimeType);
    String codecs = parseString(xpp, "codecs", adaptationSetCodecs);
    int width = parseInt(xpp, "width", adaptationSetWidth);
    int height = parseInt(xpp, "height", adaptationSetHeight);
    float frameRate = parseFrameRate(xpp, adaptationSetFrameRate);
    int audioChannels = adaptationSetAudioChannels;
    int audioSamplingRate = parseInt(xpp, "audioSamplingRate", adaptationSetAudioSamplingRate);
    ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
    ArrayList<SchemeValuePair> inbandEventStreams = new ArrayList<>();
    boolean seenFirstBaseUrl = false;
    do {
        xpp.next();
        if (XmlPullParserUtil.isStartTag(xpp, "BaseURL")) {
            if (!seenFirstBaseUrl) {
                baseUrl = parseBaseUrl(xpp, baseUrl);
                seenFirstBaseUrl = true;
            }
        } else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) {
            audioChannels = parseAudioChannelConfiguration(xpp);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentBase")) {
            segmentBase = parseSegmentBase(xpp, (SingleSegmentBase) segmentBase);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentList")) {
            segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase);
        } else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
            segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase);
        } else if (XmlPullParserUtil.isStartTag(xpp, "ContentProtection")) {
            SchemeData contentProtection = parseContentProtection(xpp);
            if (contentProtection != null) {
                drmSchemeDatas.add(contentProtection);
            }
        } else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
            inbandEventStreams.add(parseInbandEventStream(xpp));
        }
    } while (!XmlPullParserUtil.isEndTag(xpp, "Representation"));
    Format format = buildFormat(id, mimeType, width, height, frameRate, audioChannels, audioSamplingRate, bandwidth, adaptationSetLanguage, adaptationSetSelectionFlags, adaptationSetAccessibilityDescriptors, codecs);
    segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase();
    return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas, inbandEventStreams);
}
Also used : SingleSegmentBase(com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase) ArrayList(java.util.ArrayList) SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData) SegmentTemplate(com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTemplate) Format(com.google.android.exoplayer2.Format)

Example 4 with SchemeData

use of com.google.android.exoplayer2.drm.DrmInitData.SchemeData in project ExoPlayer by google.

the class DashManifestParser method buildRepresentation.

protected Representation buildRepresentation(RepresentationInfo representationInfo, String contentId, ArrayList<SchemeData> extraDrmSchemeDatas, ArrayList<SchemeValuePair> extraInbandEventStreams) {
    Format format = representationInfo.format;
    ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
    drmSchemeDatas.addAll(extraDrmSchemeDatas);
    if (!drmSchemeDatas.isEmpty()) {
        format = format.copyWithDrmInitData(new DrmInitData(drmSchemeDatas));
    }
    ArrayList<SchemeValuePair> inbandEventStremas = representationInfo.inbandEventStreams;
    inbandEventStremas.addAll(extraInbandEventStreams);
    return Representation.newInstance(contentId, Representation.REVISION_ID_DEFAULT, format, representationInfo.baseUrl, representationInfo.segmentBase, inbandEventStremas);
}
Also used : Format(com.google.android.exoplayer2.Format) DrmInitData(com.google.android.exoplayer2.drm.DrmInitData) SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData)

Example 5 with SchemeData

use of com.google.android.exoplayer2.drm.DrmInitData.SchemeData in project ExoPlayer by google.

the class DashManifestParser method parseContentProtection.

/**
   * 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;
}
Also used : SchemeData(com.google.android.exoplayer2.drm.DrmInitData.SchemeData) UUID(java.util.UUID)

Aggregations

SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)6 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)3 Format (com.google.android.exoplayer2.Format)2 UUID (java.util.UUID)2 HandlerThread (android.os.HandlerThread)1 ParserException (com.google.android.exoplayer2.ParserException)1 LeafAtom (com.google.android.exoplayer2.extractor.mp4.Atom.LeafAtom)1 SegmentTemplate (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTemplate)1 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)1 ArrayList (java.util.ArrayList)1