Search in sources :

Example 71 with MediaItem

use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.

the class DashMediaSource method processManifest.

private void processManifest(boolean scheduleRefresh) {
    // Update any periods.
    for (int i = 0; i < periodsById.size(); i++) {
        int id = periodsById.keyAt(i);
        if (id >= firstPeriodId) {
            periodsById.valueAt(i).updateManifest(manifest, id - firstPeriodId);
        } else {
        // This period has been removed from the manifest so it doesn't need to be updated.
        }
    }
    // Update the window.
    Period firstPeriod = manifest.getPeriod(0);
    int lastPeriodIndex = manifest.getPeriodCount() - 1;
    Period lastPeriod = manifest.getPeriod(lastPeriodIndex);
    long lastPeriodDurationUs = manifest.getPeriodDurationUs(lastPeriodIndex);
    long nowUnixTimeUs = Util.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
    long windowStartTimeInManifestUs = getAvailableStartTimeInManifestUs(firstPeriod, manifest.getPeriodDurationUs(0), nowUnixTimeUs);
    long windowEndTimeInManifestUs = getAvailableEndTimeInManifestUs(lastPeriod, lastPeriodDurationUs, nowUnixTimeUs);
    boolean windowChangingImplicitly = manifest.dynamic && !isIndexExplicit(lastPeriod);
    if (windowChangingImplicitly && manifest.timeShiftBufferDepthMs != C.TIME_UNSET) {
        // Update the available start time to reflect the manifest's time shift buffer depth.
        long timeShiftBufferStartTimeInManifestUs = windowEndTimeInManifestUs - Util.msToUs(manifest.timeShiftBufferDepthMs);
        windowStartTimeInManifestUs = max(windowStartTimeInManifestUs, timeShiftBufferStartTimeInManifestUs);
    }
    long windowDurationUs = windowEndTimeInManifestUs - windowStartTimeInManifestUs;
    long windowStartUnixTimeMs = C.TIME_UNSET;
    long windowDefaultPositionUs = 0;
    if (manifest.dynamic) {
        checkState(manifest.availabilityStartTimeMs != C.TIME_UNSET);
        long nowInWindowUs = nowUnixTimeUs - Util.msToUs(manifest.availabilityStartTimeMs) - windowStartTimeInManifestUs;
        updateLiveConfiguration(nowInWindowUs, windowDurationUs);
        windowStartUnixTimeMs = manifest.availabilityStartTimeMs + Util.usToMs(windowStartTimeInManifestUs);
        windowDefaultPositionUs = nowInWindowUs - Util.msToUs(liveConfiguration.targetOffsetMs);
        long minimumWindowDefaultPositionUs = min(MIN_LIVE_DEFAULT_START_POSITION_US, windowDurationUs / 2);
        if (windowDefaultPositionUs < minimumWindowDefaultPositionUs) {
            // The default position is too close to the start of the live window. Set it to the minimum
            // default position provided the window is at least twice as big. Else set it to the middle
            // of the window.
            windowDefaultPositionUs = minimumWindowDefaultPositionUs;
        }
    }
    long offsetInFirstPeriodUs = windowStartTimeInManifestUs - Util.msToUs(firstPeriod.startMs);
    DashTimeline timeline = new DashTimeline(manifest.availabilityStartTimeMs, windowStartUnixTimeMs, elapsedRealtimeOffsetMs, firstPeriodId, offsetInFirstPeriodUs, windowDurationUs, windowDefaultPositionUs, manifest, mediaItem, manifest.dynamic ? liveConfiguration : null);
    refreshSourceInfo(timeline);
    if (!sideloadedManifest) {
        // Remove any pending simulated refresh.
        handler.removeCallbacks(simulateManifestRefreshRunnable);
        // If the window is changing implicitly, post a simulated manifest refresh to update it.
        if (windowChangingImplicitly) {
            handler.postDelayed(simulateManifestRefreshRunnable, getIntervalUntilNextManifestRefreshMs(manifest, Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs)));
        }
        if (manifestLoadPending) {
            startLoadingManifest();
        } else if (scheduleRefresh && manifest.dynamic && manifest.minUpdatePeriodMs != C.TIME_UNSET) {
            // Schedule an explicit refresh if needed.
            long minUpdatePeriodMs = manifest.minUpdatePeriodMs;
            if (minUpdatePeriodMs == 0) {
                // TODO: This is a temporary hack to avoid constantly refreshing the MPD in cases where
                // minimumUpdatePeriod is set to 0. In such cases we shouldn't refresh unless there is
                // explicit signaling in the stream, according to:
                // http://azure.microsoft.com/blog/2014/09/13/dash-live-streaming-with-azure-media-service
                minUpdatePeriodMs = 5000;
            }
            long nextLoadTimestampMs = manifestLoadStartTimestampMs + minUpdatePeriodMs;
            long delayUntilNextLoadMs = max(0, nextLoadTimestampMs - SystemClock.elapsedRealtime());
            scheduleManifestRefresh(delayUntilNextLoadMs);
        }
    }
}
Also used : MediaPeriod(com.google.android.exoplayer2.source.MediaPeriod) Period(com.google.android.exoplayer2.source.dash.manifest.Period)

