Search in sources :

Example 1 with LoadControl

use of com.google.android.exoplayer2.LoadControl in project Signal-Android by signalapp.

the class VideoPlayer method setExoViewSource.

private void setExoViewSource(@NonNull VideoSlide videoSource, boolean autoplay) throws IOException {
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
    LoadControl loadControl = new DefaultLoadControl();
    exoPlayer = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
    exoPlayer.addListener(new ExoPlayerListener(window));
    // noinspection ConstantConditions
    exoView.setPlayer(exoPlayer);
    DefaultDataSourceFactory defaultDataSourceFactory = new DefaultDataSourceFactory(getContext(), "GenericUserAgent", null);
    AttachmentDataSourceFactory attachmentDataSourceFactory = new AttachmentDataSourceFactory(getContext(), defaultDataSourceFactory, null);
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
    MediaSource mediaSource = new ExtractorMediaSource(videoSource.getUri(), attachmentDataSourceFactory, extractorsFactory, null, null);
    exoPlayer.prepare(mediaSource);
    exoPlayer.setPlayWhenReady(autoplay);
}
Also used : DefaultExtractorsFactory(com.google.android.exoplayer2.extractor.DefaultExtractorsFactory) DefaultBandwidthMeter(com.google.android.exoplayer2.upstream.DefaultBandwidthMeter) DefaultLoadControl(com.google.android.exoplayer2.DefaultLoadControl) LoadControl(com.google.android.exoplayer2.LoadControl) TrackSelector(com.google.android.exoplayer2.trackselection.TrackSelector) DefaultTrackSelector(com.google.android.exoplayer2.trackselection.DefaultTrackSelector) AttachmentDataSourceFactory(org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory) DefaultDataSourceFactory(com.google.android.exoplayer2.upstream.DefaultDataSourceFactory) ExoPlayerFactory(com.google.android.exoplayer2.ExoPlayerFactory) ExtractorsFactory(com.google.android.exoplayer2.extractor.ExtractorsFactory) DefaultExtractorsFactory(com.google.android.exoplayer2.extractor.DefaultExtractorsFactory) ExtractorMediaSource(com.google.android.exoplayer2.source.ExtractorMediaSource) DefaultLoadControl(com.google.android.exoplayer2.DefaultLoadControl) ExtractorMediaSource(com.google.android.exoplayer2.source.ExtractorMediaSource) MediaSource(com.google.android.exoplayer2.source.MediaSource) ExtractorsFactory(com.google.android.exoplayer2.extractor.ExtractorsFactory) DefaultExtractorsFactory(com.google.android.exoplayer2.extractor.DefaultExtractorsFactory) DefaultDataSourceFactory(com.google.android.exoplayer2.upstream.DefaultDataSourceFactory) BandwidthMeter(com.google.android.exoplayer2.upstream.BandwidthMeter) DefaultBandwidthMeter(com.google.android.exoplayer2.upstream.DefaultBandwidthMeter) DefaultTrackSelector(com.google.android.exoplayer2.trackselection.DefaultTrackSelector) TrackSelection(com.google.android.exoplayer2.trackselection.TrackSelection) AdaptiveTrackSelection(com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection) AttachmentDataSourceFactory(org.thoughtcrime.securesms.video.exo.AttachmentDataSourceFactory)

Example 2 with LoadControl

use of com.google.android.exoplayer2.LoadControl in project NewPipe by TeamNewPipe.

the class BasePlayer method initPlayer.

