Search in sources :

Example 1 with StreamElement

use of com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement in project ExoPlayer by google.

the class DefaultSsChunkSource method updateManifest.

@Override
public void updateManifest(SsManifest newManifest) {
    StreamElement currentElement = manifest.streamElements[elementIndex];
    int currentElementChunkCount = currentElement.chunkCount;
    StreamElement newElement = newManifest.streamElements[elementIndex];
    if (currentElementChunkCount == 0 || newElement.chunkCount == 0) {
        // There's no overlap between the old and new elements because at least one is empty.
        currentManifestChunkOffset += currentElementChunkCount;
    } else {
        long currentElementEndTimeUs = currentElement.getStartTimeUs(currentElementChunkCount - 1) + currentElement.getChunkDurationUs(currentElementChunkCount - 1);
        long newElementStartTimeUs = newElement.getStartTimeUs(0);
        if (currentElementEndTimeUs <= newElementStartTimeUs) {
            // There's no overlap between the old and new elements.
            currentManifestChunkOffset += currentElementChunkCount;
        } else {
            // The new element overlaps with the old one.
            currentManifestChunkOffset += currentElement.getChunkIndex(newElementStartTimeUs);
        }
    }
    manifest = newManifest;
}
Also used : StreamElement(com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)

Example 2 with StreamElement

use of com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement 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)

Example 3 with StreamElement

use of com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement in project ExoPlayer by google.

the class DefaultSsChunkSource method getNextChunk.

@Override
public final void getNextChunk(MediaChunk previous, long playbackPositionUs, ChunkHolder out) {
    if (fatalError != null) {
        return;
    }
    long bufferedDurationUs = previous != null ? (previous.endTimeUs - playbackPositionUs) : 0;
    trackSelection.updateSelectedTrack(bufferedDurationUs);
    StreamElement streamElement = manifest.streamElements[elementIndex];
    if (streamElement.chunkCount == 0) {
        // There aren't any chunks for us to load.
        out.endOfStream = !manifest.isLive;
        return;
    }
    int chunkIndex;
    if (previous == null) {
        chunkIndex = streamElement.getChunkIndex(playbackPositionUs);
    } else {
        chunkIndex = previous.getNextChunkIndex() - currentManifestChunkOffset;
        if (chunkIndex < 0) {
            // This is before the first chunk in the current manifest.
            fatalError = new BehindLiveWindowException();
            return;
        }
    }
    if (chunkIndex >= streamElement.chunkCount) {
        // This is beyond the last chunk in the current manifest.
        out.endOfStream = !manifest.isLive;
        return;
    }
    long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
    long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(chunkIndex);
    int currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
    int trackSelectionIndex = trackSelection.getSelectedIndex();
    ChunkExtractorWrapper extractorWrapper = extractorWrappers[trackSelectionIndex];
    int manifestTrackIndex = trackSelection.getIndexInTrackGroup(trackSelectionIndex);
    Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex);
    out.chunk = newMediaChunk(trackSelection.getSelectedFormat(), dataSource, uri, null, currentAbsoluteChunkIndex, chunkStartTimeUs, chunkEndTimeUs, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), extractorWrapper);
}
Also used : BehindLiveWindowException(com.google.android.exoplayer2.source.BehindLiveWindowException) ChunkExtractorWrapper(com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper) StreamElement(com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement) Uri(android.net.Uri)

Aggregations

StreamElement (com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)3 Uri (android.net.Uri)1 Timeline (com.google.android.exoplayer2.Timeline)1 BehindLiveWindowException (com.google.android.exoplayer2.source.BehindLiveWindowException)1 SinglePeriodTimeline (com.google.android.exoplayer2.source.SinglePeriodTimeline)1 ChunkExtractorWrapper (com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper)1