Search in sources :

Example 21 with DataSource

use of androidx.media3.datasource.DataSource in project media by androidx.

the class DashDownloader method addSegmentsForAdaptationSet.

private void addSegmentsForAdaptationSet(DataSource dataSource, AdaptationSet adaptationSet, long periodStartUs, long periodDurationUs, boolean removing, ArrayList<Segment> out) throws IOException, InterruptedException {
    for (int i = 0; i < adaptationSet.representations.size(); i++) {
        Representation representation = adaptationSet.representations.get(i);
        DashSegmentIndex index;
        try {
            index = getSegmentIndex(dataSource, adaptationSet.type, representation, removing);
            if (index == null) {
                // Loading succeeded but there was no index.
                throw new DownloadException("Missing segment index");
            }
        } catch (IOException e) {
            if (!removing) {
                throw e;
            }
            // Generating an incomplete segment list is allowed. Advance to the next representation.
            continue;
        }
        long segmentCount = index.getSegmentCount(periodDurationUs);
        if (segmentCount == DashSegmentIndex.INDEX_UNBOUNDED) {
            throw new DownloadException("Unbounded segment index");
        }
        String baseUrl = castNonNull(baseUrlExclusionList.selectBaseUrl(representation.baseUrls)).url;
        @Nullable RangedUri initializationUri = representation.getInitializationUri();
        if (initializationUri != null) {
            out.add(createSegment(representation, baseUrl, periodStartUs, initializationUri));
        }
        @Nullable RangedUri indexUri = representation.getIndexUri();
        if (indexUri != null) {
            out.add(createSegment(representation, baseUrl, periodStartUs, indexUri));
        }
        long firstSegmentNum = index.getFirstSegmentNum();
        long lastSegmentNum = firstSegmentNum + segmentCount - 1;
        for (long j = firstSegmentNum; j <= lastSegmentNum; j++) {
            out.add(createSegment(representation, baseUrl, periodStartUs + index.getTimeUs(j), index.getSegmentUrl(j)));
        }
    }
}
Also used : DownloadException(androidx.media3.exoplayer.offline.DownloadException) RangedUri(androidx.media3.exoplayer.dash.manifest.RangedUri) Representation(androidx.media3.exoplayer.dash.manifest.Representation) IOException(java.io.IOException) DashSegmentIndex(androidx.media3.exoplayer.dash.DashSegmentIndex) Nullable(androidx.annotation.Nullable)

Example 22 with DataSource

use of androidx.media3.datasource.DataSource in project media by androidx.

the class DefaultSsChunkSource method newMediaChunk.

// Private methods.
private static MediaChunk newMediaChunk(Format format, DataSource dataSource, Uri uri, int chunkIndex, long chunkStartTimeUs, long chunkEndTimeUs, long chunkSeekTimeUs, @C.SelectionReason int trackSelectionReason, @Nullable Object trackSelectionData, ChunkExtractor chunkExtractor) {
    DataSpec dataSpec = new DataSpec(uri);
    // In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
    // To convert them the absolute timestamps, we need to set sampleOffsetUs to chunkStartTimeUs.
    long sampleOffsetUs = chunkStartTimeUs;
    return new ContainerMediaChunk(dataSource, dataSpec, format, trackSelectionReason, trackSelectionData, chunkStartTimeUs, chunkEndTimeUs, chunkSeekTimeUs, /* clippedEndTimeUs= */
    C.TIME_UNSET, chunkIndex, /* chunkCount= */
    1, sampleOffsetUs, chunkExtractor);
}
Also used : DataSpec(androidx.media3.datasource.DataSpec) ContainerMediaChunk(androidx.media3.exoplayer.source.chunk.ContainerMediaChunk)

Example 23 with DataSource

use of androidx.media3.datasource.DataSource in project media by androidx.

the class DefaultSsChunkSource method getNextChunk.

@Override
public final void getNextChunk(long playbackPositionUs, long loadPositionUs, List<? extends MediaChunk> queue, ChunkHolder out) {
    if (fatalError != null) {
        return;
    }
    StreamElement streamElement = manifest.streamElements[streamElementIndex];
    if (streamElement.chunkCount == 0) {
        // There aren't any chunks for us to load.
        out.endOfStream = !manifest.isLive;
        return;
    }
    int chunkIndex;
    if (queue.isEmpty()) {
        chunkIndex = streamElement.getChunkIndex(loadPositionUs);
    } else {
        chunkIndex = (int) (queue.get(queue.size() - 1).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 bufferedDurationUs = loadPositionUs - playbackPositionUs;
    long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
    MediaChunkIterator[] chunkIterators = new MediaChunkIterator[trackSelection.length()];
    for (int i = 0; i < chunkIterators.length; i++) {
        int trackIndex = trackSelection.getIndexInTrackGroup(i);
        chunkIterators[i] = new StreamElementIterator(streamElement, trackIndex, chunkIndex);
    }
    trackSelection.updateSelectedTrack(playbackPositionUs, bufferedDurationUs, timeToLiveEdgeUs, queue, chunkIterators);
    long chunkStartTimeUs = streamElement.getStartTimeUs(chunkIndex);
    long chunkEndTimeUs = chunkStartTimeUs + streamElement.getChunkDurationUs(chunkIndex);
    long chunkSeekTimeUs = queue.isEmpty() ? loadPositionUs : C.TIME_UNSET;
    int currentAbsoluteChunkIndex = chunkIndex + currentManifestChunkOffset;
    int trackSelectionIndex = trackSelection.getSelectedIndex();
    ChunkExtractor chunkExtractor = chunkExtractors[trackSelectionIndex];
    int manifestTrackIndex = trackSelection.getIndexInTrackGroup(trackSelectionIndex);
    Uri uri = streamElement.buildRequestUri(manifestTrackIndex, chunkIndex);
    out.chunk = newMediaChunk(trackSelection.getSelectedFormat(), dataSource, uri, currentAbsoluteChunkIndex, chunkStartTimeUs, chunkEndTimeUs, chunkSeekTimeUs, trackSelection.getSelectionReason(), trackSelection.getSelectionData(), chunkExtractor);
}
Also used : BaseMediaChunkIterator(androidx.media3.exoplayer.source.chunk.BaseMediaChunkIterator) MediaChunkIterator(androidx.media3.exoplayer.source.chunk.MediaChunkIterator) BehindLiveWindowException(androidx.media3.exoplayer.source.BehindLiveWindowException) StreamElement(androidx.media3.exoplayer.smoothstreaming.manifest.SsManifest.StreamElement) ChunkExtractor(androidx.media3.exoplayer.source.chunk.ChunkExtractor) BundledChunkExtractor(androidx.media3.exoplayer.source.chunk.BundledChunkExtractor) Uri(android.net.Uri)

Example 24 with DataSource

use of androidx.media3.datasource.DataSource in project media by androidx.

the class AmrExtractorSeekTest method seeking_handlesSeekingForward_extractsCorrectFrames_forNarrowBandAmr.

@Test
public void seeking_handlesSeekingForward_extractsCorrectFrames_forNarrowBandAmr() throws IOException {
    String fileName = NARROW_BAND_AMR_FILE;
    Uri fileUri = TestUtil.buildAssetUri(fileName);
    expectedTrackOutput = TestUtil.extractAllSamplesFromFile(createAmrExtractor(), ApplicationProvider.getApplicationContext(), fileName).trackOutputs.get(0);
    AmrExtractor extractor = createAmrExtractor();
    FakeExtractorOutput extractorOutput = new FakeExtractorOutput();
    SeekMap seekMap = TestUtil.extractSeekMap(extractor, extractorOutput, dataSource, fileUri);
    FakeTrackOutput trackOutput = extractorOutput.trackOutputs.get(0);
    long firstSeekTimeUs = 980_000;
    TestUtil.seekToTimeUs(extractor, seekMap, firstSeekTimeUs, dataSource, trackOutput, fileUri);
    long targetSeekTimeUs = 1_200_000;
    int extractedFrameIndex = TestUtil.seekToTimeUs(extractor, seekMap, targetSeekTimeUs, dataSource, trackOutput, fileUri);
    assertThat(extractedFrameIndex).isNotEqualTo(-1);
    assertFirstFrameAfterSeekContainTargetSeekTime(trackOutput, targetSeekTimeUs, extractedFrameIndex);
}
Also used : FakeTrackOutput(androidx.media3.test.utils.FakeTrackOutput) SeekMap(androidx.media3.extractor.SeekMap) Uri(android.net.Uri) FakeExtractorOutput(androidx.media3.test.utils.FakeExtractorOutput) Test(org.junit.Test)

Example 25 with DataSource

use of androidx.media3.datasource.DataSource in project media by androidx.

the class AmrExtractorSeekTest method amrExtractorReads_returnSeekableSeekMap_forNarrowBandAmr.

@Test
public void amrExtractorReads_returnSeekableSeekMap_forNarrowBandAmr() throws IOException {
    String fileName = NARROW_BAND_AMR_FILE;
    Uri fileUri = TestUtil.buildAssetUri(fileName);
    expectedTrackOutput = TestUtil.extractAllSamplesFromFile(createAmrExtractor(), ApplicationProvider.getApplicationContext(), fileName).trackOutputs.get(0);
    AmrExtractor extractor = createAmrExtractor();
    SeekMap seekMap = TestUtil.extractSeekMap(extractor, new FakeExtractorOutput(), dataSource, fileUri);
    assertThat(seekMap).isNotNull();
    assertThat(seekMap.getDurationUs()).isEqualTo(NARROW_BAND_FILE_DURATION_US);
    assertThat(seekMap.isSeekable()).isTrue();
}
Also used : SeekMap(androidx.media3.extractor.SeekMap) Uri(android.net.Uri) FakeExtractorOutput(androidx.media3.test.utils.FakeExtractorOutput) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)101 Uri (android.net.Uri)72 SeekMap (androidx.media3.extractor.SeekMap)65 DataSpec (androidx.media3.datasource.DataSpec)56 FakeTrackOutput (androidx.media3.test.utils.FakeTrackOutput)50 FakeExtractorOutput (androidx.media3.test.utils.FakeExtractorOutput)29 DataSource (androidx.media3.datasource.DataSource)25 Nullable (androidx.annotation.Nullable)13 IOException (java.io.IOException)13 DefaultExtractorInput (androidx.media3.extractor.DefaultExtractorInput)12 ExtractorInput (androidx.media3.extractor.ExtractorInput)10 FakeDataSource (androidx.media3.test.utils.FakeDataSource)10 StatsDataSource (androidx.media3.datasource.StatsDataSource)8 FakeDataSet (androidx.media3.test.utils.FakeDataSet)7 RangedUri (androidx.media3.exoplayer.dash.manifest.RangedUri)5 Representation (androidx.media3.exoplayer.dash.manifest.Representation)5 Before (org.junit.Before)5 Format (androidx.media3.common.Format)3 DataSourceInputStream (androidx.media3.datasource.DataSourceInputStream)3 FileDataSource (androidx.media3.datasource.FileDataSource)3