public void initPlayer() {
    if (DEBUG)
        Log.d(TAG, "initPlayer() called with: context = [" + context + "]");
    if (databaseUpdateReactor != null)
        databaseUpdateReactor.dispose();
    databaseUpdateReactor = new CompositeDisposable();
    final String userAgent = Downloader.USER_AGENT;
    final DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    dataSource = new PlayerDataSource(context, userAgent, bandwidthMeter);
    final AdaptiveTrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    trackSelector = new CustomTrackSelector(trackSelectionFactory);
    final LoadControl loadControl = new LoadController(context);
    final RenderersFactory renderFactory = new DefaultRenderersFactory(context);
    simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(renderFactory, trackSelector, loadControl);
    simpleExoPlayer.addListener(this);
    simpleExoPlayer.setPlayWhenReady(true);
    simpleExoPlayer.setSeekParameters(PlayerHelper.getSeekParameters(context));
    audioReactor = new AudioReactor(context, simpleExoPlayer);
    mediaSessionManager = new MediaSessionManager(context, simpleExoPlayer, new BasePlayerMediaSession(this));
}
Also used : DefaultBandwidthMeter(com.google.android.exoplayer2.upstream.DefaultBandwidthMeter) LoadControl(com.google.android.exoplayer2.LoadControl) RenderersFactory(com.google.android.exoplayer2.RenderersFactory) ExoPlayerFactory(com.google.android.exoplayer2.ExoPlayerFactory) DefaultRenderersFactory(com.google.android.exoplayer2.DefaultRenderersFactory) MediaSessionManager(org.schabi.newpipe.player.helper.MediaSessionManager) PlayerHelper.getTimeString(org.schabi.newpipe.player.helper.PlayerHelper.getTimeString) RenderersFactory(com.google.android.exoplayer2.RenderersFactory) DefaultRenderersFactory(com.google.android.exoplayer2.DefaultRenderersFactory) AudioReactor(org.schabi.newpipe.player.helper.AudioReactor) BasePlayerMediaSession(org.schabi.newpipe.player.playback.BasePlayerMediaSession) PlayerDataSource(org.schabi.newpipe.player.helper.PlayerDataSource) AdaptiveTrackSelection(com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection) CustomTrackSelector(org.schabi.newpipe.player.playback.CustomTrackSelector) DefaultRenderersFactory(com.google.android.exoplayer2.DefaultRenderersFactory) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) LoadController(org.schabi.newpipe.player.helper.LoadController)

Example 3 with LoadControl

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

the class ExoPlayerImplInternal method doSomeWork.

