My configuration
iPhone X
iOS 12
Problem
Since iOS 11/12 my apps audio for some reason has a periodic crackling/popping sound which appears to get worse/more noticeable the louder or more constant the audio is.
Troubleshooting
I played a 800Hz sine wave from djay2 through AudioBus into my app and saved the output of my app to a file.
Loading my apps output into Audacity I can see that the crackling occurs every 14,112 samples or every 0.320 seconds.
Has anyone got any idea where I should start looking. Changing the internal configuration of my app between 41.1kHz and 48kHz appears to make no difference. I thought it might have been due to downsampling from the hardware sample rate.
Toggling Inter-App Audio Sync on/off within AudioBus appears to have some effect (1 in every ~8 toggles will stop the crackling).
I assume this is due to the AudioSession being restarted or something.
Has anyone got any idea what might be causing this or has experienced this before?
Thanks,
Anthony
Related
My app (made with Flutter but this should not matter) has something like a timer functionality that makes a tick sound in regular periods (between 10s and 3min). I have the background mode Audio, AirPlay, and Picture in Picture activated and the following in my Info.plist.
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
but the audio will still stop when running in background.
This occurs when running the app in profile mode, when I run in debug mode, the audio continues when running in background.
What can I do to have the audio continue to run in background?
There is a relevant note in the audio_service 0.18.0 README which can help here:
Note that the audio background mode permits an app to run in the background only for the purpose of playing audio. The OS may kill your process if it sits idly without playing audio, for example, by using a timer to sleep for a few seconds. If your app needs to pause for a few seconds between audio tracks, consider playing a silent audio track to create that effect rather than using an idle timer.
Well, unless you did this in native code (Swift/Objective-C), your code is running inside the Flutter engine - probably with some Dart Timer.periodic.
The Flutter engine may be killed off at any point in time when the app is in the background. On Android this can even happen when simply switching to the camera and back to the app afterwards. On iOS usually after some fixed time or on high system load.
In this regard, Flutter (and most other cross-platform toolkits) are very different to native apps.
You can start with the official documentation here: https://flutter.dev/docs/development/packages-and-plugins/background-processes
This may be a good article: https://medium.com/vrt-digital-studio/flutter-workmanager-81e0cfbd6f6e
I don't know enough about iOS but I think there is no easy way to schedule execution in the small intervals you require. On Android something like the AlarmManager can be used.
You can try writing the scheduling code natively and schedule it from the app via a MethodChannel when the period is set.
You can look at these libraries:
https://pub.dev/packages/workmanager (probably can't wake up at the small intervals you need)
https://pub.dev/packages/android_alarm_manager_plus (only for Android)
https://pub.dev/packages/audio_service (may give you some idea on how to achieve background execution on iOS)
Edit:
After reading more about Enabling Background Audio on iOS, it seems to me, that this only works when using
an AVAudioSession. Which you are probably not using. To get this working you need some native code. The audio_service package uses such a session. You can try scheduling with Dart code and playing the sound via the audio_service package. Sounds like it could work but I have no experience with this package.
Please, pay attention to the answer from #RyanHeise – he's correct on the point of using AudioSession: in background you should play either sound or silence. As soon as audio will be paused, app can be suspended.
Also, Important Note: when app entering background, scheduled timers will pause. That's why you might think it stopped working. Do not use scheduling via Timers on background - rely on events from the system.
I have a legacy video streaming library that seems to be broken on iPhone 11 (and above) devices. After digging into the problem it seems that the code that is initiating the AVAudioSession is failing due to the call to AVAudioSession.sharedInstance.setPreferredSampleRate(44100) not changing the actual sample rate and keeping it at 48000Hz.
Has anyone else faced this? I know that the method says preferred and it is not guaranteed that it will change the audio sample rate, but it was working on all previous devices.
So the main idea is: my broadcast upload extension making video of phone screen and when it finishes it saves video into directory.
When I am starting extension it works well and saving video. It can make video during 30 minutes and longer. But for some reason it can be randomly killed after few seconds of work even few minutes without any error being displayed. I don't know what what is the problem?. Maybe somebody can help me with that?
It happens on iOS 13 and iOS 12.
Issue description
AVSampleBufferDisplayLayer seems to hang on iOS 12.3.1 (>= iOS 12.2 is also affected) after
reboot. It looks that after 5 minutes everything works fine again.
The issue is not reproducible on iOS 11.
In our production code we don't use AVAssetReader, so please ignore any issues
with it, if minor.
I can make application hang on AVSampleBufferDisplayLayer init, enqueue and
requestMediaDataWhenReadyOnQueue.
Please advise how we should implement AVSampleBufferDisplayLayer correctly
(examples are welcome). Especially when we have to maintain and exchange
many display layers at once.
How to reproduce the issue:
Clone repo: https://github.com/mackode/AVSampleBufferDisplayLayer_Hanging
Download:
Tears of Steel segment
Put tearsofsteel_4k.mov_1918x852_2000.mp4 in Resources/ directory
Open AVSampleBufferDisplayLayer_BlackScreen.xcodeproj
Take iOS 12.3.1 device and reboot it
Start debugging AVSampleBufferDisplayLayer_BlackScreen
The video should start playing, then move a slider (seek) one or a few more times
Sample code is available here:
https://github.com/mackode/AVSampleBufferDisplayLayer_Hanging
Observed result:
Video hangs usually on AVSampleBufferDisplayLayer methods
Expected result:
Video seeks and continues to play
Can someone help me with solving this mistery?
Have little hope that anyone's encountered this, but there seems to be a system wide bug with AVPlayer. I've tested with my app along with other apps, including Pandora.
Namely, and randomly, if you successfully open the app and begin playing, then put the app in the background, perform a variety of random actions, such as playing media in other apps, making a phone call, etc, and try to come back to the app, the AVPlayer's don't play.
I've replicated this many times, though inconsistently, with Pandora and the app that I'm working on.
I've logged my code and have not found any errors in playback. It just doesn't play.
Has anyone else experienced this strange issue? I have spent countless days on it and am now desperate.
Looks like the AVFoundation media server is crashing and resetting, causing this problem.
The solution:
https://developer.apple.com/library/ios/qa/qa1749/_index.html