Audio player becomes unresponsive after paused for a minute - just-audio

Building an audio streaming app using just_audio and audio_service. It uses an HLS url stream to get the audio. When audio is playing and the device is locked the controls will show on the lock screen and work properly using play/pause. However if the audio is paused for around a minute or longer the play button is tapped the lock screen controls will turn grey. I'll then open the app and try tapping play in the view and the Audio processing state will change to idle and nothing else happens.
I'm wonder if it has to do with the HLS stream at all. The amount of time that the player has to be paused before it "breaks" varies, but does seem to be consistent with the amount of audio that has buffered. So play/pause works fine if the amount of time the audio has been paused is less than the buffered amount, but if it passes then I encounter this issue.
As far as I can tell, nothing useful is logged at the time the audio player stops working, nor when tapping play/pause while in this state. I've tried to see if the OS kills the audio player maybe so I could re-init, but that doesn't seem to be the case either.

Figured this out, however, I'm not sure it's best solution.
One part is the provider for our HLS url for the live stream was able to increase the session timeout from 45 seconds to 5 minutes. There doesn't seem to be any negative behavior in doing this. It somehow prevents the background controls from breaking (greying out) when the audio has been paused for more then a minute (this varies and doesn't seem directly related to the session timeout, so maybe some magic iOS is doing too, who knows).
The other part is when a user locks their device and interacts with the background player something breaks to the point where if they go back into the app and try to switch the audio source something fails deep in the audio player. To "fix" this, when switching from the live stream to a non-HLS url I am now calling dispose on the audio player in the handler then re-initializing it.
This has solved my problem, but I think a better solution exists. For my specific case, using the SwitchAudioHandler may be that better solution, but I haven't had the time to try it.

Related

Youtube iframe api. Player state gets stuck on BUFFERING state on mobile devices

For my app I need to constantly monitor the state of the youtube player but for some reason onStateChange behaves differently on desktop and mobile. In particular I have the following problem: when I try to change the current time of the player to the point that is not buffered yet and the player is currently in PAUSED state, it switches to the BUFFERING state and never goes back to PAUSED state even after it finishes buffering. On the desktop it switches to BUFFERING and then back to PAUSED which is exactly what I want.
I use custom loading overlay when the player is buffering so this behavior complete breaks the functionality. The overlay just gets stuck on mobile devices forever.
If anyone experienced similar issues please let me know.
Thanks.

Playing a muted video without interrupting background music

My design calls for a video playing in the background of my login screen, exactly like 6snap has.
I would like to avoid the default behavior of stopping the user's music when the video starts to play. My video does not have sound.
I'm using:
<MediaElement Source="MyVideo.mp4" />
I tried setting IsMuted=true which didn't help. Does anyone have an idea how 6snap managed it?
Edit: currently trying the animated gif route. Using the ImageTools 3rd party library and having converted my MP4, it works fine. My 9 second 640x1136 3MB video became a 41MB GIF, so I have to reduce the quality drastically. Still trying to find a better way if possible.
You won't be able to do that with Background Audio and MediaElement, hence as MSDN says:
When a MediaElement control plays audio or video content, any background sounds or media already playing are halted. The app launches the playback experience when the user taps the control. Only one MediaElement control can operate at a time.
It's no matter you have no sound - when you start to play all background sounds/media are halted.
I'm not sure how the App you have mentioned achieved that, but maybe you can try with DirectX/XNA - thought I've not tried this and don't know if that would help.

iOS how to don't stop music when the app start launching