private void doSomeWork() throws ExoPlaybackException, IOException {
    long operationStartTimeMs = clock.uptimeMillis();
    updatePeriods();
    if (playbackInfo.playbackState == Player.STATE_IDLE || playbackInfo.playbackState == Player.STATE_ENDED) {
        // Remove all messages. Prepare (in case of IDLE) or seek (in case of ENDED) will resume.
        handler.removeMessages(MSG_DO_SOME_WORK);
        return;
    }
    @Nullable MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod();
    if (playingPeriodHolder == null) {
        // We're still waiting until the playing period is available.
        scheduleNextWork(operationStartTimeMs, ACTIVE_INTERVAL_MS);
        return;
    }
    TraceUtil.beginSection("doSomeWork");
    updatePlaybackPositions();
    boolean renderersEnded = true;
    boolean renderersAllowPlayback = true;
    if (playingPeriodHolder.prepared) {
        long rendererPositionElapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
        playingPeriodHolder.mediaPeriod.discardBuffer(playbackInfo.positionUs - backBufferDurationUs, retainBackBufferFromKeyframe);
        for (int i = 0; i < renderers.length; i++) {
            Renderer renderer = renderers[i];
            if (!isRendererEnabled(renderer)) {
                continue;
            }
            // TODO: Each renderer should return the maximum delay before which it wishes to be called
            // again. The minimum of these values should then be used as the delay before the next
            // invocation of this method.
            renderer.render(rendererPositionUs, rendererPositionElapsedRealtimeUs);
            renderersEnded = renderersEnded && renderer.isEnded();
            // Determine whether the renderer allows playback to continue. Playback can continue if the
            // renderer is ready or ended. Also continue playback if the renderer is reading ahead into
            // the next stream or is waiting for the next stream. This is to avoid getting stuck if
            // tracks in the current period have uneven durations and are still being read by another
            // renderer. See: https://github.com/google/ExoPlayer/issues/1874.
            boolean isReadingAhead = playingPeriodHolder.sampleStreams[i] != renderer.getStream();
            boolean isWaitingForNextStream = !isReadingAhead && renderer.hasReadStreamToEnd();
            boolean allowsPlayback = isReadingAhead || isWaitingForNextStream || renderer.isReady() || renderer.isEnded();
            renderersAllowPlayback = renderersAllowPlayback && allowsPlayback;
            if (!allowsPlayback) {
                renderer.maybeThrowStreamError();
            }
        }
    } else {
        playingPeriodHolder.mediaPeriod.maybeThrowPrepareError();
    }
    long playingPeriodDurationUs = playingPeriodHolder.info.durationUs;
    boolean finishedRendering = renderersEnded && playingPeriodHolder.prepared && (playingPeriodDurationUs == C.TIME_UNSET || playingPeriodDurationUs <= playbackInfo.positionUs);
    if (finishedRendering && pendingPauseAtEndOfPeriod) {
        pendingPauseAtEndOfPeriod = false;
        setPlayWhenReadyInternal(/* playWhenReady= */
        false, playbackInfo.playbackSuppressionReason, /* operationAck= */
        false, Player.PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM);
    }
    if (finishedRendering && playingPeriodHolder.info.isFinal) {
        setState(Player.STATE_ENDED);
        stopRenderers();
    } else if (playbackInfo.playbackState == Player.STATE_BUFFERING && shouldTransitionToReadyState(renderersAllowPlayback)) {
        setState(Player.STATE_READY);
        // Any pending error was successfully recovered from.
        pendingRecoverableRendererError = null;
        if (shouldPlayWhenReady()) {
            startRenderers();
        }
    } else if (playbackInfo.playbackState == Player.STATE_READY && !(enabledRendererCount == 0 ? isTimelineReady() : renderersAllowPlayback)) {
        isRebuffering = shouldPlayWhenReady();
        setState(Player.STATE_BUFFERING);
        if (isRebuffering) {
            notifyTrackSelectionRebuffer();
            livePlaybackSpeedControl.notifyRebuffer();
        }
        stopRenderers();
    }
    boolean playbackMaybeStuck = false;
    if (playbackInfo.playbackState == Player.STATE_BUFFERING) {
        for (int i = 0; i < renderers.length; i++) {
            if (isRendererEnabled(renderers[i]) && renderers[i].getStream() == playingPeriodHolder.sampleStreams[i]) {
                renderers[i].maybeThrowStreamError();
            }
        }
        if (!playbackInfo.isLoading && playbackInfo.totalBufferedDurationUs < 500_000 && isLoadingPossible()) {
            // The renderers are not ready, there is more media available to load, and the LoadControl
            // is refusing to load it (indicated by !playbackInfo.isLoading). This could be because the
            // renderers are still transitioning to their ready states, but it could also indicate a
            // stuck playback. The playbackInfo.totalBufferedDurationUs check further isolates the
            // cause to a lack of media for the renderers to consume, to avoid classifying playbacks as
            // stuck when they're waiting for other reasons (in particular, loading DRM keys).
            playbackMaybeStuck = true;
        }
    }
    if (!playbackMaybeStuck) {
        playbackMaybeBecameStuckAtMs = C.TIME_UNSET;
    } else if (playbackMaybeBecameStuckAtMs == C.TIME_UNSET) {
        playbackMaybeBecameStuckAtMs = clock.elapsedRealtime();
    } else if (clock.elapsedRealtime() - playbackMaybeBecameStuckAtMs >= PLAYBACK_STUCK_AFTER_MS) {
        throw new IllegalStateException("Playback stuck buffering and not loading");
    }
    if (offloadSchedulingEnabled != playbackInfo.offloadSchedulingEnabled) {
        playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(offloadSchedulingEnabled);
    }
    boolean sleepingForOffload = false;
    if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY) || playbackInfo.playbackState == Player.STATE_BUFFERING) {
        sleepingForOffload = !maybeScheduleWakeup(operationStartTimeMs, ACTIVE_INTERVAL_MS);
    } else if (enabledRendererCount != 0 && playbackInfo.playbackState != Player.STATE_ENDED) {
        scheduleNextWork(operationStartTimeMs, IDLE_INTERVAL_MS);
    } else {
        handler.removeMessages(MSG_DO_SOME_WORK);
    }
    if (playbackInfo.sleepingForOffload != sleepingForOffload) {
        playbackInfo = playbackInfo.copyWithSleepingForOffload(sleepingForOffload);
    }
    // A sleep request is only valid for the current doSomeWork.
    requestForRendererSleep = false;
    TraceUtil.endSection();
}
Also used : TextRenderer(com.google.android.exoplayer2.text.TextRenderer) Nullable(androidx.annotation.Nullable)

