Search in sources :

Example 1 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class ExtractorMediaPeriod method maybeFinishPrepare.

// Internal methods.
private void maybeFinishPrepare() {
    if (released || prepared || seekMap == null || !tracksBuilt) {
        return;
    }
    int trackCount = sampleQueues.size();
    for (int i = 0; i < trackCount; i++) {
        if (sampleQueues.valueAt(i).getUpstreamFormat() == null) {
            return;
        }
    }
    loadCondition.close();
    TrackGroup[] trackArray = new TrackGroup[trackCount];
    trackIsAudioVideoFlags = new boolean[trackCount];
    trackEnabledStates = new boolean[trackCount];
    durationUs = seekMap.getDurationUs();
    for (int i = 0; i < trackCount; i++) {
        Format trackFormat = sampleQueues.valueAt(i).getUpstreamFormat();
        trackArray[i] = new TrackGroup(trackFormat);
        String mimeType = trackFormat.sampleMimeType;
        boolean isAudioVideo = MimeTypes.isVideo(mimeType) || MimeTypes.isAudio(mimeType);
        trackIsAudioVideoFlags[i] = isAudioVideo;
        haveAudioVideoTracks |= isAudioVideo;
    }
    tracks = new TrackGroupArray(trackArray);
    prepared = true;
    sourceListener.onSourceInfoRefreshed(new SinglePeriodTimeline(durationUs, seekMap.isSeekable()), null);
    callback.onPrepared(this);
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 2 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class TrackSelectionHelper method buildView.

@SuppressLint("InflateParams")
private View buildView(Context context) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.track_selection_dialog, null);
    ViewGroup root = (ViewGroup) view.findViewById(R.id.root);
    TypedArray attributeArray = context.getTheme().obtainStyledAttributes(new int[] { android.R.attr.selectableItemBackground });
    int selectableItemBackgroundResourceId = attributeArray.getResourceId(0, 0);
    attributeArray.recycle();
    // View for disabling the renderer.
    disableView = (CheckedTextView) inflater.inflate(android.R.layout.simple_list_item_single_choice, root, false);
    disableView.setBackgroundResource(selectableItemBackgroundResourceId);
    disableView.setText(R.string.selection_disabled);
    disableView.setFocusable(true);
    disableView.setOnClickListener(this);
    root.addView(disableView);
    // View for clearing the override to allow the selector to use its default selection logic.
    defaultView = (CheckedTextView) inflater.inflate(android.R.layout.simple_list_item_single_choice, root, false);
    defaultView.setBackgroundResource(selectableItemBackgroundResourceId);
    defaultView.setText(R.string.selection_default);
    defaultView.setFocusable(true);
    defaultView.setOnClickListener(this);
    root.addView(inflater.inflate(R.layout.list_divider, root, false));
    root.addView(defaultView);
    // Per-track views.
    boolean haveSupportedTracks = false;
    boolean haveAdaptiveTracks = false;
    trackViews = new CheckedTextView[trackGroups.length][];
    for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
        TrackGroup group = trackGroups.get(groupIndex);
        boolean groupIsAdaptive = trackGroupsAdaptive[groupIndex];
        haveAdaptiveTracks |= groupIsAdaptive;
        trackViews[groupIndex] = new CheckedTextView[group.length];
        for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
            if (trackIndex == 0) {
                root.addView(inflater.inflate(R.layout.list_divider, root, false));
            }
            int trackViewLayoutId = groupIsAdaptive ? android.R.layout.simple_list_item_multiple_choice : android.R.layout.simple_list_item_single_choice;
            CheckedTextView trackView = (CheckedTextView) inflater.inflate(trackViewLayoutId, root, false);
            trackView.setBackgroundResource(selectableItemBackgroundResourceId);
            trackView.setText(buildTrackName(group.getFormat(trackIndex)));
            if (trackInfo.getTrackFormatSupport(rendererIndex, groupIndex, trackIndex) == RendererCapabilities.FORMAT_HANDLED) {
                trackView.setFocusable(true);
                trackView.setTag(Pair.create(groupIndex, trackIndex));
                trackView.setOnClickListener(this);
                haveSupportedTracks = true;
            } else {
                trackView.setFocusable(false);
                trackView.setEnabled(false);
            }
            trackViews[groupIndex][trackIndex] = trackView;
            root.addView(trackView);
        }
    }
    if (!haveSupportedTracks) {
        // Indicate that the default selection will be nothing.
        defaultView.setText(R.string.selection_default_none);
    } else if (haveAdaptiveTracks) {
        // View for using random adaptation.
        enableRandomAdaptationView = (CheckedTextView) inflater.inflate(android.R.layout.simple_list_item_multiple_choice, root, false);
        enableRandomAdaptationView.setBackgroundResource(selectableItemBackgroundResourceId);
        enableRandomAdaptationView.setText(R.string.enable_random_adaptation);
        enableRandomAdaptationView.setOnClickListener(this);
        root.addView(inflater.inflate(R.layout.list_divider, root, false));
        root.addView(enableRandomAdaptationView);
    }
    updateViews();
    return view;
}
Also used : ViewGroup(android.view.ViewGroup) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) CheckedTextView(android.widget.CheckedTextView) LayoutInflater(android.view.LayoutInflater) TypedArray(android.content.res.TypedArray) View(android.view.View) CheckedTextView(android.widget.CheckedTextView) SuppressLint(android.annotation.SuppressLint) SuppressLint(android.annotation.SuppressLint)

Example 3 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class ExoPlayerTest method testPlaySinglePeriodTimeline.

/**
   * Tests playback of a source that exposes a single period.
   */
public void testPlaySinglePeriodTimeline() throws Exception {
    PlayerWrapper playerWrapper = new PlayerWrapper();
    Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(false, false, 0));
    Object manifest = new Object();
    MediaSource mediaSource = new FakeMediaSource(timeline, manifest, TEST_VIDEO_FORMAT);
    FakeRenderer renderer = new FakeRenderer(TEST_VIDEO_FORMAT);
    playerWrapper.setup(mediaSource, renderer);
    playerWrapper.blockUntilEnded(TIMEOUT_MS);
    assertEquals(0, playerWrapper.positionDiscontinuityCount);
    assertEquals(1, renderer.formatReadCount);
    assertEquals(1, renderer.bufferReadCount);
    assertTrue(renderer.isEnded);
    assertEquals(timeline, playerWrapper.timeline);
    assertEquals(manifest, playerWrapper.manifest);
    assertEquals(new TrackGroupArray(new TrackGroup(TEST_VIDEO_FORMAT)), playerWrapper.trackGroups);
}
Also used : MediaSource(com.google.android.exoplayer2.source.MediaSource) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray)

Example 4 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class HlsMediaPeriod method onPrepared.

// HlsSampleStreamWrapper.Callback implementation.
@Override
public void onPrepared() {
    if (--pendingPrepareCount > 0) {
        return;
    }
    int totalTrackGroupCount = 0;
    for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
        totalTrackGroupCount += sampleStreamWrapper.getTrackGroups().length;
    }
    TrackGroup[] trackGroupArray = new TrackGroup[totalTrackGroupCount];
    int trackGroupIndex = 0;
    for (HlsSampleStreamWrapper sampleStreamWrapper : sampleStreamWrappers) {
        int wrapperTrackGroupCount = sampleStreamWrapper.getTrackGroups().length;
        for (int j = 0; j < wrapperTrackGroupCount; j++) {
            trackGroupArray[trackGroupIndex++] = sampleStreamWrapper.getTrackGroups().get(j);
        }
    }
    trackGroups = new TrackGroupArray(trackGroupArray);
    callback.onPrepared(this);
}
Also used : TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray)

Example 5 with TrackGroup

use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.

the class HlsSampleStreamWrapper method buildTracks.

/**
   * Builds tracks that are exposed by this {@link HlsSampleStreamWrapper} instance, as well as
   * internal data-structures required for operation.
   * <p>
   * Tracks in HLS are complicated. A HLS master playlist contains a number of "variants". Each
   * variant stream typically contains muxed video, audio and (possibly) additional audio, metadata
   * and caption tracks. We wish to allow the user to select between an adaptive track that spans
   * all variants, as well as each individual variant. If multiple audio tracks are present within
   * each variant then we wish to allow the user to select between those also.
   * <p>
   * To do this, tracks are constructed as follows. The {@link HlsChunkSource} exposes (N+1) tracks,
   * where N is the number of variants defined in the HLS master playlist. These consist of one
   * adaptive track defined to span all variants and a track for each individual variant. The
   * adaptive track is initially selected. The extractor is then prepared to discover the tracks
   * inside of each variant stream. The two sets of tracks are then combined by this method to
   * create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
   * <ul>
   * <li>The extractor tracks are inspected to infer a "primary" track type. If a video track is
   * present then it is always the primary type. If not, audio is the primary type if present.
   * Else text is the primary type if present. Else there is no primary type.</li>
   * <li>If there is exactly one extractor track of the primary type, it's expanded into (N+1)
   * exposed tracks, all of which correspond to the primary extractor track and each of which
   * corresponds to a different chunk source track. Selecting one of these tracks has the effect
   * of switching the selected track on the chunk source.</li>
   * <li>All other extractor tracks are exposed directly. Selecting one of these tracks has the
   * effect of selecting an extractor track, leaving the selected track on the chunk source
   * unchanged.</li>
   * </ul>
   */
