Audio not resume after switch to another app

I import FMOD from Unity Asset Store, version 2.01.07.

  • Build and run in iPhone, switch your app to another app, which can play audio/video like YouTube.
  • Then switch back to your app, audio will not resume.
  • It will be fixed about 30s later or never.

I think is a bug for iOS AVAudioSessionInterruptionNotification in the file “platform_ios”.

I try to fix it with 2 new notifications, or someone else can feed me back with a better way.

// platform_ios.mm
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

void (*gSuspendCallback)(bool suspend);

extern "C" void RegisterSuspendCallback(void (*callback)(bool))
{
    if (!gSuspendCallback)
    {
        gSuspendCallback = callback;
        
        [[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
         {  
            bool began = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue] == AVAudioSessionInterruptionTypeBegan;
            
            if (!began)
            {
                [[AVAudioSession sharedInstance] setActive:TRUE error:nil];
            }
            
            if (gSuspendCallback)
            {
                gSuspendCallback(began);
            }
        }];
        
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillResignActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
         {  
            [[AVAudioSession sharedInstance] setActive:FALSE error:nil];
            
            if (gSuspendCallback)
            {
                gSuspendCallback(1);
            }
        }];
        
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
         {  
            [[AVAudioSession sharedInstance] setActive:TRUE error:nil];
            
            if (gSuspendCallback)
            {
                gSuspendCallback(0);
            }
        }];
    }
}

In 2.01.08, we changed platform_ios.mm to address similar issues. This version is available on our website, not currently via the unity store. Below is a copy of the updated platform_ios.mm file.

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

void (*gSuspendCallback)(bool suspend);
bool gIsSuspended = false;

extern "C" void RegisterSuspendCallback(void (*callback)(bool))
{
    if (!gSuspendCallback)
    {
        gSuspendCallback = callback;
        
        [[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
        {
            bool began = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue] == AVAudioSessionInterruptionTypeBegan;
            
            if (began == gIsSuspended)
            {
                return;
            }
            if (@available(iOS 10.3, *))
            {
                if (began && [[notification.userInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue])
                {
                    return;
                }
            }
            
            gIsSuspended = began;
            if (!began)
            {
                [[AVAudioSession sharedInstance] setActive:TRUE error:nil];
            }
            if (gSuspendCallback)
            {
                gSuspendCallback(began);
            }
        }];
        
        [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
        {
#ifndef TARGET_OS_TV
            if (!gIsSuspended)
            {
                return;
            }
#else
            if (gSuspendCallback)
            {
                gSuspendCallback(true);
            }
#endif
            [[AVAudioSession sharedInstance] setActive:TRUE error:nil];
            if (gSuspendCallback)
            {
                gSuspendCallback(false);
            }
            gIsSuspended = false;
        }];
    }
}

We found when unity ios game foreground, hold the lock button open Siri and close it immediately (by touch anywhere else or press lock button once), audio is not resume. We found that [[AVAudioSession sharedInstance] setActive:TRUE error:nil] in UIApplicationDidBecomeActiveNotification will fail, but change gIsSuspended = false, and the next time AVAudioSessionInterruptionNotification will return, course audio not resume;
and we change to
BOOL result = [[AVAudioSession sharedInstance] setActive:TRUE error:nil];
if (!result)
return;
so that when next time AVAudioSessionInterruptionNotification, it will call setActive and gSuspendCallback. And we test that audio is resume after Siri is close.
And we wonder is it safe to change?

Thanks for sharing this - I’ve been able to reproduce the issue with Siri, but just to be sure, could I get you to provide your FMOD Unity Integration and iOS versions? As for your workaround, I’ll pass it along to the development team for confirmation on whether it’s safe or not.

fmod 2.01.20 ios 16.1.2

Apologies for the late reply - I can confirm that your workaround safe. A fix for the issue will be implemented in a future release. Thanks again for sharing!