You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Keep audio playing when the iOS app backgrounds during software-decoded
(VP9 / AV1-without-HW / etc.) playback. The combined demux loop drops video
and paces on the audio renderer while backgroundAudioOnly is set; the engine
routes the SW host to audio-only on background-enter and resumes video on
foreground. Verified headless via aetherctl bgaudio + unit tests + iOS/tvOS builds.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@@ -683,6 +716,7 @@ final class SoftwarePlaybackHost {
683
716
clockArmed: getClockArmed,
684
717
markClockArmed: setClockArmed,
685
718
seekGeneration: getSeekGeneration,
719
+
backgroundAudioOnly: getBackgroundAudioOnly,
686
720
onError: onError,
687
721
onEnd: onEnd
688
722
)
@@ -963,6 +997,7 @@ final class SoftwarePlaybackHost {
963
997
clockArmed:@Sendable()->Bool,
964
998
markClockArmed:@Sendable()->Void,
965
999
seekGeneration:@Sendable()->UInt64,
1000
+
backgroundAudioOnly:@Sendable()->Bool,
966
1001
onError:@Sendable(String)->Void,
967
1002
onEnd:@Sendable()->Void
968
1003
){
@@ -1089,8 +1124,14 @@ final class SoftwarePlaybackHost {
1089
1124
}
1090
1125
1091
1126
if streamIdx == videoStreamIndex {
1127
+
// Background audio-only: drop video, don't gate on the non-draining display layer.
1128
+
ifbackgroundAudioOnly(){
1129
+
av_packet_unref(packet)
1130
+
av_packet_free_safe(packet)
1131
+
continue
1132
+
}
1092
1133
// Back-pressure via SampleBufferRenderer.isReadyForMoreMediaData (not the deprecated layer property). Park on condition while paused to avoid 200 Hz CPU spin.
1093
-
while !renderer.isReadyForMoreMediaData && !stopRequested(){
1134
+
while !renderer.isReadyForMoreMediaData && !stopRequested()&& !backgroundAudioOnly(){
1094
1135
if !isPlaying(){
1095
1136
condition.lock()
1096
1137
while !isPlaying() && !stopRequested(){
@@ -1101,6 +1142,12 @@ final class SoftwarePlaybackHost {
1101
1142
Thread.sleep(forTimeInterval:0.005)
1102
1143
}
1103
1144
}
1145
+
// Entered background while parked on back-pressure: drop this frame.
1146
+
ifbackgroundAudioOnly(){
1147
+
av_packet_unref(packet)
1148
+
av_packet_free_safe(packet)
1149
+
continue
1150
+
}
1104
1151
ifstopRequested(){
1105
1152
av_packet_unref(packet)
1106
1153
av_packet_free_safe(packet)
@@ -1120,6 +1167,26 @@ final class SoftwarePlaybackHost {
0 commit comments