I've noticed that when my app start, the music I'm listening is automatically stopped, and I've noticed that when I start some other apps, the music just continue... this means that I don't know how to manage the actual playing music in the device to let it plays or stop.
I'm developing a game with obj-c and cocos2d btw, I've searched but sadly I've found nothing... so here's my question, how can I let the music I'm listening with my device continue to play even if I start the app ?
edit: I'm using SimpleAudioEngine to start a background music and some sound effects in my app
Place this line in your application:didFinishLaunchingWithOptions: method of your AppDelegate or in general before using the audio player.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
According to the documentation, the AVAudioSessionCategoryAmbient category is
for an app in which sound playback is nonprimary—that is, your app can
be used successfully with the sound turned off.
This category is also appropriate for “play along” style apps, such as a virtual piano that a user plays over iPod audio. When you
use this category, audio from other apps mixes with your audio. Your
audio is silenced by screen locking and by the Silent switch (called
the Ring/Silent switch on iPhone).
please import AVFoundation/AVFoundation.h
Swift:
Before playing enter this line:
let audioSession = AVAudioSession.sharedInstance()
if audioSession.otherAudioPlaying {
_ = try? audioSession.setCategory(AVAudioSessionCategoryAmbient, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)
}
For people looking to solve this within react native (iOS)
My problem was quite the opposite where some of our muted videos with no music was causing background sound to be paused from other apps for no reason.
To fix this, also pass ignoreSilentSwitch="obey" prop alongside disableFocus and muted props through your Video component.
According to the docs:
You can activate the audio session at any time after setting its category, but it’s generally preferable to defer this call until your app begins audio playback. Deferring the call ensures that you won’t prematurely interrupt any other background audio that may be in progress.
Be sure not to be starting the audio session directly via its setActive method or indirectly via AVAudioEngine or other playback engine(s) immediately after the app launches. You should set only the category at this stage if you don't want your app to interrupt others on launch. If you're using AVAudioEngine, defer setting up the engine or connecting anything to the engine's mainMixerNode or outputNode until you actually need to start playing something.
When your app starts playing music, it will pause any audio currently playing. For obvious reasons. If you want your music to carry on playing when the app launches then don't let the app play any music.

background app listen to audio input

Our app knows how to listen to the audio input. Can I open the app in the background (multi-tasking) and still get it to work as if it is open? Or can my app stay in the background and still get audio inputs,and output audio sounds? How i do that?
Set your AudioSessionCategory as AVAudioSessionCategoryRecord. The docs explain here that this category will allow you to record audio input even when the app is in the background. This will allow you to listen to the device input in an AudioQueue recording callback function. However, when this is occurring in the background, the status bar is tinted red by the system to alert the user that a backgrounded app is listening (and possibly recording) device input.
The phone is only allowed to do a few things in the background, like play sounds, and monitor location.
My guess is that this won't work, or if it does, it will be rejected by apple.
You may be able to get it working by playing a sound in the background and using that to keep the app alive to listen to the input. I'm not sure if this will work.

OverrideCategoryDefaultToSpeaker not responding with iPod Touch

A little background:
I am working on an iOS app which does audio recording and makes use of the audio session category AVAudioSessionCategoryPlayAndRecord. The app also plays sound effects which I want to play through the device's main speaker (while the user is not recording). In order stop output audio from playing through the main speakers while recording I use the following code snippet:
UInt32 defaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof (defaultRoute),
&defaultRoute);
When the user starts recording I run the same code again with a defaultRoute of 0 which causes output audio to stop being played through the speakers and therefore not included in the recording. This method has been working fine on the iPhone.
The Issue:
When I run the same code on an iPod Touch (4th generation), the kAudioSessionProperty_OverrideCategoryDefaultToSpeaker property does not seem to have any affect. The result is that while a user is recording audio on their iPod Touch, sound effects will still play through the speaker and are included in the recording.
Does anyone know why this is happening, or how to fix it? I want to the behaviour on the iPod Touch to match the behaviour on the iPhone: output audio does not play through the main speakers while recording.
Note:
The closest to a solution that I have gotten is detecting if the device is an iPod Touch and if it is, mute system audio when recording starts using the following code snippet:
[MPMusicPlayerController iPodMusicPlayer].volume = 0.0;
This was not a desirable solution as when this code is executed, the volume overlay view pops up showing that the volume was turned down. This adds confusion to the UI and is not a good enough solution.
Any help would be appreciated!