Running Exoplayer in a service connected to a PlayerView on UI for AnalyticsListener and VideoListener features
See original GitHub issueChecked Stackoverflow and GitHub issues but could not address my issue directly
I am building an app to analyze live TV video streams and report when a drop, loaderror or other issue is detected. So the app will run on a low profile Android phone (current test phone: Samsung J7 , 1GB RAM , Android 7.1 OS) The phone will run Exoplayer in a service and open a different HLS stream every N seconds (15 seconds at the moment) Then using the AnalyticsListener and VideoListener features it will collect information and events from streams.
When I tried this, I see that VideoListener does not work if the player is not bound to a PlayerView which is visible. Is this correct ? If there is a way to use VideoListener without any visible PlayerView, can you tell me ?
In the worst case, I force the app to leave screen on and disable keyguard, it works. But I have this problem:
Since the player is using the playerview on UI thread I have to release and start an new player every 15 seconds. I use this code:
main service thread:
MyService.runOnUI(new Runnable() {
public void run() {
if (player.getPlaybackState() == Player.STATE_BUFFERING) {
//player.release();
//startPlayer();
reStartPlayer();
} else {
startPlayer();
}
}
});
Handler handler = new Handler(Looper.getMainLooper());
Runnable runnableCode = new Runnable() {
@Override
public void run() {
postStat();
}
};
handler.postDelayed(runnableCode, 15000);
so the main thread calls restartPlayer() and then after 15 seconds it uses postStat() function to post collected stats, and goes back to start.
restartPlayer function is like:
public void reStartPlayer() {
player.release();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
player.removeAnalyticsListener(playerAnalyticsListener);
player.removeVideoListener(playerVideoListener);
player=null;
DefaultLoadControl loadControl = new DefaultLoadControl.Builder().setPrioritizeTimeOverSizeThresholds(false).setBufferDurationsMs(2500, 10000, 2500, 2500).build();
player = new SimpleExoPlayer.Builder(getApplicationContext()).setLoadControl(loadControl).build();
player.setVolume(0);
playerAnalyticsListener=new MainAlayticsListenerForService(player);
player.addAnalyticsListener(playerAnalyticsListener);
player.addVideoListener(playerVideoListener);
playerView = myPlayerView();
playerView.setPlayer(player);
playerView.requestFocus();
Uri hlsVideoUri = Uri.parse(currURL);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "Test"));
HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(hlsVideoUri);
player.setPlayWhenReady(true);
player.prepare(hlsMediaSource);
}
Now this works, but after some time of running , it stops with following exception:
2020-10-13 12:05:03.339 26492-26513/? W/OpenGLRenderer: swapBuffers encountered EGL error 12301 on 0x9b5cd0e0, halting rendering...
2020-10-13 12:05:03.339 26492-31666/? E/art: ashmem_create_region failed for 'indirect ref table': Too many open files
2020-10-13 12:05:03.340 26492-31666/? W/art: Throwing OutOfMemoryError "Could not allocate JNI Env"
2020-10-13 12:05:03.348 26492-31666/? E/ExoPlayerImplInternal: Playback error
com.google.android.exoplayer2.ExoPlaybackException: Unexpected runtime error
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:564)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.OutOfMemoryError: Could not allocate JNI Env
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:730)
at com.google.android.exoplayer2.audio.DefaultAudioSink.flush(DefaultAudioSink.java:1167)
at com.google.android.exoplayer2.audio.MediaCodecAudioRenderer.onDisabled(MediaCodecAudioRenderer.java:511)
at com.google.android.exoplayer2.BaseRenderer.disable(BaseRenderer.java:175)
at com.google.android.exoplayer2.ExoPlayerImplInternal.disableRenderer(ExoPlayerImplInternal.java:1510)
at com.google.android.exoplayer2.ExoPlayerImplInternal.seekToPeriodPosition(ExoPlayerImplInternal.java:1131)
at com.google.android.exoplayer2.ExoPlayerImplInternal.seekToPeriodPosition(ExoPlayerImplInternal.java:1095)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMediaSourceListInfoRefreshed(ExoPlayerImplInternal.java:1690)
at com.google.android.exoplayer2.ExoPlayerImplInternal.setMediaItemsInternal(ExoPlayerImplInternal.java:670)
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:505)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
2020-10-13 12:05:03.410 26492-26503/? I/art: Background sticky concurrent mark sweep GC freed 109466(10MB) AllocSpace objects, 10(1856KB) LOS objects, 8% free, 108MB/118MB, paused 22.656ms total 231.827ms
I don’t understand why I get " Too many open files" error because I release the player every 15 seconds before creating a new one. What can I do about this ?
thanks.
Issue Analytics
- State:
- Created 3 years ago
- Comments:23 (10 by maintainers)
thanks. I’ve opened a new issue for it. And , now I will close this one if you’ve nothing else to add ?
This issue tracker is the right place to ask. Best is to create a new issue for this so the title matches the question. This way other user who have a similar question can find it and it’s not off-topic in this issue.
If you open a new issue, it’s helpful to also describe quickly what your use case is. Because then we can probably advice you which callback of the
AnalyticsListener
is the best to use.