Reputation: 694
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
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