Search in sources :

Example 96 with ExoPlayer

use of androidx.media3.exoplayer.ExoPlayer in project media by androidx.

the class DefaultHlsExtractorFactory method createExtractor.

@Override
public BundledHlsMediaChunkExtractor createExtractor(Uri uri, Format format, @Nullable List<Format> muxedCaptionFormats, TimestampAdjuster timestampAdjuster, Map<String, List<String>> responseHeaders, ExtractorInput sniffingExtractorInput, PlayerId playerId) throws IOException {
    @FileTypes.Type int formatInferredFileType = FileTypes.inferFileTypeFromMimeType(format.sampleMimeType);
    @FileTypes.Type int responseHeadersInferredFileType = FileTypes.inferFileTypeFromResponseHeaders(responseHeaders);
    @FileTypes.Type int uriInferredFileType = FileTypes.inferFileTypeFromUri(uri);
    // Defines the order in which to try the extractors.
    List<Integer> fileTypeOrder = new ArrayList<>(/* initialCapacity= */
    DEFAULT_EXTRACTOR_ORDER.length);
    addFileTypeIfValidAndNotPresent(formatInferredFileType, fileTypeOrder);
    addFileTypeIfValidAndNotPresent(responseHeadersInferredFileType, fileTypeOrder);
    addFileTypeIfValidAndNotPresent(uriInferredFileType, fileTypeOrder);
    for (int fileType : DEFAULT_EXTRACTOR_ORDER) {
        addFileTypeIfValidAndNotPresent(fileType, fileTypeOrder);
    }
    // Extractor to be used if the type is not recognized.
    @Nullable Extractor fallBackExtractor = null;
    sniffingExtractorInput.resetPeekPosition();
    for (int i = 0; i < fileTypeOrder.size(); i++) {
        int fileType = fileTypeOrder.get(i);
        Extractor extractor = checkNotNull(createExtractorByFileType(fileType, format, muxedCaptionFormats, timestampAdjuster));
        if (sniffQuietly(extractor, sniffingExtractorInput)) {
            return new BundledHlsMediaChunkExtractor(extractor, format, timestampAdjuster);
        }
        if (fallBackExtractor == null && (fileType == formatInferredFileType || fileType == responseHeadersInferredFileType || fileType == uriInferredFileType || fileType == FileTypes.TS)) {
            // If sniffing fails, fallback to the file types inferred from context. If all else fails,
            // fallback to Transport Stream. See https://github.com/google/ExoPlayer/issues/8219.
            fallBackExtractor = extractor;
        }
    }
    return new BundledHlsMediaChunkExtractor(checkNotNull(fallBackExtractor), format, timestampAdjuster);
}
Also used : ArrayList(java.util.ArrayList) Ac4Extractor(androidx.media3.extractor.ts.Ac4Extractor) Extractor(androidx.media3.extractor.Extractor) TsExtractor(androidx.media3.extractor.ts.TsExtractor) AdtsExtractor(androidx.media3.extractor.ts.AdtsExtractor) Mp3Extractor(androidx.media3.extractor.mp3.Mp3Extractor) Ac3Extractor(androidx.media3.extractor.ts.Ac3Extractor) FragmentedMp4Extractor(androidx.media3.extractor.mp4.FragmentedMp4Extractor) SuppressLint(android.annotation.SuppressLint) Nullable(androidx.annotation.Nullable)

Example 97 with ExoPlayer

use of androidx.media3.exoplayer.ExoPlayer in project media by androidx.

the class DashPlaybackTest method emsgNearToPeriodBoundary.

// https://github.com/google/ExoPlayer/issues/8710
@Test
public void emsgNearToPeriodBoundary() throws Exception {
    Context applicationContext = ApplicationProvider.getApplicationContext();
    CapturingRenderersFactory capturingRenderersFactory = new CapturingRenderersFactory(applicationContext);
    ExoPlayer player = new ExoPlayer.Builder(applicationContext, capturingRenderersFactory).setClock(new FakeClock(/* isAutoAdvancing= */
    true)).build();
    player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */
    1)));
    PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
    player.setMediaItem(MediaItem.fromUri("asset:///media/dash/emsg/sample.mpd"));
    player.prepare();
    player.play();
    TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
    player.release();
    DumpFileAsserts.assertOutput(applicationContext, playbackOutput, "playbackdumps/dash/emsg.dump");
}
Also used : Context(android.content.Context) PlaybackOutput(androidx.media3.test.utils.robolectric.PlaybackOutput) SurfaceTexture(android.graphics.SurfaceTexture) CapturingRenderersFactory(androidx.media3.test.utils.CapturingRenderersFactory) FakeClock(androidx.media3.test.utils.FakeClock) ExoPlayer(androidx.media3.exoplayer.ExoPlayer) Surface(android.view.Surface) Test(org.junit.Test)

