Search in sources :

Example 1 with HlsMasterPlaylist

use of com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist in project ExoPlayer by google.

the class HlsMasterPlaylistParserTest method testPlaylistWithClosedCaption.

public void testPlaylistWithClosedCaption() throws IOException {
    HlsMasterPlaylist playlist = parseMasterPlaylist(PLAYLIST_URI, MASTER_PLAYLIST_WITH_CC);
    assertEquals(1, playlist.muxedCaptionFormats.size());
    Format closedCaptionFormat = playlist.muxedCaptionFormats.get(0);
    assertEquals(MimeTypes.APPLICATION_CEA708, closedCaptionFormat.sampleMimeType);
    assertEquals(4, closedCaptionFormat.accessibilityChannel);
    assertEquals("es", closedCaptionFormat.language);
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 2 with HlsMasterPlaylist

use of com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist 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 3 with HlsMasterPlaylist

use of com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist in project ExoPlayer by google.

the class HlsMediaPeriod method buildAndPrepareSampleStreamWrappers.

// Internal methods.
private void buildAndPrepareSampleStreamWrappers() {
    HlsMasterPlaylist masterPlaylist = playlistTracker.getMasterPlaylist();
    // Build the default stream wrapper.
    List<HlsUrl> selectedVariants = new ArrayList<>(masterPlaylist.variants);
    ArrayList<HlsUrl> definiteVideoVariants = new ArrayList<>();
    ArrayList<HlsUrl> definiteAudioOnlyVariants = new ArrayList<>();
    for (int i = 0; i < selectedVariants.size(); i++) {
        HlsUrl variant = selectedVariants.get(i);
        if (variant.format.height > 0 || variantHasExplicitCodecWithPrefix(variant, "avc")) {
            definiteVideoVariants.add(variant);
        } else if (variantHasExplicitCodecWithPrefix(variant, "mp4a")) {
            definiteAudioOnlyVariants.add(variant);
        }
    }
    if (!definiteVideoVariants.isEmpty()) {
        // We've identified some variants as definitely containing video. Assume variants within the
        // master playlist are marked consistently, and hence that we have the full set. Filter out
        // any other variants, which are likely to be audio only.
        selectedVariants = definiteVideoVariants;
    } else if (definiteAudioOnlyVariants.size() < selectedVariants.size()) {
        // We've identified some variants, but not all, as being audio only. Filter them out to leave
        // the remaining variants, which are likely to contain video.
        selectedVariants.removeAll(definiteAudioOnlyVariants);
    } else {
    // Leave the enabled variants unchanged. They're likely either all video or all audio.
    }
    List<HlsUrl> audioRenditions = masterPlaylist.audios;
    List<HlsUrl> subtitleRenditions = masterPlaylist.subtitles;
    sampleStreamWrappers = new HlsSampleStreamWrapper[1 + /* variants */
    audioRenditions.size() + subtitleRenditions.size()];
    int currentWrapperIndex = 0;
    pendingPrepareCount = sampleStreamWrappers.length;
    Assertions.checkArgument(!selectedVariants.isEmpty());
    HlsUrl[] variants = new HlsMasterPlaylist.HlsUrl[selectedVariants.size()];
    selectedVariants.toArray(variants);
    HlsSampleStreamWrapper sampleStreamWrapper = buildSampleStreamWrapper(C.TRACK_TYPE_DEFAULT, variants, masterPlaylist.muxedAudioFormat, masterPlaylist.muxedCaptionFormats);
    sampleStreamWrappers[currentWrapperIndex++] = sampleStreamWrapper;
    sampleStreamWrapper.setIsTimestampMaster(true);
    sampleStreamWrapper.continuePreparing();
    // Build audio stream wrappers.
    for (int i = 0; i < audioRenditions.size(); i++) {
        sampleStreamWrapper = buildSampleStreamWrapper(C.TRACK_TYPE_AUDIO, new HlsUrl[] { audioRenditions.get(i) }, null, Collections.<Format>emptyList());
        sampleStreamWrappers[currentWrapperIndex++] = sampleStreamWrapper;
        sampleStreamWrapper.continuePreparing();
    }
    // Build subtitle stream wrappers.
    for (int i = 0; i < subtitleRenditions.size(); i++) {
        HlsUrl url = subtitleRenditions.get(i);
        sampleStreamWrapper = buildSampleStreamWrapper(C.TRACK_TYPE_TEXT, new HlsUrl[] { url }, null, Collections.<Format>emptyList());
        sampleStreamWrapper.prepareSingleTrack(url.format);
        sampleStreamWrappers[currentWrapperIndex++] = sampleStreamWrapper;
    }
}
Also used : Format(com.google.android.exoplayer2.Format) HlsUrl(com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl) ArrayList(java.util.ArrayList) HlsMasterPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist)

Aggregations

Format (com.google.android.exoplayer2.Format)3 ArrayList (java.util.ArrayList)2 HlsMasterPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist)1 HlsUrl (com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl)1