Baseflow / XamarinMediaManager

Cross platform Xamarin plugin to play and control Audio and Video
https://baseflow.com
MIT License
761 stars 304 forks source link

MediaManager stops after locking screen #911

Open ThiagoFrancischini opened 5 months ago

ThiagoFrancischini commented 5 months ago

🐛 Bug Report

I'm working on a Radio App using .NET MAUI (this plugin is working quite fine in MAUI), but I'm facing an issue where the audio player stops after a few seconds when the phone is locked (I'm playing live audio). Has anyone else encountered this problem?

I've tested this on Android, but I haven't had the chance to test it on iOS yet.

Version: 1.x

Platform:

ThiagoFrancischini commented 5 months ago

Adding some info, i'm streaming a audio file with .m3u8 extension, and i was looking into the logs and found the following error:

01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: Playback error 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: com.google.android.exoplayer2.ExoPlaybackException: Source error 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:684) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:656) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at android.os.Handler.dispatchMessage(Handler.java:102) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at android.os.Looper.loopOnce(Looper.java:205) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at android.os.Looper.loop(Looper.java:294) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at android.os.HandlerThread.run(HandlerThread.java:67) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: Caused by: com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: java.net.SocketTimeoutException: failed to connect to play.radio.br/131.255.161.38 (port 8089) from /10.0.2.16 (port 41420) after 8000ms 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:388) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:269) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:90) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DataSourceInputStream.checkOpened(DataSourceInputStream.java:105) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DataSourceInputStream.open(DataSourceInputStream.java:68) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.ParsingLoadable.load(ParsingLoadable.java:179) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:420) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.lang.Thread.run(Thread.java:1012) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: Caused by: java.net.SocketTimeoutException: failed to connect to play.radio.br/131.255.161.38 (port 8089) from /10.0.2.16 (port 41420) after 8000ms 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at libcore.io.IoBridge.connectErrno(IoBridge.java:235) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at libcore.io.IoBridge.connect(IoBridge.java:179) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at java.net.Socket.connect(Socket.java:646) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.Platform.connectSocket(Platform.java:182) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:145) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:659) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:556) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:382) 01-29 11:57:12.874 12446 12529 E ExoPlayerImplInternal: ... 9 more

adumitru2019 commented 3 months ago

I found the same problem with MediaManager while using it in a Maui Android app. The player stops few minutes after the application is minimized or after the screen of the device is locked.

ThiagoFrancischini commented 3 months ago

If it helps, I managed to make it work by creating a foreground service that starts when I play a stream URL and stop when I pause or stop the stream. This service does nothing but the fact that it exists prevents the OS from killing the app.

adumitru2019 commented 3 months ago

Yes, thanks; that's what I was going to do. In Windows the app runs fine when minimized or when the screen is locked. It seems that MediaManager uses different libraries for Windows.

ikeremozcan commented 2 months ago

Android devices has battery optimization settings for the apps. Could you try to get this permission and see that's work for you. if (Build.VERSION.SdkInt >= BuildVersionCodes.M) { String? packageName = Platform.CurrentActivity?.PackageName; Android.Content.Intent intent = new Android.Content.Intent(); intent.SetAction(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations); intent.SetData(Android.Net.Uri.Parse("package:" + packageName)); Platform.CurrentActivity?.StartActivity(intent); }

Also add this to manifest <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

adumitru2019 commented 2 months ago

I disabled the battery optimization on the device for the application which I deployed to the device. Android is ignoring that option.

Where do I add the code which you suggested? Do I add that to the constructor of the MainPage? Do I need to stop and destroy the service when the application ends?

ikeremozcan commented 2 months ago

I added that part into my HomeViewModel. Just asked the permission and that's it. Some android devices have own restrictions, it could be that as well

adumitru2019 commented 2 months ago

The suggested solution did not work. The application is still stopped if it loses focus.