Example 98 with ExoPlayer

use of androidx.media3.exoplayer.ExoPlayer in project media by androidx.

the class HlsMediaPlaylistParserTest method parseMediaPlaylist.

@Test
public void parseMediaPlaylist() throws Exception {
    Uri playlistUri = Uri.parse("https://example.com/test.m3u8");
    String playlistString = "#EXTM3U\n" + "#EXT-X-VERSION:3\n" + "#EXT-X-PLAYLIST-TYPE:VOD\n" + "#EXT-X-START:TIME-OFFSET=-25\n" + "#EXT-X-TARGETDURATION:8\n" + "#EXT-X-MEDIA-SEQUENCE:2679\n" + "#EXT-X-DISCONTINUITY-SEQUENCE:4\n" + "#EXT-X-ALLOW-CACHE:YES\n" + "\n" + "#EXTINF:7.975,\n" + "#EXT-X-BYTERANGE:51370@0\n" + "https://priv.example.com/fileSequence2679.ts\n" + "\n" + "#EXT-X-KEY:METHOD=AES-128," + "URI=\"https://priv.example.com/key.php?r=2680\",IV=0x1566B\n" + "#EXTINF:7.975,segment title\n" + "#EXT-X-BYTERANGE:51501@2147483648\n" + "https://priv.example.com/fileSequence2680.ts\n" + "\n" + "#EXT-X-KEY:METHOD=NONE\n" + "#EXTINF:7.941,segment title .,:/# with interesting chars\n" + // @2147535149
    "#EXT-X-BYTERANGE:51501\n" + "https://priv.example.com/fileSequence2681.ts\n" + "\n" + "#EXT-X-DISCONTINUITY\n" + "#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=2682\"\n" + // Trailing comma is omitted.
    "#EXTINF:7.975\n" + // @2147586650
    "#EXT-X-BYTERANGE:51740\n" + "https://priv.example.com/fileSequence2682.ts\n" + "\n" + "#EXTINF:7.975,\n" + "https://priv.example.com/fileSequence2683.ts\n" + "\n" + // 2.002 tests correct rounding, see https://github.com/google/ExoPlayer/issues/9575.
    "#EXTINF:2.002,\n" + "https://priv.example.com/fileSequence2684.ts\n" + "#EXT-X-ENDLIST";
    InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
    HlsPlaylist playlist = new HlsPlaylistParser().parse(playlistUri, inputStream);
    HlsMediaPlaylist mediaPlaylist = (HlsMediaPlaylist) playlist;
    assertThat(mediaPlaylist.playlistType).isEqualTo(HlsMediaPlaylist.PLAYLIST_TYPE_VOD);
    assertThat(mediaPlaylist.startOffsetUs).isEqualTo(mediaPlaylist.durationUs - 25000000);
    assertThat(mediaPlaylist.mediaSequence).isEqualTo(2679);
    assertThat(mediaPlaylist.version).isEqualTo(3);
    assertThat(mediaPlaylist.hasEndTag).isTrue();
    assertThat(mediaPlaylist.protectionSchemes).isNull();
    assertThat(mediaPlaylist.targetDurationUs).isEqualTo(8000000);
    assertThat(mediaPlaylist.partTargetDurationUs).isEqualTo(C.TIME_UNSET);
    List<Segment> segments = mediaPlaylist.segments;
    assertThat(segments).isNotNull();
    assertThat(segments).hasSize(6);
    Segment segment = segments.get(0);
    assertThat(mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence).isEqualTo(4);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
    assertThat(segment.encryptionIV).isNull();
    assertThat(segment.byteRangeLength).isEqualTo(51370);
    assertThat(segment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2679.ts");
    segment = segments.get(1);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("segment title");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2680");
    assertThat(segment.encryptionIV).isEqualTo("0x1566B");
    assertThat(segment.byteRangeLength).isEqualTo(51501);
    assertThat(segment.byteRangeOffset).isEqualTo(2147483648L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2680.ts");
    segment = segments.get(2);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
    assertThat(segment.durationUs).isEqualTo(7941000);
    assertThat(segment.title).isEqualTo("segment title .,:/# with interesting chars");
    assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
    assertThat(segment.encryptionIV).isEqualTo(null);
    assertThat(segment.byteRangeLength).isEqualTo(51501);
    assertThat(segment.byteRangeOffset).isEqualTo(2147535149L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2681.ts");
    segment = segments.get(3);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2682");
    // 0xA7A == 2682.
    assertThat(segment.encryptionIV).isNotNull();
    assertThat(segment.encryptionIV).ignoringCase().isEqualTo("A7A");
    assertThat(segment.byteRangeLength).isEqualTo(51740);
    assertThat(segment.byteRangeOffset).isEqualTo(2147586650L);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2682.ts");
    segment = segments.get(4);
    assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
    assertThat(segment.durationUs).isEqualTo(7975000);
    assertThat(segment.title).isEqualTo("");
    assertThat(segment.fullSegmentEncryptionKeyUri).isEqualTo("https://priv.example.com/key.php?r=2682");
    // 0xA7B == 2683.
    assertThat(segment.encryptionIV).isNotNull();
    assertThat(segment.encryptionIV).ignoringCase().isEqualTo("A7B");
    assertThat(segment.byteRangeLength).isEqualTo(C.LENGTH_UNSET);
    assertThat(segment.byteRangeOffset).isEqualTo(0);
    assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2683.ts");
    segment = segments.get(5);
    assertThat(segment.durationUs).isEqualTo(2002000);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Uri(android.net.Uri) Segment(androidx.media3.exoplayer.hls.playlist.HlsMediaPlaylist.Segment) Test(org.junit.Test)

Example 99 with ExoPlayer

use of androidx.media3.exoplayer.ExoPlayer in project media by androidx.

the class AdTagLoader method loadAdInternal.

private void loadAdInternal(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) {
    if (adsManager == null) {
        // Drop events after release.
        if (configuration.debugModeEnabled) {
            Log.d(TAG, "loadAd after release " + getAdMediaInfoString(adMediaInfo) + ", ad pod " + adPodInfo);
        }
        return;
    }
    int adGroupIndex = getAdGroupIndexForAdPod(adPodInfo);
    int adIndexInAdGroup = adPodInfo.getAdPosition() - 1;
    AdInfo adInfo = new AdInfo(adGroupIndex, adIndexInAdGroup);
    // The ad URI may already be known, so force put to update it if needed.
    adInfoByAdMediaInfo.forcePut(adMediaInfo, adInfo);
    if (configuration.debugModeEnabled) {
        Log.d(TAG, "loadAd " + getAdMediaInfoString(adMediaInfo));
    }
    if (adPlaybackState.isAdInErrorState(adGroupIndex, adIndexInAdGroup)) {
        // timeout after its media load timeout.
        return;
    }
    // The ad count may increase on successive loads of ads in the same ad pod, for example, due to
    // separate requests for ad tags with multiple ads within the ad pod completing after an earlier
    // ad has loaded. See also https://github.com/google/ExoPlayer/issues/7477.
    AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adInfo.adGroupIndex);
    adPlaybackState = adPlaybackState.withAdCount(adInfo.adGroupIndex, max(adPodInfo.getTotalAds(), adGroup.states.length));
    adGroup = adPlaybackState.getAdGroup(adInfo.adGroupIndex);
    for (int i = 0; i < adIndexInAdGroup; i++) {
        // Any preceding ads that haven't loaded are not going to load.
        if (adGroup.states[i] == AdPlaybackState.AD_STATE_UNAVAILABLE) {
            adPlaybackState = adPlaybackState.withAdLoadError(adGroupIndex, /* adIndexInAdGroup= */
            i);
        }
    }
    Uri adUri = Uri.parse(adMediaInfo.getUrl());
    adPlaybackState = adPlaybackState.withAdUri(adInfo.adGroupIndex, adInfo.adIndexInAdGroup, adUri);
    updateAdPlaybackState();
}
Also used : AdPlaybackState(androidx.media3.common.AdPlaybackState) Uri(android.net.Uri)

Example 100 with ExoPlayer

use of androidx.media3.exoplayer.ExoPlayer in project media by androidx.

the class RtspMediaPeriodTest method prepareMediaPeriod_refreshesSourceInfoAndCallsOnPrepared.

@Test
public void prepareMediaPeriod_refreshesSourceInfoAndCallsOnPrepared() throws Exception {
    RtpPacketStreamDump rtpPacketStreamDump = RtspTestUtils.readRtpPacketStreamDump("media/rtsp/aac-dump.json");
    rtspServer = new RtspServer(new RtspServer.ResponseProvider() {

        @Override
        public RtspResponse getOptionsResponse() {
            return new RtspResponse(/* status= */
            200, new RtspHeaders.Builder().add(RtspHeaders.PUBLIC, "OPTIONS, DESCRIBE").build());
        }

        @Override
        public RtspResponse getDescribeResponse(Uri requestedUri, RtspHeaders headers) {
            return RtspTestUtils.newDescribeResponseWithSdpMessage("v=0\r\n" + "o=- 1606776316530225 1 IN IP4 127.0.0.1\r\n" + "s=Exoplayer test\r\n" + "t=0 0\r\n" + // The session is 50.46s long.
            "a=range:npt=0-50.46\r\n", ImmutableList.of(rtpPacketStreamDump), requestedUri);
        }
    });
    AtomicBoolean prepareCallbackCalled = new AtomicBoolean();
    AtomicLong refreshedSourceDurationMs = new AtomicLong();
    mediaPeriod = new RtspMediaPeriod(new DefaultAllocator(/* trimOnReset= */
    true, C.DEFAULT_BUFFER_SEGMENT_SIZE), new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), RtspTestUtils.getTestUri(rtspServer.startAndGetPortNumber()), /* listener= */
    timing -> refreshedSourceDurationMs.set(timing.getDurationMs()), /* userAgent= */
    "ExoPlayer:RtspPeriodTest", /* socketFactory= */
    SocketFactory.getDefault(), /* debugLoggingEnabled= */
    false);
    mediaPeriod.prepare(new MediaPeriod.Callback() {

        @Override
        public void onPrepared(MediaPeriod mediaPeriod) {
            prepareCallbackCalled.set(true);
        }

        @Override
        public void onContinueLoadingRequested(MediaPeriod source) {
            source.continueLoading(/* positionUs= */
            0);
        }
    }, /* positionUs= */
    0);
    RobolectricUtil.runMainLooperUntil(prepareCallbackCalled::get);
    mediaPeriod.release();
    assertThat(refreshedSourceDurationMs.get()).isEqualTo(50_460);
}
Also used : Uri(android.net.Uri) RunWith(org.junit.runner.RunWith) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test) Truth.assertThat(com.google.common.truth.Truth.assertThat) Util(androidx.media3.common.util.Util) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) DefaultAllocator(androidx.media3.exoplayer.upstream.DefaultAllocator) SocketFactory(javax.net.SocketFactory) C(androidx.media3.common.C) AtomicLong(java.util.concurrent.atomic.AtomicLong) ImmutableList(com.google.common.collect.ImmutableList) RobolectricUtil(androidx.media3.test.utils.robolectric.RobolectricUtil) After(org.junit.After) MediaPeriod(androidx.media3.exoplayer.source.MediaPeriod) Uri(android.net.Uri) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) DefaultAllocator(androidx.media3.exoplayer.upstream.DefaultAllocator) MediaPeriod(androidx.media3.exoplayer.source.MediaPeriod) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)242 FakeMediaSource (androidx.media3.test.utils.FakeMediaSource)179 TestExoPlayerBuilder (androidx.media3.test.utils.TestExoPlayerBuilder)172 FakeTimeline (androidx.media3.test.utils.FakeTimeline)121 PlayerRunnable (androidx.media3.test.utils.ActionSchedule.PlayerRunnable)108 Timeline (androidx.media3.common.Timeline)96 ActionSchedule (androidx.media3.test.utils.ActionSchedule)92 SinglePeriodTimeline (androidx.media3.exoplayer.source.SinglePeriodTimeline)89 NoUidTimeline (androidx.media3.test.utils.NoUidTimeline)89 Listener (androidx.media3.common.Player.Listener)85 Player (androidx.media3.common.Player)83 TimelineWindowDefinition (androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition)73 ExoPlayerTestRunner (androidx.media3.test.utils.ExoPlayerTestRunner)67 ConcatenatingMediaSource (androidx.media3.exoplayer.source.ConcatenatingMediaSource)64 MediaSource (androidx.media3.exoplayer.source.MediaSource)52 MediaItem (androidx.media3.common.MediaItem)48 FakeClock (androidx.media3.test.utils.FakeClock)48 ClippingMediaSource (androidx.media3.exoplayer.source.ClippingMediaSource)47 CompositeMediaSource (androidx.media3.exoplayer.source.CompositeMediaSource)47 MaskingMediaSource (androidx.media3.exoplayer.source.MaskingMediaSource)47