Example 72 with MediaItem

use of com.google.android.exoplayer2.MediaItem 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);
    }
    long startTimeUs = Long.MAX_VALUE;
    long endTimeUs = Long.MIN_VALUE;
    for (StreamElement element : manifest.streamElements) {
        if (element.chunkCount > 0) {
            startTimeUs = min(startTimeUs, element.getStartTimeUs(0));
            endTimeUs = max(endTimeUs, element.getStartTimeUs(element.chunkCount - 1) + element.getChunkDurationUs(element.chunkCount - 1));
        }
    }
    Timeline timeline;
    if (startTimeUs == Long.MAX_VALUE) {
        long periodDurationUs = manifest.isLive ? C.TIME_UNSET : 0;
        timeline = new SinglePeriodTimeline(periodDurationUs, /* windowDurationUs= */
        0, /* windowPositionInPeriodUs= */
        0, /* windowDefaultStartPositionUs= */
        0, /* isSeekable= */
        true, /* isDynamic= */
        manifest.isLive, /* useLiveConfiguration= */
        manifest.isLive, manifest, mediaItem);
    } else if (manifest.isLive) {
        if (manifest.dvrWindowLengthUs != C.TIME_UNSET && manifest.dvrWindowLengthUs > 0) {
            startTimeUs = max(startTimeUs, endTimeUs - manifest.dvrWindowLengthUs);
        }
        long durationUs = endTimeUs - startTimeUs;
        long defaultStartPositionUs = durationUs - Util.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 = min(MIN_LIVE_DEFAULT_START_POSITION_US, durationUs / 2);
        }
        timeline = new SinglePeriodTimeline(/* periodDurationUs= */
        C.TIME_UNSET, durationUs, startTimeUs, defaultStartPositionUs, /* isSeekable= */
        true, /* isDynamic= */
        true, /* useLiveConfiguration= */
        true, manifest, mediaItem);
    } else {
        long durationUs = manifest.durationUs != C.TIME_UNSET ? manifest.durationUs : endTimeUs - startTimeUs;
        timeline = new SinglePeriodTimeline(startTimeUs + durationUs, durationUs, startTimeUs, /* windowDefaultStartPositionUs= */
        0, /* isSeekable= */
        true, /* isDynamic= */
        false, /* useLiveConfiguration= */
        false, manifest, mediaItem);
    }
    refreshSourceInfo(timeline);
}
Also used : Timeline(com.google.android.exoplayer2.Timeline) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) StreamElement(com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement)

Example 73 with MediaItem

use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.

the class TransformerEndToEndTest method startTransformation_audioOnlyTranscoding_completesSuccessfully.