Example 4 with LoadControl

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

the class ExoPlayerTest method loadControlNeverWantsToLoad_throwsIllegalStateException.

@Test
public void loadControlNeverWantsToLoad_throwsIllegalStateException() {
    LoadControl neverLoadingLoadControl = new DefaultLoadControl() {

        @Override
        public boolean shouldContinueLoading(long playbackPositionUs, long bufferedDurationUs, float playbackSpeed) {
            return false;
        }

        @Override
        public boolean shouldStartPlayback(long bufferedDurationUs, float playbackSpeed, boolean rebuffering, long targetLiveOffsetUs) {
            return true;
        }
    };
    // Use chunked data to ensure the player actually needs to continue loading and playing.
    FakeAdaptiveDataSet.Factory dataSetFactory = new FakeAdaptiveDataSet.Factory(/* chunkDurationUs= */
    500_000, /* bitratePercentStdDev= */
    10.0, new Random(0));
    MediaSource chunkedMediaSource = new FakeAdaptiveMediaSource(new FakeTimeline(), new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT)), new FakeChunkSource.Factory(dataSetFactory, new FakeDataSource.Factory()));
    ExoPlaybackException exception = assertThrows(ExoPlaybackException.class, () -> new ExoPlayerTestRunner.Builder(context).setLoadControl(neverLoadingLoadControl).setMediaSources(chunkedMediaSource).build().start().blockUntilEnded(TIMEOUT_MS));
    assertThat(exception.type).isEqualTo(ExoPlaybackException.TYPE_UNEXPECTED);
    assertThat(exception.getUnexpectedException()).isInstanceOf(IllegalStateException.class);
}
Also used : TestExoPlayerBuilder(com.google.android.exoplayer2.testutil.TestExoPlayerBuilder) FakeAdaptiveMediaSource(com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) FakeMediaSourceFactory(com.google.android.exoplayer2.testutil.FakeMediaSourceFactory) FakeAdaptiveDataSet(com.google.android.exoplayer2.testutil.FakeAdaptiveDataSet) Random(java.util.Random) ServerSideAdInsertionMediaSource(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource) FakeAdaptiveMediaSource(com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource) MaskingMediaSource(com.google.android.exoplayer2.source.MaskingMediaSource) ConcatenatingMediaSource(com.google.android.exoplayer2.source.ConcatenatingMediaSource) MediaSource(com.google.android.exoplayer2.source.MediaSource) CompositeMediaSource(com.google.android.exoplayer2.source.CompositeMediaSource) ClippingMediaSource(com.google.android.exoplayer2.source.ClippingMediaSource) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) TrackGroup(com.google.android.exoplayer2.source.TrackGroup) FakeChunkSource(com.google.android.exoplayer2.testutil.FakeChunkSource) Test(org.junit.Test)

Example 5 with LoadControl

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

the class ExoPlayerTest method nextLoadPositionExceedingLoadControlMaxBuffer_whileCurrentLoadInProgress_doesNotThrowException.

