The sounds and music of my app stop when iPad suspends then resumes. I have 2 AudioSources, one looping compressed background music, the other one playing uncompressed sounds. When I resume, music + sounds stop. After a while, music resumes (when looping). If I load another scene everything goes back to normal.
Sometimes when I resume I can hear a short piece (~300ms) of the music that was playing before suspending, then it stops.
There is no error on the console (only the → applicationDidResignActive() → applicationDidBecomeActive()).
I tried to enable / disable the hardware decoding on the background audioclip, but that did not change anything.
Running on Unity 3 pro + iPhone advanced, device is iPad running iOS 3.2.2.
I have the same problem, but for now I’ve bodged the music by starting it again after the app comes out of pause. I also check to see if my player prefs is set to play music at the same time.
Thank you Gnimmel ! I did not even know OnApplicationPause was called on iOS.
I had to make this more generic (I have to save the time of the AudioSource because I often play audio tutorials that have to keep in sync with what’s happening on the screen). Here is what I use :
using UnityEngine;
using System.Collections;
public class AudioSourceSuspendHack : MonoBehaviour {
private class AudioSourceInfo {
public AudioSource audioSource;
public float time;
public bool wasPlaying;
}
private AudioSourceInfo[] sourcesToBeResumed;
#if UNITY_IPHONE
void OnApplicationPause(bool pause) {
if (pause) {
// Application is pausing.
// Save infos about the audio sources in the scene
AudioSource[] sources = (AudioSource[]) FindObjectsOfType(typeof(AudioSource));
if (sources != null sources.Length > 0) {
// Create array of sources for resume
sourcesToBeResumed = new AudioSourceInfo[sources.Length];
for (int i = 0; i < sourcesToBeResumed.Length; i++) {
// Store informations about the sources
sourcesToBeResumed[i] = new AudioSourceSuspendHack.AudioSourceInfo();
sourcesToBeResumed[i].audioSource = sources[i];
sourcesToBeResumed[i].time = sources[i].time;
// For some reason, sources[i].isPlaying always returns false, even if the source is actually playing.
// We have to check the time instead.
if (sources[i].time > 0) {
sourcesToBeResumed[i].wasPlaying = true;
} else {
sourcesToBeResumed[i].wasPlaying = false;
}
// Stop the source
sources[i].Stop();
}
} else {
sourcesToBeResumed = null;
}
} else if (sourcesToBeResumed != null sourcesToBeResumed.Length > 0) {
// Application is resuming and there are sources to be resumed.
// Restore audio source settings.
foreach (AudioSourceInfo ainfo in sourcesToBeResumed) {
if (ainfo.wasPlaying) {
ainfo.audioSource.time = ainfo.time;
ainfo.audioSource.Play ();
}
}
}
}
#endif
}
Here is an update for iOS 4.2 : the script works well when the app goes background / foreground, but does not when suspending the iPad.
I found out that when switching between apps, the correct events are sent to AppController.mm : applicationWillEnterForeground (which tells Unity Audio has to be restored), then applicationDidBecomeActive (which un-pauses Unity).
However, when suspending the iPad, applicationWillEnterForeground is not called by iOS, therefore Unity is never told to restore the audio session. To fix this, I slightly changed the two functions in AppController.mm :