Background audio on iOS

#rb aaron.mcleran
#jira UE-168559
#fyi adam.kinge
#preflight 63be75f26729b05ec9329d58

[CL 23643122 by axel riffard in ue5-main branch]
This commit is contained in:
axel riffard
2023-01-11 03:50:50 -05:00
parent 192c5a1bcb
commit b1e030ed49
6 changed files with 49 additions and 10 deletions

View File

@@ -347,6 +347,10 @@ namespace UnrealBuildTool
bool bRemoteNotificationsSupported = false;
Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bRemoteNotificationsSupported);
// Add audio as background mode
bool bBackgroundAudioSupported = false;
Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsBackgroundAudio", out bBackgroundAudioSupported);
// Add background fetch as background mode
bool bBackgroundFetch = false;
Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableBackgroundFetch", out bBackgroundFetch);
@@ -539,10 +543,14 @@ namespace UnrealBuildTool
}
// Add remote-notifications as background mode
if (bRemoteNotificationsSupported || bBackgroundFetch)
if (bRemoteNotificationsSupported || bBackgroundFetch || bBackgroundAudioSupported)
{
Text.AppendLine("\t<key>UIBackgroundModes</key>");
Text.AppendLine("\t<array>");
if (bBackgroundAudioSupported)
{
Text.AppendLine("\t\t<string>audio</string>");
}
if (bRemoteNotificationsSupported)
{
Text.AppendLine("\t\t<string>remote-notification</string>");

View File

@@ -82,6 +82,8 @@ namespace Audio
return false;
}
bSupportsBackgroundAudio = GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsBackgroundAudio"), bSupportsBackgroundAudio, GEngineIni);
OSStatus Status;
GraphSampleRate = (double) InternalPlatformSettings.SampleRate;
UInt32 BufferSize = (UInt32) GetNumFrames(InternalPlatformSettings.CallbackBufferFrameSize);
@@ -513,6 +515,12 @@ namespace Audio
void FMixerPlatformAudioUnit::SuspendContext()
{
#if PLATFORM_IOS
if (bSupportsBackgroundAudio)
{
return;
}
#endif
if (SuspendCounter == 0)
{
FPlatformAtomics::InterlockedIncrement(&SuspendCounter);

View File

@@ -72,6 +72,8 @@ namespace Audio
int32 BytesPerSubmittedBuffer;
double GraphSampleRate;
bool bSupportsBackgroundAudio;
// We may have to grow the circular buffer capacity since Audio Unit callback size is not guaranteed to be constant
// Currently, this just zero's-out and reallocates, so it will pop. (We always keep largest capacity)

View File

@@ -606,8 +606,20 @@ static IOSAppDelegate* CachedDelegate = nil;
self.bAudioActive = bActive;
// get the category and settings to use
NSString* Category = [self IsFeatureActive:EAudioFeature::DoNotMixWithOthers] ? AVAudioSessionCategorySoloAmbient : AVAudioSessionCategoryAmbient;
// get the category and settings to use
NSString* Category = AVAudioSessionCategoryAmbient;
if([self IsFeatureActive:EAudioFeature::DoNotMixWithOthers])
{
Category = AVAudioSessionCategorySoloAmbient;
}
#if !PLATFORM_TVOS
bool bSupportsBackgroundAudio = GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsBackgroundAudio"), bSupportsBackgroundAudio, GEngineIni);
if (bSupportsBackgroundAudio)
{
Category = AVAudioSessionCategoryPlayback;
}
#endif
NSString* Mode = AVAudioSessionModeDefault;
AVAudioSessionCategoryOptions Options = 0;
if (self.bAudioActive || [self IsBackgroundAudioPlaying] || [self IsFeatureActive:EAudioFeature::BackgroundAudio])
@@ -1327,11 +1339,8 @@ FCriticalSection RenderSuspend;
FEmbeddedCommunication::KeepAwake(TEXT("Background"), false);
FGraphEventRef ResignTask = FFunctionGraphTask::CreateAndDispatchWhenReady([]()
{
UE_LOG(LogTemp, Display, TEXT("Calling Delegate"));
FCoreDelegates::ApplicationWillDeactivateDelegate.Broadcast();
FEmbeddedCommunication::AllowSleep(TEXT("Background"));
FCoreDelegates::ApplicationWillDeactivateDelegate.Broadcast();
FEmbeddedCommunication::AllowSleep(TEXT("Background"));
}, TStatId(), NULL, ENamedThreads::GameThread);
// Do not wait forever for this task to complete since the game thread may be stuck on waiting for user input from a modal dialog box
@@ -1347,11 +1356,18 @@ FCriticalSection RenderSuspend;
}
UE_LOG(LogTemp, Display, TEXT("Done with entering background tasks time."));
}
bool bSupportsBackgroundAudio = GConfig->GetBool(TEXT("/Script/IOSRuntimeSettings.IOSRuntimeSettings"), TEXT("bSupportsBackgroundAudio"), bSupportsBackgroundAudio, GEngineIni);
// fix for freeze on tvOS, moving to applicationDidEnterBackground. Not making the changes for iOS platforms as the bug does not happen and could bring some side effets.
#if !PLATFORM_TVOS
[self ToggleSuspend:true];
if (!bSupportsBackgroundAudio)
{
[self ToggleSuspend:true];
[self ToggleAudioSession:false];
}
#else
[self ToggleAudioSession:false];
#endif
[self ToggleAudioSession:false];
RenderSuspend.TryLock();
if (FTaskGraphInterface::IsRunning())

View File

@@ -503,6 +503,10 @@ public:
UPROPERTY(config, EditAnywhere, Category = "Audio")
FPlatformRuntimeAudioCompressionOverrides CompressionOverrides;
/** Whether this app's audio can be played when using other apps or on the srpingboard */
UPROPERTY(config, EditAnywhere, Category = "Audio", meta = (DisplayName = "Whether audio from this plays in background (iOS and iPadOS only)"))
bool bSupportsBackgroundAudio;
/** This determines the max amount of memory that should be used for the cache at any given time. If set low (<= 8 MB), it lowers the size of individual chunks of audio during cook. */
UPROPERTY(GlobalConfig, EditAnywhere, Category = "Audio|CookOverrides|Stream Caching", meta = (DisplayName = "Max Cache Size (KB)"))
int32 CacheSizeKB;

View File

@@ -50,6 +50,7 @@ UIOSRuntimeSettings::UIOSRuntimeSettings(const FObjectInitializer& ObjectInitial
bSupportsMetal = true;
bSupportsMetalMRT = false;
bDisableHTTPS = false;
bSupportsBackgroundAudio = false;
}
void UIOSRuntimeSettings::PostReloadConfig(class FProperty* PropertyThatWasLoaded)