Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onPlayerStateChanged is never called when SimpleExoPlayerView is gone. #2432

Closed
khs8727 opened this issue Feb 9, 2017 · 8 comments
Closed
Assignees
Labels

Comments

@khs8727
Copy link

khs8727 commented Feb 9, 2017

Hi,
I'm using ExoPlayer (r2.1.1) to develop a music video application for Android.
I'm a beginner in android development.

I want to play video in background mode as well, so I made "VideoPlayerService" static class for foreground service. It has all variables and methods which handle a video player.
Also I made "VideoPlayerEventListener" which inherits "ExoPlayer.EventListener".
I attach this instance when creating a player like below.

mainHandler = new Handler();
videoTrackSelectionFactory` = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
loadControl = new DefaultLoadControl();
player = ExoPlayerFactory.newSimpleInstance(holderContext,trackSelector,loadControl);
VideoPlayerEventListener listener = new VideoPlayerEventListener(holderContext);
player.addListener(listener);

This is the flow to call a video player.

  1. When user click a video thumbnail in the main activity (main page), call "VideoPlayerViewActivity" which is our main playerView for the application.
  2. The "VideoPlayerViewActivity" has "SimpleExoPlayerView" in its view and pass it to "VideoPlayerService" as a parameter.
  3. VideoPlayerService initializes a ExoPlayer and attach it into "SimpleExoPlayerView"

The problem is
When "VideoPlayerViewActivity" is on, "onPlayerStateChanged" works like a charm.
However, "VideoPlayerViewActivity" is off (when application goes background or "VideoPlayerViewActivity" is closed), "onPlayerStateChanged" never called.

I guess that the player instance is still alive in the background because "VideoPlayerService" static class has it as a static variable and video keeps playing even in background. Also I use the player again when "VideoPlayerViewActivity" re-opened (to play video without pausing).

After I research, I found this.
When "SimpleExoPlayerView" on the main screen, the listener works.
However the "SimpleExoPlayerView" is not showing on the main screen, it does not works.
I also checked that "ExoPlayerImpl.handleEvent()" is never called in background.

If my assumption is right,
Why "SimpleExoPlayerView" is related to calling listeners in "SimpleExoPlayer"?
Is possible to play "SimpleExoPlayer" no matter "SimpleExoPlayerView" exist or not?

Any help will be greatly appreciated!

@Yonezpt
Copy link

Yonezpt commented Feb 9, 2017

I am not certain about this, but usually background applications must make use of service or asynctask so they can continue normal operations while in the background, otherwise most operations are suspended: https://developer.android.com/training/best-background.html

Disregard any of this if you are already using any of those methods.

@Jermyhewitt
Copy link

I have the same issue, I found a thread and I think the accepted answer is:
To solve this, you should be disabling the video renderer when the app moves to the background and enabling it again when the app moves back to the foreground. The demo app does this here. Note that since the isEnded checks are only performed on enabled renderers, the video renderer is not then taken into account to determine whether playback has finished. source of the quote
The demo that the thread references does not use SimpleExoplayer though. Maybe that can help to guide you in the right direction. Sorry I can't provide more information I hope you find a solution I will continue to search because I need the solution also.

@khs8727
Copy link
Author

khs8727 commented Feb 10, 2017

Thanks for reply.

I found an alternative solution after further investigation.

if (allRenderersEnded
        && (durationUs == TrackRenderer.UNKNOWN_TIME_US || durationUs <= positionUs)) {
setState(ExoPlayer.STATE_ENDED);

The problem was that videoRenderer is not ended forever when player goes in background mode. which means "allRenderersEnded" is never set to true.
Instead of making status of VideoRenderer to "ended", I check ended status from audioRenderer.

As Contributor mentioned in #1407,

I override MediaCodecAudioTrackRenderer.onOutputStreamEnded() and send a message using LocalBroadcastManager to player.

It works well!

@AquilesCanta
Copy link
Contributor

Disabling the unused renderers through the TrackSelector should fix your issue.

@Jermyhewitt
Copy link

Jermyhewitt commented Feb 17, 2017

As keima mentioned in issue #2461 there is a very noticeable delay when the the renderer is enabled. So when the activity is resumed and the surface is recreated and the renderer is re-enabled the audio playback stops for about 3 seconds. Is there a fix for that? khs8727 could you please provide a more complete example of your solution?

@NtcWai
Copy link

NtcWai commented Apr 19, 2017

@khs8727 I face the same problem, could you provide more code of your solution, please ?
thank you!

@ojw28 ojw28 self-assigned this Apr 19, 2017
@ojw28 ojw28 added the bug label Apr 19, 2017
@ojw28
Copy link
Contributor

ojw28 commented Apr 19, 2017

I have a feeling this is fixed in the dev-v2 branch, and that it's no longer necessary to disable the renderer . I could be wrong though. Please give it a try if you have a chance.

@ojw28
Copy link
Contributor

ojw28 commented May 24, 2017

Pretty sure this is fixed in recent V2 releases. Closing.

@ojw28 ojw28 closed this as completed May 24, 2017
@google google locked and limited conversation to collaborators Sep 22, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants