MediaPlayer sometimes not preparing when screen is locked - android

I have a MusicService for MediaPlayback, wich uses a MediaPlayer with the settings:
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
and those Listeners are set:
OnPreparedListener, OnCompletionListener, OnErrorListener, OnSeekCompleteListener
The MediaPlayer is used for mp3-Playback. When one Song is finished, onCompletion is called. Then PlayNext is called, wich resets the MediaPlayer, then sets the Datasource with the URI of the next Track. Uri is loaded with:
Uri trackUri = ContentUris
.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
Then the Player is prepared, then the player is started. This is working fine, but only sometimes, when the Device is locked and played about 1-3 Songs while it was locked and the next Song should start, the Player doesn't prepare until i hit the power button. Figured out, that if I don't hit the PowerButton it takes the Player about 2 Minutes to prepare.
I've Logged everything now and made a few custom outputs with Log.e(...).
This is put out before prepare() (prepareAsync() delivers the same result) is called:
E/MusicService: Preparing now...
This is put out, when onPrepared is called:
E/MusicService: Player prepared.
So this is the full Device-Output after "Preparing now..." is put out:
04-02 13:54:55.506 12517-12517/at.htlleonding.musync E/MusicService: Preparing now.
04-02 13:54:55.525 811-888/? E/libsuspend: Error writing to /sys/power/state: Device or resource busy
04-02 13:54:55.544 246-14756/? D/offload_visualizer: thread exit
04-02 13:54:55.546 246-14754/? V/offload_effect_bundle: offload_effects_bundle_hal_stop_output output 1879 pcm_id 9
04-02 13:54:55.546 246-14754/? D/hardware_info: hw_info_append_hw_type : device_name = speaker
04-02 13:54:55.549 246-14752/? E/audio_hw_primary: offload_thread_loop: Compress handle is NULL
04-02 13:54:55.549 246-924/? D/audio_hw_primary: adev_close_output_stream: enter:stream_handle(0xb5bfa640)
04-02 13:54:55.549 246-924/? D/audio_hw_primary: out_standby: enter: stream (0xb5bfa640) usecase(3: compress-offload-playback)
04-02 13:54:55.555 246-924/? W/AudioFlinger: moveEffectChain_l() effect chain for session 0 not on source thread 0xb59fa000
04-02 13:54:55.611 246-15030/? I/FFmpegExtractor: android-source:0xb1834060
04-02 13:54:55.820 811-888/? E/libsuspend: Error writing to /sys/power/state: Device or resource busy
04-02 13:54:55.972 246-15030/? I/FFMPEG: [mp3 # 0xae2f4400] Skipping 0 bytes of junk at 2177007.
... Then theres no output until i hit the PowerButton. Then the Song is prepared.
If someone is interested in the full output after I hit the PowerButton until "Player prepared" is called, I created a Gist here.
Sidenote:
While the App is used, a few Album-Covers are displayed in some Fragments. They are loaded with Picasso, so I don't need to worry about memory caching. Some ImageViews are filled without Picasso (for example the ImageViews that hold the drawables of my PlayerControls). Maybe there are Problems with the memory/resources?

I might have found the answer in another thread where some faced the same problem while streaming music here.
My final solution is to use a WakeLock, wich I require before preparing a Song and release again onPrepared and onError and onDestroy of my Service. It's important to release it again to save Battery. Make sure to check if the WakeLock is held before releasing it.
I create my WakeLock like this in onCreate of my Service:
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MusicService");
aquire:
wakeLock.acquire();
release:
if(wakeLock.isHeld())
wakeLock.release();
Tested the Playback now for about 10 Minutes and didn't stop until now. I don't know if this is a very battery-saving solution

Related

Exoplayer Dolby playback issues with dynamic ad insertion

Im playing a DAI supported DASH stream with Exoplayer 2.18.1 (on firetv 4k) where the multi-period manifest gets stitched with the ad period. The ad period sometimes have dolby (stereo or 5.1) audio tracks and when the playback switches to ad from live we see some video freezes and then complete playback freeze at the end of the ad. The adb logcat at this time show following spurious audio timestamp related logs:
09-21 17:34:57.312 19192 23498 W AudioTrack: Spurious audio timestamp (frame position mismatch): 28270119, 10923744015, 10923743917, 189528000, 9827328, 9827328
09-21 17:34:57.816 19192 23498 W AudioTrack: Spurious audio timestamp (frame position mismatch): 28294325, 10924248296, 10924248198, 189528000, 9827328, 9827328
09-21 17:34:58.211 19192 19231 V SessionStateManager: 2022-09-21 17:34:58,211 - Thread: [main] - player time 1663761496000ms program start time 1663759800000ms media session time 1696000ms
09-21 17:34:58.211 19192 19231 V SessionStateManager: 2022-09-21 17:34:58,211 - Thread: [main] - com.mobitv.client.connect.core.media.session.MobiMediaSession#34d0ee4 set media session playback state to PLAYING time 1696000ms
09-21 17:34:58.211 19192 19231 V SessionStateManager: 2022-09-21 17:34:58,211 - Thread: [main] - setting playback state PlaybackState {state=3, position=1696000, buffered position=0, speed=1.0, updated=10924643, actions=8963, error code=0, error message=null, custom actions=[], active item id=-1}
09-21 17:34:58.213 739 932 V Avrcp : MediaController playback changed: PlaybackState {state=3, position=1696000, buffered position=0, speed=1.0, updated=10924643, actions=8963, custom actions=[], active item id=-1, error=null}
09-21 17:34:58.322 19192 23498 W AudioTrack: Spurious audio timestamp (frame position mismatch): 28318587, 10924753767, 10924753671, 189528000, 9827328, 9827328
One interesting thing to note is that this exact ad plays well when played individually i.e like a DASH VoD asset but not when stitched with DASH live period.
Some more information from stitched manifest that might help. The live period contains 1 video and 1 audio track:
<Representation id="L_5000_W" codecs="avc1.64001f" bandwidth="5120000" width="1280" height="720" frameRate="60/2" sar="1:1">
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Time$.m4s" timescale="90000" presentationTimeOffset="150764576748000">
...
</SegmentTemplate>
</Representation>
<Representation id="L_384_ENG" codecs="ac-3" bandwidth="384000" audioSamplingRate="48000">
<AudioChannelConfiguration schemeIdUri="tag:dolby.com,2014:dash:audio_channel_configuration:2011" value="F801"/>
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Time$.m4s" timescale="48000" presentationTimeOffset="80407774265537">
...
</SegmentTemplate>
</Representation>
The ad period too contains 1 video and 1 audio track:
<Representation id="A_5000_W" codecs="avc1.4d4028" bandwidth="5120000" width="1920" height="1080" frameRate="60/2" sar="1:1">
<SegmentTemplate initialization="/prod-ad-1/$RepresentationID$/init.mp4" media="/prod-ad-1/$RepresentationID$/$Number$.m4s" timescale="90000" startNumber="1">
...
</SegmentTemplate>
</Representation>
<Representation id="A_384_ENG" codecs="ac-3" bandwidth="384000" audioSamplingRate="48000">
<AudioChannelConfiguration schemeIdUri="tag:dolby.com,2014:dash:audio_channel_configuration:2011" value="F801"/>
<SegmentTemplate initialization="/prod-ad-1/$RepresentationID$/init.mp4" media="/prod-ad-1/$RepresentationID$/$Number$.m4s" timescale="48000" startNumber="1">
...
</SegmentTemplate>
</Representation>
As of now Im struggling to understand the exact reasons for this playback problem. Can any please one help understanding this issue ?
Edit: FireTV stick 4K with Fire OS 6.2.9.3 (NS6293/4731)

MediaPlayer - NuPlayerRenderer: possible video time jump of x ms

I get some lines like the following:
10-15 21:34:30.318 6996-20354/? I/NuPlayerRenderer: possible video time jump of 546ms (266286180 : 260922630) or uninitialized media clock, retrying in 10ms
10-15 21:34:30.328 6996-20354/? I/NuPlayerRenderer: possible video time jump of 536ms (266286180 : 260922630) or uninitialized media clock, retrying in 10ms
10-15 21:34:30.338 6996-20354/? I/NuPlayerRenderer: possible video time jump of 526ms (266286180 : 260922630) or uninitialized media clock, retrying in 10ms
10-15 21:34:30.348 6996-20354/? I/NuPlayerRenderer: possible video time jump of 516ms (266286180 : 260922630) or uninitialized media clock, retrying in 10ms
10-15 21:34:30.358 6996-20354/? I/NuPlayerRenderer: possible video time jump of 506ms (266286180 : 260922630) or uninitialized media clock, retrying in 10ms
When I use the Media Player to use as Live Wallpaper using WallpaperService.Engine.
#Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
Log.i("VideoWallpaperEngine", "onVisibilityChanged");
try {
if(visible)
mediaPlayer.start();
else
mediaPlayer.pause();
} catch (Exception e) {
e.printStackTrace();
}
}
While these lines are printed, the video is paused because (I think) he tries to synchronize the video and the audio!?
I am only interested in the video stream and not the audio so does someone have an idea how to skip this check and to simply continue playing the video? Is there a library to play a video (mp4) without this?
Many thanks in advance.
Solution: (by #VC.One)
Use an mp4 without audio line. See https://www.youtube.com/watch?v=YwT1FTRjRNQ to remove the audio line from a video using VLC player.
(of course, only if you don't need the audio part of your video)

How to stop Android openSLES audio recorder properly?

I have a native audio recorder using openSLES in Android. The recorder works but when the stop method is called, it seems to continue write buffers, as I continue to get the logs:
...
08-07 01:36:43.229: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.239: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
08-07 01:36:43.249: V/AudioRecord(6194): Overrun user: 61400, server: 61c00, flags 0001
...
I am using the thread lock method to record the buffers, but why am I getting these logs after stopping the recorder as follows:
typedef struct opensl_stream {
...
SLObjectItf recorderObject;
SLRecordItf recorderRecord;
SLAndroidSimpleBufferQueueItf recorderBufferQueue;
...
} OPENSL_STREAM;
OPENSL_STREAM *p;
//starting recorder
...
//stopping recorder
if (p->recorderObject != NULL) {
(*p->recorderObject)->Destroy(p->recorderObject);
p->recorderObject = NULL;
p->recorderRecord = NULL;
p->recorderBufferQueue = NULL;
}
After trying to stop the recorder as above I still get the AudioRecord(6194): Overrun user log, which means buffer is read but not used. How can I stop recording properly?
First, you should stop the recorder before destroying it, but that's not enough.
Since OpenSL callbacks are called from its own thread, stopping the recorder from another thread does not mean immediately all callbacks halt. (Or no new callbacks will be called.) Therefore you have to 'count' how many buffers you enqueued, so in the callback you can count how many callbacks were processed.
So the pseudo code looks something like this:
stop the recorder by setting the record state to SL_RECORDSTATE_STOPPED, do not enqueue more buffer queues.
wait till all the enqueued buffer queues were processed by checking your counter(s).
destroy the recorder, and free up other resources (memory) that might be used by your callback.
When enqueueing bufferques, and at the end of opensl callbacks you have to count the enqueued / processed buffer queues yourself in a thread safe manner.
You can use pthread mutexes / conditions / broadcasting while waiting for all the processing happen. (Or you may use a simple while loop with some sleeping some inside.)

MediaPlayer mutes after some minutes of playing mp3

I'm developing an AudioBook player for Android. For the playing part, I've used MediaPlayer class which works perfectly for some minutes but then always suddenly fails and no voice could be heard.
Even if I stop and issue a new request (read new chapter) it doesn't work. However the passing of time seems natural (for example playing a 10 seconds clip takes 10 seconds to finish) but there is absolutely no voice!
Does someone have any clues what might cause this problem?
Here's the relevant parts of my MediaPlayer usage.
And here's the logcat around the place it mutes.
EDIT:
By analyzing the logcat, I found out that this part is showing after the muting has happened:
E/AudioFlinger( 146): no more track names available
E/AudioTrack( 146): AudioFlinger could not create track, status: -12
E/AudioSink( 146): Unable to create audio track
E/AwesomePlayer( 146): deleting Audio Player - start failed
E/MediaPlayer( 5558): error (-19, 0)
***V/MainActivity( 5558): onNewPage()
E/MediaPlayer( 5558): Error (-19,0)
E/Sensors ( 285): sensors_poll_context_t::pollEvents, line 202: receive event #### i=2, nb=0
E/Sensors ( 285): sensors_poll_context_t::pollEvents, line 202: receive event #### i=2, nb=0
E/Sensors ( 285): sensors_poll_context_t::pollEvents, line 202: receive event #### i=2, nb=0
E/Sensors ( 285): sensors_poll_context_t::pollEvents, line 202: receive event #### i=2, nb=0
***V/MediaPlayerWrapper( 5558): stop()
***D/MediaPlayerWrapper( 5558): Stopping player...
E/MediaPlayer( 5558): stop called in state 0
E/MediaPlayer( 5558): error (-38, 0)
The lines with three * at beginning are my messages, others are frameworks'.
The problem was simply because of not releasing the media player object; as these answers (a,b,c) suggested already.
mMediaPlayer.release();

MediaPlayer completes after pausing

I recently observed a very weird problem with MediaPlayer playing an mp3 file. I'm running this code (mPlayer is a MediaPlayer):
Log.d(TAG, "Pausing");
try {
mPlayer.pause();
Log.d(TAG, "Paused");
} catch (IllegalStateException e) {
Log.w(TAG, "exception pausing player");
}
The weird thing is that if I'm close to the end of the audio file, the player sends a completion notification to my OnCompletionListener a short time after the above code completes. (I haven't pinned down exactly how close I have to be, but it's on the order of 1/4 second.) For instance, here's a typical logcat output when this occurs:
05-27 17:23:43.439: DEBUG/Player(266): Pausing
05-27 17:23:43.487: DEBUG/Player(266): Paused
05-27 17:23:43.838: WARN/Player(266): Audio completed (state=PAUSED)
Note that the warning line (logged from my OnCompletionListener), comes over 300 ms after the call to pause() returned!
The result is that the media player enters the PlaybackCompleted state when I don't expect it. This screws up the behavior of my code (as well as start(), which restarts from the beginning instead of playing the last little bit of the file).
This has happened on emulators from 1.6 through 2.3 and on at least one device running 2.2. Does anyone know about this problem and what to do about it?
The mediaplayer runs in a separate thread and you have to wait until the ui thread and the mediaplayer's thread have synced. So the delay is normal. It may be possible that the player really completes the file because of your pause-command reaching the player too late. Try what happens with a longer audio-file.
Another problem which might come up is other code seeking beyond the end of the track after the pause-command. What's the code of your listener?

Categories

Resources