Search in sources :

Example 1 with Window

use of com.google.android.exoplayer2.Timeline.Window in project react-native-video by react-native-community.

the class ReactExoplayerView method createViews.

private void createViews() {
    mediaDataSourceFactory = buildDataSourceFactory(true);
    mainHandler = new Handler();
    window = new Timeline.Window();
    if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
        CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
    }
    LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    exoPlayerView = new ExoPlayerView(getContext());
    exoPlayerView.setLayoutParams(layoutParams);
    addView(exoPlayerView, 0, layoutParams);
}
Also used : Timeline(com.google.android.exoplayer2.Timeline) CookieHandler(java.net.CookieHandler) Handler(android.os.Handler)

Example 2 with Window

use of com.google.android.exoplayer2.Timeline.Window in project ExoPlayer by google.

the class ClippingMediaSourceTest method testClippingStartAndEnd.

public void testClippingStartAndEnd() {
    Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true);
    Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2);
    assertEquals(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3, clippedTimeline.getWindow(0, window).getDurationUs());
    assertEquals(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3, clippedTimeline.getPeriod(0, period).getDurationUs());
}
Also used : Timeline(com.google.android.exoplayer2.Timeline)

Example 3 with Window

use of com.google.android.exoplayer2.Timeline.Window in project ExoPlayer by google.

the class ClippingMediaSourceTest method testClippingEnd.

public void testClippingEnd() {
    Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true);
    Timeline clippedTimeline = getClippedTimeline(timeline, 0, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
    assertEquals(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US, clippedTimeline.getWindow(0, window).getDurationUs());
    assertEquals(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US, clippedTimeline.getPeriod(0, period).getDurationUs());
}
Also used : Timeline(com.google.android.exoplayer2.Timeline)

Example 4 with Window

use of com.google.android.exoplayer2.Timeline.Window in project ExoPlayer by google.

the class HlsChunkSource method getNextChunk.

/**
   * Returns the next chunk to load.
   * <p>
   * If a chunk is available then {@link HlsChunkHolder#chunk} is set. If the end of the stream has
   * been reached then {@link HlsChunkHolder#endOfStream} is set. If a chunk is not available but
   * the end of the stream has not been reached, {@link HlsChunkHolder#playlist} is set to
   * contain the {@link HlsUrl} that refers to the playlist that needs refreshing.
   *
   * @param previous The most recently loaded media chunk.
   * @param playbackPositionUs The current playback position. If {@code previous} is null then this
   *     parameter is the position from which playback is expected to start (or restart) and hence
   *     should be interpreted as a seek position.
   * @param out A holder to populate.
   */
public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, HlsChunkHolder out) {
    int oldVariantIndex = previous == null ? C.INDEX_UNSET : trackGroup.indexOf(previous.trackFormat);
    // Use start time of the previous chunk rather than its end time because switching format will
    // require downloading overlapping segments.
    long bufferedDurationUs = previous == null ? 0 : Math.max(0, previous.startTimeUs - playbackPositionUs);
    // Select the variant.
    trackSelection.updateSelectedTrack(bufferedDurationUs);
    int selectedVariantIndex = trackSelection.getSelectedIndexInTrackGroup();
    boolean switchingVariant = oldVariantIndex != selectedVariantIndex;
    HlsUrl selectedUrl = variants[selectedVariantIndex];
    if (!playlistTracker.isSnapshotValid(selectedUrl)) {
        out.playlist = selectedUrl;
        // Retry when playlist is refreshed.
        return;
    }
    HlsMediaPlaylist mediaPlaylist = playlistTracker.getPlaylistSnapshot(selectedUrl);
    // Select the chunk.
    int chunkMediaSequence;
    if (previous == null || switchingVariant) {
        long targetPositionUs = previous == null ? playbackPositionUs : previous.startTimeUs;
        if (!mediaPlaylist.hasEndTag && targetPositionUs > mediaPlaylist.getEndTimeUs()) {
            // If the playlist is too old to contain the chunk, we need to refresh it.
            chunkMediaSequence = mediaPlaylist.mediaSequence + mediaPlaylist.segments.size();
        } else {
            chunkMediaSequence = Util.binarySearchFloor(mediaPlaylist.segments, targetPositionUs - mediaPlaylist.startTimeUs, true, !playlistTracker.isLive() || previous == null) + mediaPlaylist.mediaSequence;
            if (chunkMediaSequence < mediaPlaylist.mediaSequence && previous != null) {
                // We try getting the next chunk without adapting in case that's the reason for falling
                // behind the live window.
                selectedVariantIndex = oldVariantIndex;
                selectedUrl = variants[selectedVariantIndex];
                mediaPlaylist = playlistTracker.getPlaylistSnapshot(selectedUrl);
                chunkMediaSequence = previous.getNextChunkIndex();
            }
        }
    } else {
        chunkMediaSequence = previous.getNextChunkIndex();
    }
    if (chunkMediaSequence < mediaPlaylist.mediaSequence) {
        fatalError = new BehindLiveWindowException();
        return;
    }
    int chunkIndex = chunkMediaSequence - mediaPlaylist.mediaSequence;
    if (chunkIndex >= mediaPlaylist.segments.size()) {
        if (mediaPlaylist.hasEndTag) {
            out.endOfStream = true;
        } else /* Live */
        {
            out.playlist = selectedUrl;
        }
        return;
    }
    // Handle encryption.
    HlsMediaPlaylist.Segment segment = mediaPlaylist.segments.get(chunkIndex);
    // Check if encryption is specified.
    if (segment.isEncrypted) {
        Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.encryptionKeyUri);
        if (!keyUri.equals(encryptionKeyUri)) {
            // Encryption is specified and the key has changed.
            out.chunk = newEncryptionKeyChunk(keyUri, segment.encryptionIV, selectedVariantIndex, trackSelection.getSelectionReason(), trackSelection.getSelectionData());
            return;
        }
        if (!Util.areEqual(segment.encryptionIV, encryptionIvString)) {
            setEncryptionData(keyUri, segment.encryptionIV, encryptionKey);
        }
    } else {
        clearEncryptionData();
    }
    DataSpec initDataSpec = null;
    Segment initSegment = mediaPlaylist.initializationSegment;
    if (initSegment != null) {
        Uri initSegmentUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, initSegment.url);
        initDataSpec = new DataSpec(initSegmentUri, initSegment.byterangeOffset, initSegment.byterangeLength, null);
    }
    // Compute start time of the next chunk.
    long startTimeUs = mediaPlaylist.startTimeUs + segment.relativeStartTimeUs;
    int discontinuitySequence = mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence;
    TimestampAdjuster timestampAdjuster = timestampAdjusterProvider.getAdjuster(discontinuitySequence);
    // Configure the data source and spec for the chunk.
    Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
    DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength, null);
    out.chunk = new HlsMediaChunk(mediaDataSource, dataSpec, initDataSpec, selectedUrl, muxedCaptionFormats, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence, isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv);
}
Also used : Segment(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment) HlsUrl(com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl) BehindLiveWindowException(com.google.android.exoplayer2.source.BehindLiveWindowException) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) HlsMediaPlaylist(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist) TimestampAdjuster(com.google.android.exoplayer2.util.TimestampAdjuster) Uri(android.net.Uri) Segment(com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)

Example 5 with Window

use of com.google.android.exoplayer2.Timeline.Window in project ExoPlayer by google.

the class SsMediaSource method processManifest.

// Internal methods
private void processManifest() {
    for (int i = 0; i < mediaPeriods.size(); i++) {
        mediaPeriods.get(i).updateManifest(manifest);
    }
    Timeline timeline;
    if (manifest.isLive) {
        long startTimeUs = Long.MAX_VALUE;
        long endTimeUs = Long.MIN_VALUE;
        for (int i = 0; i < manifest.streamElements.length; i++) {
            StreamElement element = manifest.streamElements[i];
            if (element.chunkCount > 0) {
                startTimeUs = Math.min(startTimeUs, element.getStartTimeUs(0));
                endTimeUs = Math.max(endTimeUs, element.getStartTimeUs(element.chunkCount - 1) + element.getChunkDurationUs(element.chunkCount - 1));
            }
        }
        if (startTimeUs == Long.MAX_VALUE) {
            timeline = new SinglePeriodTimeline(C.TIME_UNSET, false);
        } else {
            if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) {
                startTimeUs = Math.max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
            }
            long durationUs = endTimeUs - startTimeUs;
            long defaultStartPositionUs = durationUs - C.msToUs(livePresentationDelayMs);
            if (defaultStartPositionUs < MIN_LIVE_DEFAULT_START_POSITION_US) {
                // The default start position is too close to the start of the live window. Set it to the
                // minimum default start position provided the window is at least twice as big. Else set
                // it to the middle of the window.
                defaultStartPositionUs = Math.min(MIN_LIVE_DEFAULT_START_POSITION_US, durationUs / 2);
            }
            timeline = new SinglePeriodTimeline(C.TIME_UNSET, durationUs, startTimeUs, defaultStartPositionUs, true, /* isSeekable */
            true);
        }
    } else {
        boolean isSeekable = manifest.durationUs != C.TIME_UNSET;
        timeline = new SinglePeriodTimeline(manifest.durationUs, isSeekable);
    }
    sourceListener.onSourceInfoRefreshed(timeline, manifest);
}
Also used : SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) Timeline(com.google.android.exoplayer2.Timeline) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) StreamElement(com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)

Aggregations

Timeline (com.google.android.exoplayer2.Timeline)9 Uri (android.net.Uri)1 Handler (android.os.Handler)1 Period (com.google.android.exoplayer2.Timeline.Period)1 Window (com.google.android.exoplayer2.Timeline.Window)1 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)1 SinglePeriodTimeline (com.google.android.exoplayer2.source.SinglePeriodTimeline)1 HlsUrl (com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl)1 HlsMediaPlaylist (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist)1 Segment (com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment)1 StreamElement (com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)1 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)1 TimestampAdjuster (com.google.android.exoplayer2.util.TimestampAdjuster)1 CookieHandler (java.net.CookieHandler)1