@Test
public void nextLoadPositionExceedingLoadControlMaxBuffer_whileCurrentLoadInProgress_doesNotThrowException() throws Exception {
    long maxBufferUs = 2 * C.MICROS_PER_SECOND;
    LoadControl loadControlWithMaxBufferUs = new DefaultLoadControl() {

        @Override
        public boolean shouldContinueLoading(long playbackPositionUs, long bufferedDurationUs, float playbackSpeed) {
            return bufferedDurationUs < maxBufferUs;
        }

        @Override
        public boolean shouldStartPlayback(long bufferedDurationUs, float playbackSpeed, boolean rebuffering, long targetLiveOffsetUs) {
            return true;
        }
    };
    MediaSource mediaSourceWithLoadInProgress = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {

        @Override
        protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
            return new FakeMediaPeriod(trackGroupArray, allocator, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, mediaSourceEventDispatcher) {

                @Override
                public long getBufferedPositionUs() {
                    // Pretend not to have buffered data yet.
                    return 0;
                }

                @Override
                public long getNextLoadPositionUs() {
                    // Set next load position beyond the maxBufferUs configured in the LoadControl.
                    return Long.MAX_VALUE;
                }

                @Override
                public boolean isLoading() {
                    return true;
                }
            };
        }
    };
    FakeRenderer rendererWaitingForData = new FakeRenderer(C.TRACK_TYPE_VIDEO) {

        @Override
        public boolean isReady() {
            return false;
        }
    };
    ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(rendererWaitingForData).setLoadControl(loadControlWithMaxBufferUs).build();
    player.setMediaSource(mediaSourceWithLoadInProgress);
    player.prepare();
    // Wait until the MediaSource is prepared, i.e. returned its timeline, and at least one
    // iteration of doSomeWork after this was run.
    TestPlayerRunHelper.runUntilTimelineChanged(player);
    runUntilPendingCommandsAreFullyHandled(player);
    assertThat(player.getPlayerError()).isNull();
}
Also used : TransferListener(com.google.android.exoplayer2.upstream.TransferListener) Allocator(com.google.android.exoplayer2.upstream.Allocator) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) DrmSessionManager(com.google.android.exoplayer2.drm.DrmSessionManager) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) FakeRenderer(com.google.android.exoplayer2.testutil.FakeRenderer) FakeMediaPeriod(com.google.android.exoplayer2.testutil.FakeMediaPeriod) ServerSideAdInsertionMediaSource(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource) FakeAdaptiveMediaSource(com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource) MaskingMediaSource(com.google.android.exoplayer2.source.MaskingMediaSource) ConcatenatingMediaSource(com.google.android.exoplayer2.source.ConcatenatingMediaSource) MediaSource(com.google.android.exoplayer2.source.MediaSource) CompositeMediaSource(com.google.android.exoplayer2.source.CompositeMediaSource) ClippingMediaSource(com.google.android.exoplayer2.source.ClippingMediaSource) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) TestExoPlayerBuilder(com.google.android.exoplayer2.testutil.TestExoPlayerBuilder) Nullable(androidx.annotation.Nullable) Test(org.junit.Test)

Aggregations

DefaultTrackSelector (com.google.android.exoplayer2.trackselection.DefaultTrackSelector)6 DefaultLoadControl (com.google.android.exoplayer2.DefaultLoadControl)5 MediaSource (com.google.android.exoplayer2.source.MediaSource)5 ExoPlayerFactory (com.google.android.exoplayer2.ExoPlayerFactory)4 LoadControl (com.google.android.exoplayer2.LoadControl)4 ClippingMediaSource (com.google.android.exoplayer2.source.ClippingMediaSource)4 CompositeMediaSource (com.google.android.exoplayer2.source.CompositeMediaSource)4 ConcatenatingMediaSource (com.google.android.exoplayer2.source.ConcatenatingMediaSource)4 MaskingMediaSource (com.google.android.exoplayer2.source.MaskingMediaSource)4 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)4 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)4 ServerSideAdInsertionMediaSource (com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource)4 FakeAdaptiveMediaSource (com.google.android.exoplayer2.testutil.FakeAdaptiveMediaSource)4 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)4 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)4 TrackSelection (com.google.android.exoplayer2.trackselection.TrackSelection)4 Test (org.junit.Test)4 Nullable (androidx.annotation.Nullable)3 DefaultRenderersFactory (com.google.android.exoplayer2.DefaultRenderersFactory)3 SimpleExoPlayer (com.google.android.exoplayer2.SimpleExoPlayer)3