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

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.

Related

Audio player becomes unresponsive after paused for a minute

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.

iBeacon entry.exit callback when app is force killed by swipe up iOS

I read in many places that if user swipes up and kills an app, that app will not be able to receive location updates. I get didEnterRegion and didExitRegion callbacks are received when my app is not killed and is in background. But if I swipe kill app, app doesn't get those callbacks. My question here is,
Is it that app will stop getting callbacks ever? i.e., even if the app is launched again and is in background it does not get the callbacks
I read about startMonitoringSignificantLocationChanges and background app refresh when used together, I can get callback even when app is killed by swipe. I tried this and could not get it working. Is this the expected behavior?
Will startMonitoringSignificantLocationChanges and background app refresh together when used, I get region entry/exit callbacks after rebooting device?
This is not expected behavior. You are supposed to get didEnterRegion and didExitRegion callbacks even after killing an app in the task switcher. If you are not seeing this, something may be wrong with your app or testing methodology. Posting code may be helpful.
A few caveats and tips:
Make sure your app has obtained backround permission with locationManager.requestAlwaysAuthorization(). Without it, it cannot detect at all in the background.
Detection in the killed state did not work on iOS 7.0.x. It started working as of 7.1+.
Make sure you wait long enough to get detections. In some app states, it can take up to 15 minutes.
Before killing your app in testing, check logs to ensure you know what CoreLocation thinks is your current region state. If you turn off a beacon then kill your app, CoreLocation may not have had time to realize the beacon disappeared, thinking it is still inside the region. If you then turn on the beacon, you will not get a new entry event because it thinks you are already inside.

Is there a way to determine whether a Windows Store app is suspended?

I'm building a Windows Store app and it pops up toast notifications from time to time. I also have an animation that plays to show when something has updated. Both of these happen at the same time.
What I would like is to not show the toast when the app is running.
So, is there a nice easy way to determine this or do I have to manually track the state via the suspending/resuming events?
Edited info:
The solution has a background task project which goes off, gets the data, then decides if anything has changed that the user needs to know about.
If so, it creates a toast, updates the tile badge, and plays an animation to fade in the new data.
The issue is that I don't want to show the toast and update the tile badge if the user has the app full screen. Similarly, playing the animation isn't needed until the app is resumed (that's the easy part though).
I realize I could solve it by having one timer that works when the app is running, and a separate background task for when it's suspended but that seems like overkill in this case.
The simple answer here is that if your app is suspended, your code won't be running.
If you want to pop up toasts when your app is suspended, you'll either need to use the WPNS or a background task to track changes.

Confusion between background vs suspended app states

I am bit confused about these two states. Following is my understanding;
when app is in background and if you have "Application does not run
in background" set to NO in App plist file then App continues running
in background. In suspend mode App stays in memory but does not
execute code! System doesn't notify App when it moves to Suspended
state and wipes out App from memory in low memory situation to create space for foreground Apps.
Is my understanding correct? If it is so then why don't I get my NSLog printed on console when App running in background and executing code? What actually happens to my TCP socket connection where I am continuously gets the data from server? Why do we need Suspended state as anyway System eventually wipes out App from memory in low memory situation. Is there any difference between App becoming active from suspended state or starting fresh?
You should look in the IOS App Programming Guide section "App States and Multitasking".
Find that by searching the Xcode documentation with the phrase "App States and Multitasking" and "Hits Must" item set to "Match Search Term". Another useful search phrase: "background execution".
The summary answer is that an application can continue "executing" in the background indefinitely for only a limited number of reasons:
in iOS, only specific app types are allowed to run in the background:
Apps that play audible content to the user while in the background,
such as a music player app
Apps that keep users informed of their
location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Newsstand apps that need to download and process new content
Apps that receive regular updates from external accessories
Aside from those specific operations, an app can ask to continue to execute for a very short time which the documentation covers in the section "Executing a Finite-Length Task in the Background". After a short time either your app tells the system it is done (and is then suspended) or it is forcibly terminated. Details in the doc.
Another useful bit of that document, with nice state diagrams, is the section "Managing App State Changes". That section talks about going into the background and returning to the foreground. It should answer your question about the difference between starting fresh versus starting from the suspended state. The short (not quite correct) answer is that if you start from the suspended state and you don't take any special actions when entering the background or (re)entering the foreground then you just continue more-or-less from where you were. Also, starting from the suspended state is faster. Read the doc since it says it much better than my paraphrase would.
App State
Not running: Your app is in this state before it starts up.
Active: Once your app is started, receiving events.
Inactive: When your app is running but something happens to interrupt it, like a phone call, it becomes inactive. Inactive means that the app is still running in the foreground but it’s not receiving events.
Backgrounded: In this state, your app is not in the foreground anymore but it is still able to run code.
Suspended: Your app enters this state when it’s no longer able to run code.
Background:
Executing code - Code is executed while the app is in a background state.
An app must go into a background state before it can go into a suspended state.
ie. Suppose you're on Facebook and you upload a video and you quickly switch to another app immediately after pressing the POST button. Although you switched to another app w/o terminating the app, the app can be configured to perform background processes to complete the upload.
An app that is in background does not necessarily mean it is suspended but an app that is suspended is in background.
An app can request to stay in background mode for extra time (for purposes of playing audio in the background or completing a network request, for example); afterward it will either go to suspended state or it will be forcibly terminated by the system.
Suspended:
Not executing code - Code is not executed while the app is in a suspended state.
An app that is in a suspended state is also in a background state.
The system moves apps to this state w/o notifying you beforehand.
An app in a suspended state is still in memory.
Some additional information that may help you on this topic:
UIApplication notifies the app of state transitions through methods in the AppDelegate.
Most state transitions are accompanies by these methods.
These methods are part of the UIApplicationDelegate protocol.
They provide you with a chance to respond to state changes.
The method below, for example, tells the delegate when the app is about to terminate. - It's only called if the app's in background before being terminated; not suspended.
func applicationWillTerminate(_ application: UIApplication) { ... }
In addition to Charlie Price's answer from 2013, iOS now also allows background for:
REMOTE NOTIFICATIONS that signal there is new content available for download. When a remote notification arrives, the system launches or resumes the app in the background and gives it a small amount of time to download the new content.
CORE BLUETOOTH to communicate with a bluetooth accessory while in background.
Click here for more details
UIApplication.shared.backgroundTimeRemaining tells you how many seconds is remaining until the system terminates the application. 3 minutes is the maximum time limit, but this time restarts each time the app is woken up in background mode.
You can prevent your app from ever entering a background or suspended state & instead immediately terminating by setting the UIApplicationExitsOnSuspend key to YES in the info.plist.
Additional links you may find useful:
https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/preparing_your_app_to_run_in_the_background/about_the_background_execution_sequence
https://medium.com/#abhimuralidharan/finite-length-tasks-in-background-ios-swift-60f2db4fa01b
https://qph.fs.quoracdn.net/main-qimg-473264d5d9f0ec16d57b8dffcc9824d8

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.