private void buildTracks() {
    // Iterate through the extractor tracks to discover the "primary" track type, and the index
    // of the single track of this type.
    int primaryExtractorTrackType = PRIMARY_TYPE_NONE;
    int primaryExtractorTrackIndex = C.INDEX_UNSET;
    int extractorTrackCount = sampleQueues.size();
    for (int i = 0; i < extractorTrackCount; i++) {
        String sampleMimeType = sampleQueues.valueAt(i).getUpstreamFormat().sampleMimeType;
        int trackType;
        if (MimeTypes.isVideo(sampleMimeType)) {
            trackType = PRIMARY_TYPE_VIDEO;
        } else if (MimeTypes.isAudio(sampleMimeType)) {
            trackType = PRIMARY_TYPE_AUDIO;
        } else if (MimeTypes.isText(sampleMimeType)) {
            trackType = PRIMARY_TYPE_TEXT;
        } else {
            trackType = PRIMARY_TYPE_NONE;
        }
        if (trackType > primaryExtractorTrackType) {
            primaryExtractorTrackType = trackType;
            primaryExtractorTrackIndex = i;
        } else if (trackType == primaryExtractorTrackType && primaryExtractorTrackIndex != C.INDEX_UNSET) {
            // We have multiple tracks of the primary type. We only want an index if there only exists a
            // single track of the primary type, so unset the index again.
            primaryExtractorTrackIndex = C.INDEX_UNSET;
        }
    }
    TrackGroup chunkSourceTrackGroup = chunkSource.getTrackGroup();
    int chunkSourceTrackCount = chunkSourceTrackGroup.length;
    // Instantiate the necessary internal data-structures.
    primaryTrackGroupIndex = C.INDEX_UNSET;
    groupEnabledStates = new boolean[extractorTrackCount];
    // Construct the set of exposed track groups.
    TrackGroup[] trackGroups = new TrackGroup[extractorTrackCount];
    for (int i = 0; i < extractorTrackCount; i++) {
        Format sampleFormat = sampleQueues.valueAt(i).getUpstreamFormat();
        if (i == primaryExtractorTrackIndex) {
            Format[] formats = new Format[chunkSourceTrackCount];
            for (int j = 0; j < chunkSourceTrackCount; j++) {
                formats[j] = deriveFormat(chunkSourceTrackGroup.getFormat(j), sampleFormat);
            }
            trackGroups[i] = new TrackGroup(formats);
            primaryTrackGroupIndex = i;
        } else {
            Format trackFormat = primaryExtractorTrackType == PRIMARY_TYPE_VIDEO && MimeTypes.isAudio(sampleFormat.sampleMimeType) ? muxedAudioFormat : null;
            trackGroups[i] = new TrackGroup(deriveFormat(trackFormat, sampleFormat));
        }
    }
    this.trackGroups = new TrackGroupArray(trackGroups);
}
Also used : Format(com.google.android.exoplayer2.Format) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray)

Aggregations

TrackGroup (com.google.android.exoplayer2.source.TrackGroup)13 Format (com.google.android.exoplayer2.Format)8 Point (android.graphics.Point)6 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)6 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)2 ArrayList (java.util.ArrayList)2 SuppressLint (android.annotation.SuppressLint)1 TypedArray (android.content.res.TypedArray)1 LayoutInflater (android.view.LayoutInflater)1 View (android.view.View)1 ViewGroup (android.view.ViewGroup)1 CheckedTextView (android.widget.CheckedTextView)1 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)1 RendererConfiguration (com.google.android.exoplayer2.RendererConfiguration)1 Metadata (com.google.android.exoplayer2.metadata.Metadata)1 CompositeSequenceableLoader (com.google.android.exoplayer2.source.CompositeSequenceableLoader)1 MediaSource (com.google.android.exoplayer2.source.MediaSource)1 SampleStream (com.google.android.exoplayer2.source.SampleStream)1 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)1 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)1