@Test
public void startTransformation_audioOnlyTranscoding_completesSuccessfully() throws Exception {
    Transformer transformer = createTransformerBuilder().setTransformationRequest(new TransformationRequest.Builder().setAudioMimeType(// supported by encoder and muxer
    MimeTypes.AUDIO_AAC).build()).build();
    MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_AUDIO_UNSUPPORTED_BY_ENCODER);
    transformer.startTransformation(mediaItem, outputPath);
    TransformerTestRunner.runUntilCompleted(transformer);
    DumpFileAsserts.assertOutput(context, testMuxer, getDumpFileName(FILE_AUDIO_UNSUPPORTED_BY_ENCODER + ".aac"));
}
Also used : MediaItem(com.google.android.exoplayer2.MediaItem) Test(org.junit.Test)

Example 74 with MediaItem

use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.

the class TransformerEndToEndTest method startTransformation_fromWrongThread_throwsError.

@Test
public void startTransformation_fromWrongThread_throwsError() throws Exception {
    Transformer transformer = createTransformerBuilder().build();
    MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_AUDIO_VIDEO);
    HandlerThread anotherThread = new HandlerThread("AnotherThread");
    AtomicReference<IllegalStateException> illegalStateException = new AtomicReference<>();
    CountDownLatch countDownLatch = new CountDownLatch(1);
    anotherThread.start();
    new Handler(anotherThread.getLooper()).post(() -> {
        try {
            transformer.startTransformation(mediaItem, outputPath);
        } catch (IOException e) {
        // Do nothing.
        } catch (IllegalStateException e) {
            illegalStateException.set(e);
        } finally {
            countDownLatch.countDown();
        }
    });
    countDownLatch.await();
    assertThat(illegalStateException.get()).isNotNull();
}
Also used : HandlerThread(android.os.HandlerThread) MediaItem(com.google.android.exoplayer2.MediaItem) Handler(android.os.Handler) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 75 with MediaItem

use of com.google.android.exoplayer2.MediaItem in project ExoPlayer by google.

the class TransformerEndToEndTest method startTransformation_concurrentTransformations_throwsError.

@Test
public void startTransformation_concurrentTransformations_throwsError() throws Exception {
    Transformer transformer = createTransformerBuilder().build();
    MediaItem mediaItem = MediaItem.fromUri(URI_PREFIX + FILE_VIDEO_ONLY);
    transformer.startTransformation(mediaItem, outputPath);
    assertThrows(IllegalStateException.class, () -> transformer.startTransformation(mediaItem, outputPath));
}
Also used : MediaItem(com.google.android.exoplayer2.MediaItem) Test(org.junit.Test)

Aggregations

MediaItem (com.google.android.exoplayer2.MediaItem)160 Test (org.junit.Test)151 MediaSource (com.google.android.exoplayer2.source.MediaSource)31 ArrayList (java.util.ArrayList)29 Timeline (com.google.android.exoplayer2.Timeline)25 InOrder (org.mockito.InOrder)20 Nullable (androidx.annotation.Nullable)19 AdsMediaSource (com.google.android.exoplayer2.source.ads.AdsMediaSource)19 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)19 Player (com.google.android.exoplayer2.Player)17 Uri (android.net.Uri)15 Listener (com.google.android.exoplayer2.Player.Listener)15 TestPlayerRunHelper.playUntilStartOfMediaItem (com.google.android.exoplayer2.robolectric.TestPlayerRunHelper.playUntilStartOfMediaItem)15 DefaultMediaSourceFactory (com.google.android.exoplayer2.source.DefaultMediaSourceFactory)15 AnalyticsListener (com.google.android.exoplayer2.analytics.AnalyticsListener)13 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)13 TransferListener (com.google.android.exoplayer2.upstream.TransferListener)13 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)13 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)12 ClippingMediaSource (com.google.android.exoplayer2.source.ClippingMediaSource)12