Search in sources :

Example 26 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class HlsPlaylistParser method parseMasterPlaylist.

private static HlsMasterPlaylist parseMasterPlaylist(LineIterator iterator, String baseUri) throws IOException {
    ArrayList<HlsMasterPlaylist.HlsUrl> variants = new ArrayList<>();
    ArrayList<HlsMasterPlaylist.HlsUrl> audios = new ArrayList<>();
    ArrayList<HlsMasterPlaylist.HlsUrl> subtitles = new ArrayList<>();
    Format muxedAudioFormat = null;
    ArrayList<Format> muxedCaptionFormats = new ArrayList<>();
    String line;
    while (iterator.hasNext()) {
        line = iterator.next();
        if (line.startsWith(TAG_MEDIA)) {
            @C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
            String uri = parseOptionalStringAttr(line, REGEX_URI);
            String id = parseStringAttr(line, REGEX_NAME);
            String language = parseOptionalStringAttr(line, REGEX_LANGUAGE);
            Format format;
            switch(parseStringAttr(line, REGEX_TYPE)) {
                case TYPE_AUDIO:
                    format = Format.createAudioContainerFormat(id, MimeTypes.APPLICATION_M3U8, null, null, Format.NO_VALUE, Format.NO_VALUE, Format.NO_VALUE, null, selectionFlags, language);
                    if (uri == null) {
                        muxedAudioFormat = format;
                    } else {
                        audios.add(new HlsMasterPlaylist.HlsUrl(uri, format));
                    }
                    break;
                case TYPE_SUBTITLES:
                    format = Format.createTextContainerFormat(id, MimeTypes.APPLICATION_M3U8, MimeTypes.TEXT_VTT, null, Format.NO_VALUE, selectionFlags, language);
                    subtitles.add(new HlsMasterPlaylist.HlsUrl(uri, format));
                    break;
                case TYPE_CLOSED_CAPTIONS:
                    String instreamId = parseStringAttr(line, REGEX_INSTREAM_ID);
                    String mimeType;
                    int accessibilityChannel;
                    if (instreamId.startsWith("CC")) {
                        mimeType = MimeTypes.APPLICATION_CEA608;
                        accessibilityChannel = Integer.parseInt(instreamId.substring(2));
                    } else /* starts with SERVICE */
                    {
                        mimeType = MimeTypes.APPLICATION_CEA708;
                        accessibilityChannel = Integer.parseInt(instreamId.substring(7));
                    }
                    muxedCaptionFormats.add(Format.createTextContainerFormat(id, null, mimeType, null, Format.NO_VALUE, selectionFlags, language, accessibilityChannel));
                    break;
                default:
                    // Do nothing.
                    break;
            }
        } else if (line.startsWith(TAG_STREAM_INF)) {
            int bitrate = parseIntAttr(line, REGEX_BANDWIDTH);
            String codecs = parseOptionalStringAttr(line, REGEX_CODECS);
            String resolutionString = parseOptionalStringAttr(line, REGEX_RESOLUTION);
            int width;
            int height;
            if (resolutionString != null) {
                String[] widthAndHeight = resolutionString.split("x");
                width = Integer.parseInt(widthAndHeight[0]);
                height = Integer.parseInt(widthAndHeight[1]);
                if (width <= 0 || height <= 0) {
                    // Resolution string is invalid.
                    width = Format.NO_VALUE;
                    height = Format.NO_VALUE;
                }
            } else {
                width = Format.NO_VALUE;
                height = Format.NO_VALUE;
            }
            line = iterator.next();
            Format format = Format.createVideoContainerFormat(Integer.toString(variants.size()), MimeTypes.APPLICATION_M3U8, null, codecs, bitrate, width, height, Format.NO_VALUE, null, 0);
            variants.add(new HlsMasterPlaylist.HlsUrl(line, format));
        }
    }
    return new HlsMasterPlaylist(baseUri, variants, audios, subtitles, muxedAudioFormat, muxedCaptionFormats);
}
Also used : Format(com.google.android.exoplayer2.Format) ArrayList(java.util.ArrayList)

Example 27 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class DashUtil method newWrappedExtractor.

