murkr
murkr

Reputation: 694

Exoplayer: Loop creates OutOfMemoryError when playing video from local file

When I try to play a video from a local file (I assume it's .mp4) in the ExoPlayer 2.10.6, I get a OutOfMemoryError. I download the video from a firebase DB and then load it with Exoplayer. The fragment with the Exoplayer exists twice, but I release the Exoplayer in onPause.

Here where I initialise the Exoplayer, displayVideo is called in onResume and later while the fragment is running:

private void displayVideo() {       
    releaseMediaPlayer();
    exoPlayer = ExoPlayerFactory.newSimpleInstance(getContext());      
    mMediaPlayerView.setPlayer(exoPlayer);
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(), com.google.android.exoplayer2.util.Util.getUserAgent(getContext(), getContext().getString(R.string.app_name)));
    MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.fromFile(new File(getContext().getExternalFilesDir(null), profilePicVideoName)));
    exoPlayer.prepare(videoSource);
    exoPlayer.setPlayWhenReady(true);
    exoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
    mMediaPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
}

Here where I release the Exoplayer:

@Override
public void onPause() {
    super.onPause();
    releaseMediaPlayer();
}

@Override
public void onDestroy() {
    super.onDestroy();
    releaseMediaPlayer();
}

private void releaseMediaPlayer() {
    if (exoPlayer != null) {
        exoPlayer.release();
        exoPlayer = null;
    }
    mMediaPlayerView.setPlayer(null);
}

The video-file in firebase is < 1MB.

Edit:

new File(getContext().getExternalFilesDir(null), Helper.profilePicVideoName).length() = 629440

And the error-message is pretty useless:

E/art: Throwing OutOfMemoryError "Failed to allocate a 65548 byte allocation with 10220 free bytes and 9KB until OOM"
E/LoadTask: OutOfMemory error loading stream
java.lang.OutOfMemoryError: Failed to allocate a 65548 byte allocation with 19092 free bytes and 18KB until OOM

Edit 2:

Ok, without the loop of the video, no OutOfMemoryError is thrown. It doesn't matter, if I loop the video with setRepeatMode, with a LoopingMediaSource or by adding a Listener that calls exoPlayer.prepare.

The only thing that stops the OutOfMemoryError is adding a listener, and with every loop to release everything with releaseMediaPlayer() and then re-instantiating Exoplayer, Mediasource and so on. But then there is a black frame between every loop and the CPU is used way more than necessary. The memory consumption drops DRASTICALLY from 180 MB, where OutOfMemory occurs to < 100 MB.

Why can't I loop the regular way? What can I do to get rid of the black frame or to optimize CPU usage?

Upvotes: 8

Views: 5126

Answers (1)

murkr
murkr

Reputation: 694

Ok, here is the reason why it created an OutOfMemoryError:

The Exoplayer has the great idea to buffer a certain length of the video if in loop-modus. If this buffer length in seconds is longer than the video length, the exoplayer just buffers the video multiple times, using a lot of memory. If the exoplayer wants to buffer 10sec and the vidoe is 3sec long, the exoplayer will buffer the complete video > 3 times.

There is a way to modify settings of the exoplayer, so you can set how many seconds should be buffered. I decreased the seconds and stopped having OOME.

Upvotes: 2

Related Questions