private static ChunkExtractorWrapper newWrappedExtractor(Format format) {
    String mimeType = format.containerMimeType;
    boolean isWebm = mimeType.startsWith(MimeTypes.VIDEO_WEBM) || mimeType.startsWith(MimeTypes.AUDIO_WEBM);
    Extractor extractor = isWebm ? new MatroskaExtractor() : new FragmentedMp4Extractor();
    return new ChunkExtractorWrapper(extractor, format);
}
Also used : FragmentedMp4Extractor(com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor) ChunkExtractorWrapper(com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper) FragmentedMp4Extractor(com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor) Extractor(com.google.android.exoplayer2.extractor.Extractor) MatroskaExtractor(com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor) MatroskaExtractor(com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor)

Example 28 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class DefaultDashChunkSource method newInitializationChunk.

private static Chunk newInitializationChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, RangedUri initializationUri, RangedUri indexUri) {
    RangedUri requestUri;
    String baseUrl = representationHolder.representation.baseUrl;
    if (initializationUri != null) {
        // It's common for initialization and index data to be stored adjacently. Attempt to merge
        // the two requests together to request both at once.
        requestUri = initializationUri.attemptMerge(indexUri, baseUrl);
        if (requestUri == null) {
            requestUri = initializationUri;
        }
    } else {
        requestUri = indexUri;
    }
    DataSpec dataSpec = new DataSpec(requestUri.resolveUri(baseUrl), requestUri.start, requestUri.length, representationHolder.representation.getCacheKey());
    return new InitializationChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper);
}
Also used : InitializationChunk(com.google.android.exoplayer2.source.chunk.InitializationChunk) RangedUri(com.google.android.exoplayer2.source.dash.manifest.RangedUri) DataSpec(com.google.android.exoplayer2.upstream.DataSpec)

Example 29 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class DefaultDashChunkSource method newMediaChunk.

private static Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, int firstSegmentNum, int maxSegmentCount) {
    Representation representation = representationHolder.representation;
    long startTimeUs = representationHolder.getSegmentStartTimeUs(firstSegmentNum);
    RangedUri segmentUri = representationHolder.getSegmentUrl(firstSegmentNum);
    String baseUrl = representation.baseUrl;
    if (representationHolder.extractorWrapper == null) {
        long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum);
        DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl), segmentUri.start, segmentUri.length, representation.getCacheKey());
        return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, representationHolder.trackType, trackFormat);
    } else {
        int segmentCount = 1;
        for (int i = 1; i < maxSegmentCount; i++) {
            RangedUri nextSegmentUri = representationHolder.getSegmentUrl(firstSegmentNum + i);
            RangedUri mergedSegmentUri = segmentUri.attemptMerge(nextSegmentUri, baseUrl);
            if (mergedSegmentUri == null) {
                // Unable to merge segment fetches because the URIs do not merge.
                break;
            }
            segmentUri = mergedSegmentUri;
            segmentCount++;
        }
        long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum + segmentCount - 1);
        DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl), segmentUri.start, segmentUri.length, representation.getCacheKey());
        long sampleOffsetUs = -representation.presentationTimeOffsetUs;
        return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, segmentCount, sampleOffsetUs, representationHolder.extractorWrapper);
    }
}
Also used : SingleSampleMediaChunk(com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk) RangedUri(com.google.android.exoplayer2.source.dash.manifest.RangedUri) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation) ContainerMediaChunk(com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)

Example 30 with Format

use of com.google.android.exoplayer2.Format 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)

Aggregations

Format (com.google.android.exoplayer2.Format)44 Point (android.graphics.Point)8 ArrayList (java.util.ArrayList)8 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)7 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)5 SuppressLint (android.annotation.SuppressLint)4 MediaFormat (android.media.MediaFormat)4 ParserException (com.google.android.exoplayer2.ParserException)4 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)4 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)4 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)3 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)3 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)3 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)2 MediaCodecInfo (com.google.android.exoplayer2.mediacodec.MediaCodecInfo)2 Metadata (com.google.android.exoplayer2.metadata.Metadata)2 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)2 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)2 RangedUri (com.google.android.exoplayer2.source.dash.manifest.RangedUri)2 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)2