Explore the integration of media technologies within your app. Discuss working with audio, video, camera, and other media functionalities.

All subtopics
Posts under Media Technologies topic

Post

Replies

Boosts

Views

Activity

Native WebRTC remote audio stops after ~1 hour while Safari still plays the same stream
Hello, I am developing BROXMEDIA Intercom, an iOS intercom application for live audiovisual production. The app uses a native Swift audio plugin, Google WebRTC, AVAudioSession, and a Capacitor user interface. The current TestFlight version is 2.0, build 17. Environment: iPhone 16 Pro Max iOS 26.5.2 TestFlight internal build AVAudioSession category: playAndRecord AVAudioSession mode: voiceChat Background audio capability enabled Bidirectional WebRTC audio between a web browser and the native iOS app Observed behavior: A remote web browser publishes WebRTC audio. The native iOS app receives and plays the audio correctly for approximately one hour. Wi-Fi disconnection/reconnection and airplane mode on/off initially recover correctly. After the prolonged session, the native app stops playing the remote audio. Signaling and participant presence remain connected. The remote participant is still shown as speaking. Completely closing and reopening the native app does not recover the remote audio. Safari on the same iPhone, connected to the same room and network, can still hear the same remote transmission. Restarting the remote web publication usually causes the native app to receive audio again. This suggests that the remote publication, network connection, signaling server, and device audio hardware are still operational when the native route fails. We are investigating whether: AVAudioSession or the underlying WebRTC audio unit has stopped rendering; the native RTCPeerConnection retains a stale receiver or audio track; inbound RTP has stopped even though the peer remains connected; an interruption, route change, or media-services reset has not been fully recovered. Our current recovery logic checks the peer connection state and whether a remote audio track object exists. However, we do not yet continuously verify that inbound RTP packets or bytes are increasing for each participant. Questions: Can AVAudioSession or its underlying audio unit stop rendering audio while RTCPeerConnection signaling remains connected? Which AVAudioSession or audio-unit callbacks should be monitored to distinguish an iOS audio-session failure from a WebRTC receiver or inbound-RTP failure? After AVAudioSession.mediaServicesWereResetNotification, should an app recreate the complete WebRTC audio engine, or is reactivating AVAudioSession normally sufficient? Is monitoring inbound RTP progression and audio energy the recommended way to detect a remote audio track that still exists but is no longer delivering usable audio? Are there any known considerations for prolonged bidirectional VoIP-style audio using playAndRecord, voiceChat, and background audio? We can add diagnostic logging and provide a Feedback Assistant report with sysdiagnose if the problem is reproduced again. Thank you.
0
0
365
3w
SFSpeechRecognizer is unavailable or fails to initialize on iOS 26.4 and 26.5 Simulators
I am testing SFSpeechRecognizer using the en_US locale. When the iPhone Simulator’s system language is set to Japanese, SFSpeechRecognizer.isAvailable returns false for en_US, so speech recognition is unavailable. As far as I have tested, this issue does not occur on iOS Simulator 26.2 or earlier. Is this a Simulator-specific issue, or is it a behavior change that could also occur on physical devices? Has any additional setup become necessary to use speech recognition in Simulator? I then changed the iPhone Simulator’s system language to English. After doing so, SFSpeechRecognizer.isAvailable returned true for en_US. However, starting a recognition task still failed immediately with kLSRErrorDomain Code=300, “Failed to initialize recognizer.” The following error was returned: Error Domain=kLSRErrorDomain Code=300 "Failed to initialize recognizer" UserInfo={ NSLocalizedDescription=Failed to initialize recognizer, NSUnderlyingError={ Error Domain=kLSRErrorDomain Code=300 "Failed to create recognizer from=/Users/<USERNAME>/Library/Developer/CoreSimulator/Devices/<DEVICE-UUID>/data/private/var/MobileAsset/AssetsV2/com_apple_MobileAsset_UAF_Siri_Understanding/purpose_auto/ c079bfa6b8856202dc8cb2135fef3b06229ced6e.asset/AssetData/mini.json" UserInfo={ NSLocalizedDescription=Failed to create recognizer from=/Users/<USERNAME>/Library/Developer/CoreSimulator/Devices/<DEVICE-UUID>/data/private/var/MobileAsset/AssetsV2/com_apple_MobileAsset_UAF_Siri_Understanding/purpose_auto/ c079bfa6b8856202dc8cb2135fef3b06229ced6e.asset/AssetData/mini.json } } } I have not observed either of these issues on iOS Simulator 26.2 or earlier: With the Simulator language set to Japanese, the en_US recognizer does not become unavailable. When SFSpeechRecognizer.isAvailable is true, recognition does not fail with kLSRErrorDomain Code=300. Environment Xcode: 26.6 (17F113) iOS Simulator 26.5 (23F77), iPhone 17 (A3258J/A) iOS Simulator 26.4 (23E244), iPhone 17 (A3258J/A)
0
0
830
3w
PHAssetChangeRequest deleteAssets completionHandler for recently captured 48MP DNG sometimes never called
I want to report a issue on PHAssetChangeRequest.deleteAssets Environment iOS 18.5, iOS 26.2.5, iOS 27.0 Steps to Reproduce Capture a 48MP ProRAW (DNG) photo with the Camera app. Open my app, call the following api to delete this photo: PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.deleteAssets(assets) }, completionHandler: completionHandler) Expected The system delete-confirmation dialog appears; after the user confirms, the asset is deleted and the completionHandler is called or report error if it failed Actual Sometime the following issue happens: The confirmation dialog never appears and the completionHandler is never called no success, no error, no timeout. The built-in Photos app can delete the affected asset but API can't. The stuck request leaks permanently. Even after the same asset is subsequently deleted via the built-in Photos app, the pending completionHandler is still never invoked. Workaround for this issue When the issue happens, restarting the iPhone or reinstall app can not help to fix it But I found if I leave the device alone for an extended period (maybe 10 min~1 hour) and restart the iPhone, finally I found PHAssetChangeRequest.deleteAssets work again. It looks like some background task for 48MP RAW image in DNG format stuck delete API. I need to wait the task finished and restart device to reset stuck status. But I can not know when the DNG is ready to delete, it looks like my app hangs I think the better behavior is completion block should return a error to tell user what happens instead of not calling completion block.
1
0
823
3w
VPIO Audio Ducking
Hey y'all, I'm new here and in the process of building some audio software. I'm hitting a roadblock trying to incorporate VPIO into audio playback states without it ducking what's currently playing in my DAW. I have a few questions: Can VPIO other-audio ducking be completely disabled on macOS, beyond fixed/minimum? Minimum is not enough for professional audio environments. Is attenuation of an unrelated application routed through a different Core Audio output device expected? Is split-device VPIO—built-in microphone input with Apollo/Universal Audio output—supported? Why can AVAudioEngine.start() succeed while the engine remains stopped and immediately emits a configuration-change notification? Thanks for any insight into this!
0
0
700
3w
Apple Music API - Credits Endpoint
Hi! I was wondering if there is currently a method that you have been using to retrieve information on credits (i.e. mixers, producers, engineers etc.) via the Apple Music API as an endpoint. I know it is possible to retrieve performing artists but would find it very useful to export data on the "Composition & Lyrics" and "Production & Engineering" sections when you view a songs credits on the front end as seen in the attached image. If not, is this a feature that is being currently worked on? Would be so useful for developers working with large catalogues. Thanks! Spencer
0
0
595
3w
Why does an edited 4K 60 FPS video become significantly smaller than the original when exported from the Photos library?
I'm observing an interesting behavior on iOS when uploading edited videos from the Photos library. Scenario Device: iPhone Video: 4K, 60 FPS Original video size (Photos app): 660 MB Uploaded original asset: 660 MB After applying a simple edit (e.g., a filter) in the Photos app: Photos app still shows the edited video. When my app uploads the current/edited asset, the uploaded file size becomes 167 MB. So the edited version is approximately 75% smaller than the original (660 MB → 167 MB), even though the duration appears unchanged. Questions Is this expected behavior for edited videos in the Photos library? Does iOS automatically re-encode edited videos using a lower bitrate or a different codec (e.g., HEVC) when generating the current rendition? Does the Photos app continue to display the size of the original asset rather than the size of the edited rendition? I'm aware that PhotoKit allows retrieving both the original and the current (edited) versions of a PHAsset. In this case, I'm intentionally retrieving the current version, and this behavior is observed only for the edited asset.
1
0
554
4w
ProResRAW shooting issue with AVCaptureMovieFileOutput with the first video
On iOS 26, the first ProRes RAW recording after launching the app consistently stalls for the entire take: audio records normally, but video contains only a few frames (for example, an 11.8-second clip at approximately 0.25 fps instead of 30 fps). Every subsequent recording works correctly. Before startRecording, the Bayer format is active, ProRes RAW is available, white balance is locked, and frame duration is pinned to 1/30. Reordering setOutputSettings and reasserting configuration have not resolved it; only discarding the first recording acts as a reliable warm-up. Is this a known one-time ProRes RAW encoder initialisation issue, and is there a supported way to prepare the encoder before the first user takes? I have a full working sample code if anyone needs but here is the setup function: import CoreMedia import CoreVideo @available(iOS 26.0, *) final class ProResRAWRecorder: NSObject, AVCaptureFileOutputRecordingDelegate { let session = AVCaptureSession() private let movieOutput = AVCaptureMovieFileOutput() private var camera: AVCaptureDevice! // Call on a serial capture queue. func configure() throws { session.beginConfiguration() defer { session.commitConfiguration() } session.sessionPreset = .inputPriority session.automaticallyConfiguresCaptureDeviceForWideColor = false guard let device = AVCaptureDevice.default( .builtInWideAngleCamera, for: .video, position: .back ) else { throw SampleError.noCamera } let cameraInput = try AVCaptureDeviceInput(device: device) guard session.canAddInput(cameraInput) else { throw SampleError.cannotAddInput } session.addInput(cameraInput) camera = device // Optional, but reproduces the real topology where audio remains healthy. if let microphone = AVCaptureDevice.default(for: .audio), let microphoneInput = try? AVCaptureDeviceInput(device: microphone), session.canAddInput(microphoneInput) { session.addInput(microphoneInput) } // Find a 12-bit packed Bayer format supporting 30 fps. guard let rawFormat = device.formats .filter({ CMFormatDescriptionGetMediaSubType($0.formatDescription) == kCVPixelFormatType_96VersatileBayerPacked12 && $0.videoSupportedFrameRateRanges.contains { $0.minFrameRate <= 30 && $0.maxFrameRate >= 30 } }) .max(by: { let a = CMVideoFormatDescriptionGetDimensions($0.formatDescription) let b = CMVideoFormatDescriptionGetDimensions($1.formatDescription) return Int(a.width) * Int(a.height) < Int(b.width) * Int(b.height) }) else { throw SampleError.noRAWFormat } try device.lockForConfiguration() device.activeFormat = rawFormat if rawFormat.supportedColorSpaces.contains(.appleLog) { device.activeColorSpace = .appleLog } let frameDuration = CMTime(value: 1, timescale: 30) device.activeVideoMinFrameDuration = frameDuration device.activeVideoMaxFrameDuration = frameDuration if device.isWhiteBalanceModeSupported(.locked) { device.whiteBalanceMode = .locked } device.unlockForConfiguration() guard session.canAddOutput(movieOutput) else { throw SampleError.cannotAddOutput } session.addOutput(movieOutput) session.startRunning() } // Call on the same serial capture queue after startRunning() returns. func record(to url: URL) throws { guard let connection = movieOutput.connection(with: .video) else { throw SampleError.noVideoConnection } // Reassert the required device state at the take boundary. try camera.lockForConfiguration() if camera.isWhiteBalanceModeSupported(.locked) { camera.whiteBalanceMode = .locked } let frameDuration = CMTime(value: 1, timescale: 30) camera.activeVideoMinFrameDuration = frameDuration camera.activeVideoMaxFrameDuration = frameDuration camera.unlockForConfiguration() guard movieOutput.availableVideoCodecTypes.contains(.proResRAW) else { throw SampleError.rawCodecUnavailable } movieOutput.setOutputSettings( [AVVideoCodecKey: AVVideoCodecType.proResRAW], for: connection ) movieOutput.startRecording(to: url, recordingDelegate: self) } func stop() { if movieOutput.isRecording { movieOutput.stopRecording() } } func fileOutput( _ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error? ) { print("Finished:", outputFileURL, "error:", error as Any) } enum SampleError: Error { case noCamera case cannotAddInput case noRAWFormat case cannotAddOutput case noVideoConnection case rawCodecUnavailable } }
1
0
1.2k
Jul ’26
AVPlayer does not switch up from SDR to HDR (Dolby Vision) variants during HLS ABR playback
Hello, I am developing a custom player SDK based on AVPlayer that supports HLS and LL-HLS playback on iOS. I have a question about AVPlayer's variant selection behavior with respect to the VIDEO-RANGE attribute. Setup Our multivariant playlist contains a ladder where the dynamic range differs per rung. Simplified example: #EXT-X-STREAM-INF:BANDWIDTH=1200000,RESOLUTION=854x480,CODECS="hvc1.2.4.L93.B0",VIDEO-RANGE=SDR,FRAME-RATE=30.000 sdr_480p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=3500000,RESOLUTION=1280x720,CODECS="dvh1.05.03",VIDEO-RANGE=PQ,FRAME-RATE=30.000 hdr_720p.m3u8 The lower rung(s) are SDR only, and HDR (Dolby Vision, VIDEO-RANGE=PQ) variants exist only at the higher rungs. There is no PQ variant at the low end and no SDR variant at the high end. Observed behavior On HDR-capable devices (AVPlayer.eligibleForHDRPlayback == true), playback starts on the SDR 480p variant and then never switches up to the HDR 720p variant, even when network throughput is clearly sufficient (verified via AVPlayerItemAccessLog.observedBitrate and variant switch events). ABR up-switching works as expected when all rungs share the same VIDEO-RANGE. Questions Is it expected behavior that AVPlayer confines ABR switching to variants of a single VIDEO-RANGE for the duration of an AVPlayerItem, i.e., it will not cross SDR <-> PQ/HLG boundaries at runtime? If so, is the VIDEO-RANGE group selected once at playback start based on display capability and the initially chosen variant, with all other ranges excluded from the eligible set? The HLS Authoring Specification for Apple devices requires parallel SDR ladders for backward compatibility (sections 1.24 / 6.16), which implies each VIDEO-RANGE should form a complete, self-contained ladder. Is a mixed-range ladder like the one above considered a non-conformant authoring pattern, and is completing the PQ ladder down to the lowest rungs the correct fix? Are there any public APIs that influence video-range selection for streaming playback (beyond eligibleForHDRPlayback, which is read-only)? I understand the ABR switching logic itself is not documented, but confirmation of the VIDEO-RANGE grouping behavior would help us author our ladders correctly. Thank you.
2
0
1.3k
Jul ’26
Manual legible (subtitle) selection not honored on live LL-HLS — select(_:in:) reverts to “off” within ~2s; automatic selection never displays non-forced subtitles
Environment: iOS 18 / iOS 26, AVPlayer + AVPlayerItem, live low-latency HLS (LL-HLS). Subtitle renditions are regular (non-forced) WebVTT: AUTOSELECT=YES, FORCED=NO. System captioning (Closed Captions + SDH) is OFF (default). Direct CDN, no P2P. Master playlist (subtitle part): #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Korean (AI)",AUTOSELECT=YES,FORCED=NO,LANGUAGE="kor",URI="..." #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English (AI)",AUTOSELECT=YES,FORCED=NO,LANGUAGE="eng",URI="..." #EXT-X-STREAM-INF:...,SUBTITLES="subs" Problem When the user picks a subtitle language we call playerItem.select(option, in: legibleGroup) with an option that is a genuine member of the item's current legible group. Right after the call, item.currentMediaSelection.selectedMediaOption(in:) returns the requested option. But within ~2 seconds, on a subset of real-user sessions, the selection spontaneously reverts with no further app interaction: most often to Off (no legible output is delivered afterwards), or it stays stuck on the previously selected language (a subsequent select to another language, or to Off, is silently ignored). It is intermittent and only appears under real conditions (frequent live playlist reloads / reconnects); it does not reproduce in a short, clean session. What we verified The option passed to select(_:in:) is a real member of the current group (re-resolved from item.asset); the call returns without error and reads back correctly immediately after. appliesMediaSelectionCriteriaAutomatically is the default true. Per the AV Foundation Release Notes ("Advice about subtitles"), automatic selection excludes options that are not AVMediaCharacteristicContainsOnlyForcedSubtitles. So on each live reload the automatic re-selection resolves non-forced subtitles to Off, appearing to override the manual select(_:in:). Reading the selected option against a freshly obtained group instance returns the same value as against the original instance — so this is a real state change, not a mismatched-group read. Questions On live HLS reloads with appliesMediaSelectionCriteriaAutomatically == true, is manual select(_:in:) for .legible expected to be overridden by automatic media selection? If so, is setMediaSelectionCriteria(_:forMediaCharacteristic:) the intended way to persist a user's choice? setMediaSelectionCriteria for subtitles is itself reported as unreliable (sometimes no subtitles) — see thread 108403. What is the recommended, deterministic way to keep a user-selected non-forced subtitle displayed across live playlist reloads, including turning subtitles Off? Is this the same underlying behavior as FB13344652 ("Auto (Recommended) doesn't display subtitles despite language match / DEFAULT=YES")? Related: https://developer.apple.com/forums/thread/722752 (FB13344652) , https://developer.apple.com/forums/thread/108403
1
0
509
Jul ’26
METrackReader subtitle tracks
Hi, I've written a Media Extension that adds support for .mkv and other file formats. I have it working for various audio and video codecs, but I'm stuck when it comes to adding support for subtitles. Some questions: How do I specify the language associated with a track? I have tried setting METrackInfo.extendedLanguageTag to e.g. "ja" or "jpn" and this value is reflected in AVAssetTrack.extendedLanguageTag, but AVAssetTrack.languageCode stays nil and AVAsset.availableMediaCharacteristicsWithMediaSelectionOptions is empty. How do I supply a subtitle track? I have tried returning a METrackInfo containing a CMFormatDescription of type kCMMediaType_Subtitle or kCMMediaType_Text with subtype kCMSubtitleFormatType_3GText or kCMSubtitleFormatType_WebVTT, but this causes AVFoundation to refuse to play the file at all. (There's some WIP code at https://github.com/Marginal/QuickLookVideo/blob/subtitles/formatreader/subtitletrackreader.swift) Anyone had any experience with either of these?
0
0
346
Jul ’26
iOS 27 beta: Opening Notification Center pauses AVPlayer playback
Since iOS 27 beta we are seeing a behavior change in our video streaming app and I would like to know whether others can reproduce it. Behavior on iOS 27 beta: Fully opening the Notification Center pauses playback. Audio continues for about 5 more seconds, then the app is suspended. Closing the Notification Center leaves the player paused. On iOS 26 the same build keeps playing in this situation. Setup: AVQueuePlayer playing video with audio, not muted audiovisualBackgroundPlaybackPolicy = .automatic (default) AVAudioSession category .playback, UIBackgroundModes: audio entitlement AVPictureInPictureController attached with canStartPictureInPictureAutomaticallyFromInline = true Filed as FB23893965 Questions: Can anyone reproduce this on iOS 27 beta? Is this intentional or a regression?
0
2
473
Jul ’26
Apple Music API - What am I missing?
So I'm digging through the Apple Music API trying to implement it into a music app. I feel like I have to be missing a huge piece of the puzzle. Did Apple really miss something this big?Let's take Apple Curators for instance, catalog/{storefront}/apple-curators/{id} Where do I get the list of all available Apple Curators? Same can be said for stations, artists, curators and activities. catalog/{storefront}/search looked promising for a second, until you realize you're required to supply a search term.At first glance, Top Chart Genres catalog/{storefront}/genres looked promising. Returns a full list of available Genres, but you then take one of those items and hit catalog/{storefront}/genres/{id} with it and you end up with the same exact json. Huh? Shouldn't that return me a list of albums and songs from that genre or at the very least, a link to get that information?Thus far the only thing that seems to return anything useful is /me/recent/played and /me/recommendations. /me/history/heavy-rotation is returning an empty data set, but I assume that's due to my lack of use of Apple Music (signed up a few weeks ago).Someone, please, tell me what I'm missing here. Is the API this lacking in functionality?
7
0
3.2k
Jul ’26
Why does retrieving the `PixelBuffer` of only one eye improve performance significantly on 2020 Mac mini?
Hi all! I'm maintaining a 3D video player, it's great to see we've developed MV-HEVC packed with great features that media industry love to use. This player uses macOS AV frameworks to decode MV-HEVC and plays time-interleaving signal on capable devices, such as DLP-Link projectors, 3D vision glasses syncing devices, etc. Previously, the player output was flickering, unstable when playing MV-HEVC, and I thought it was due to M1 didn't have hardware decoder for it, or 4K Dolby Vision decoding was too demanding for my Mac, but out of luck, I tried retrieving only 1 eye for each frame output during the DisplayLink call, and the flickering is gone. At least that's what I've seen with a 100Hz screen while testing. Why is the performance improvement so significant? And is there other ways I can improve the performance, and perhaps the energy consumption? The link to the change I've committed
0
0
407
Jul ’26
AVRoutePickerView's presented route list is automatically dismissed when CXProvider reports the call as connected (`reportOutgoingCall(with:connectedAt:)`)
Hi, I want my user to be able to change their audio output device while calling someone, even before the call is established. But I've run into an issue combining CallKit and AVRoutePickerView. On iOS 26 (Xcode 26.5, tested on iPhone 13 Mini): when my AVRoutePickerView's route list is presented while my call is still connecting (not yet established), the presented list is automatically dismissed the moment the app reports the call as connected via CXProvider.reportOutgoingCall(with:connectedAt:). That doesn't seem natural to me — it should stay open, since the user is actively interacting with unrelated system UI at that moment. This happens even when nothing about the AVAudioSession itself changes: no category change, no route change, no didActivate/didDeactivate callback fires around that time. The dismissal is caused by the CallKit "connected" state transition itself, but I don't know why, or whether it's intentional. Steps to reproduce (sample project below): Tap "Start Fake Call". Within 5 seconds, tap the small route picker button and leave its list open. Wait — at t+5s the app reports the call connected via reportOutgoingCall(connectedAt:), and the list closes itself right after. Is this normal? And is there an official, CallKit-sanctioned way to report a call's connected state without this side effect — some way to keep the route picker stable across that transition? The two workarounds I've found both have real downsides: Calling reportOutgoingCall(connectedAt:) at the very start of the call, before the callee has actually answered , but then CallKit no longer reflects the real call state (Recents/duration would include ringing time, and calls that are never answered would still show as "connected"). Disabling audio device selection entirely until the call is established... works, but hurts the user experience, since users may want to switch output before the call connects. Here's the minimal reproduction: import CallKit import SwiftUI struct ContentView: View { @StateObject private var demo = CallKitDemo() var body: some View { VStack(spacing: 24) { Text(demo.statusText) .font(.system(.body, design: .monospaced)) .multilineTextAlignment(.center) Button("Start Fake Call") { demo.startFakeCall() } .disabled(demo.isCallInProgress) RoutePickerView() .frame(width: 60, height: 60) } .padding() } } private struct RoutePickerView: UIViewRepresentable { func makeUIView(context: Context) -> AVRoutePickerView { let picker = AVRoutePickerView() picker.delegate = context.coordinator return picker } func updateUIView(_ uiView: AVRoutePickerView, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator() } final class Coordinator: NSObject, AVRoutePickerViewDelegate { func routePickerViewWillBeginPresentingRoutes(_ routePickerView: AVRoutePickerView) { print("[REPRO]", Date(), "picker WILL present routes") } func routePickerViewDidEndPresentingRoutes(_ routePickerView: AVRoutePickerView) { print("[REPRO]", Date(), "picker DID end presenting routes <- dismissed here") } } } @MainActor final class CallKitDemo: NSObject, ObservableObject { @Published var statusText = "Idle" @Published var isCallInProgress = false private let provider: CXProvider = { let configuration = CXProviderConfiguration() configuration.supportsVideo = false configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 configuration.supportedHandleTypes = [.generic] return CXProvider(configuration: configuration) }() private let callController = CXCallController() private var currentCallUUID: UUID? override init() { super.init() provider.setDelegate(self, queue: nil) } func startFakeCall() { let uuid = UUID() currentCallUUID = uuid isCallInProgress = true statusText = "Requesting CXStartCallAction..." let handle = CXHandle(type: .generic, value: "repro-call") let startAction = CXStartCallAction(call: uuid, handle: handle) callController.request(CXTransaction(action: startAction)) { error in if let error { print("[REPRO]", Date(), "CXStartCallAction request failed:", error) } } DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in guard let self, currentCallUUID == uuid else { return } print("[REPRO]", Date(), "reportOutgoingCall(connectedAt:)") statusText = "Reported connected at t+5s" provider.reportOutgoingCall(with: uuid, connectedAt: Date()) } DispatchQueue.main.asyncAfter(deadline: .now() + 8) { [weak self] in guard let self, currentCallUUID == uuid else { return } callController.request(CXTransaction(action: CXEndCallAction(call: uuid))) { _ in } currentCallUUID = nil isCallInProgress = false statusText = "Call ended" } } } extension CallKitDemo: CXProviderDelegate { func providerDidReset(_ provider: CXProvider) {} func provider(_ provider: CXProvider, perform action: CXStartCallAction) { action.fulfill() } func provider(_ provider: CXProvider, perform action: CXEndCallAction) { action.fulfill() } func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { print("[REPRO]", Date(), "didActivate") } func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { print("[REPRO]", Date(), "didDeactivate") } } Thanks for your help !
1
0
644
Jul ’26
Native WebRTC remote audio stops after ~1 hour while Safari still plays the same stream
Hello, I am developing BROXMEDIA Intercom, an iOS intercom application for live audiovisual production. The app uses a native Swift audio plugin, Google WebRTC, AVAudioSession, and a Capacitor user interface. The current TestFlight version is 2.0, build 17. Environment: iPhone 16 Pro Max iOS 26.5.2 TestFlight internal build AVAudioSession category: playAndRecord AVAudioSession mode: voiceChat Background audio capability enabled Bidirectional WebRTC audio between a web browser and the native iOS app Observed behavior: A remote web browser publishes WebRTC audio. The native iOS app receives and plays the audio correctly for approximately one hour. Wi-Fi disconnection/reconnection and airplane mode on/off initially recover correctly. After the prolonged session, the native app stops playing the remote audio. Signaling and participant presence remain connected. The remote participant is still shown as speaking. Completely closing and reopening the native app does not recover the remote audio. Safari on the same iPhone, connected to the same room and network, can still hear the same remote transmission. Restarting the remote web publication usually causes the native app to receive audio again. This suggests that the remote publication, network connection, signaling server, and device audio hardware are still operational when the native route fails. We are investigating whether: AVAudioSession or the underlying WebRTC audio unit has stopped rendering; the native RTCPeerConnection retains a stale receiver or audio track; inbound RTP has stopped even though the peer remains connected; an interruption, route change, or media-services reset has not been fully recovered. Our current recovery logic checks the peer connection state and whether a remote audio track object exists. However, we do not yet continuously verify that inbound RTP packets or bytes are increasing for each participant. Questions: Can AVAudioSession or its underlying audio unit stop rendering audio while RTCPeerConnection signaling remains connected? Which AVAudioSession or audio-unit callbacks should be monitored to distinguish an iOS audio-session failure from a WebRTC receiver or inbound-RTP failure? After AVAudioSession.mediaServicesWereResetNotification, should an app recreate the complete WebRTC audio engine, or is reactivating AVAudioSession normally sufficient? Is monitoring inbound RTP progression and audio energy the recommended way to detect a remote audio track that still exists but is no longer delivering usable audio? Are there any known considerations for prolonged bidirectional VoIP-style audio using playAndRecord, voiceChat, and background audio? We can add diagnostic logging and provide a Feedback Assistant report with sysdiagnose if the problem is reproduced again. Thank you.
Replies
0
Boosts
0
Views
365
Activity
3w
Mac Os 27, can't turn off live subtitles and code to turn it off from app
So, in macos golden gate 27, there is this new live subtitles that happens in every video that i can't even turn off? (live captions is off) and also is there anyway from code we can turn this feature off, because making a background app, it exists whenever, and i can't seem to find a way to disable it from coding and the app.
Replies
3
Boosts
0
Views
1.2k
Activity
3w
SFSpeechRecognizer is unavailable or fails to initialize on iOS 26.4 and 26.5 Simulators
I am testing SFSpeechRecognizer using the en_US locale. When the iPhone Simulator’s system language is set to Japanese, SFSpeechRecognizer.isAvailable returns false for en_US, so speech recognition is unavailable. As far as I have tested, this issue does not occur on iOS Simulator 26.2 or earlier. Is this a Simulator-specific issue, or is it a behavior change that could also occur on physical devices? Has any additional setup become necessary to use speech recognition in Simulator? I then changed the iPhone Simulator’s system language to English. After doing so, SFSpeechRecognizer.isAvailable returned true for en_US. However, starting a recognition task still failed immediately with kLSRErrorDomain Code=300, “Failed to initialize recognizer.” The following error was returned: Error Domain=kLSRErrorDomain Code=300 "Failed to initialize recognizer" UserInfo={ NSLocalizedDescription=Failed to initialize recognizer, NSUnderlyingError={ Error Domain=kLSRErrorDomain Code=300 "Failed to create recognizer from=/Users/<USERNAME>/Library/Developer/CoreSimulator/Devices/<DEVICE-UUID>/data/private/var/MobileAsset/AssetsV2/com_apple_MobileAsset_UAF_Siri_Understanding/purpose_auto/ c079bfa6b8856202dc8cb2135fef3b06229ced6e.asset/AssetData/mini.json" UserInfo={ NSLocalizedDescription=Failed to create recognizer from=/Users/<USERNAME>/Library/Developer/CoreSimulator/Devices/<DEVICE-UUID>/data/private/var/MobileAsset/AssetsV2/com_apple_MobileAsset_UAF_Siri_Understanding/purpose_auto/ c079bfa6b8856202dc8cb2135fef3b06229ced6e.asset/AssetData/mini.json } } } I have not observed either of these issues on iOS Simulator 26.2 or earlier: With the Simulator language set to Japanese, the en_US recognizer does not become unavailable. When SFSpeechRecognizer.isAvailable is true, recognition does not fail with kLSRErrorDomain Code=300. Environment Xcode: 26.6 (17F113) iOS Simulator 26.5 (23F77), iPhone 17 (A3258J/A) iOS Simulator 26.4 (23E244), iPhone 17 (A3258J/A)
Replies
0
Boosts
0
Views
830
Activity
3w
PHAssetChangeRequest deleteAssets completionHandler for recently captured 48MP DNG sometimes never called
I want to report a issue on PHAssetChangeRequest.deleteAssets Environment iOS 18.5, iOS 26.2.5, iOS 27.0 Steps to Reproduce Capture a 48MP ProRAW (DNG) photo with the Camera app. Open my app, call the following api to delete this photo: PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.deleteAssets(assets) }, completionHandler: completionHandler) Expected The system delete-confirmation dialog appears; after the user confirms, the asset is deleted and the completionHandler is called or report error if it failed Actual Sometime the following issue happens: The confirmation dialog never appears and the completionHandler is never called no success, no error, no timeout. The built-in Photos app can delete the affected asset but API can't. The stuck request leaks permanently. Even after the same asset is subsequently deleted via the built-in Photos app, the pending completionHandler is still never invoked. Workaround for this issue When the issue happens, restarting the iPhone or reinstall app can not help to fix it But I found if I leave the device alone for an extended period (maybe 10 min~1 hour) and restart the iPhone, finally I found PHAssetChangeRequest.deleteAssets work again. It looks like some background task for 48MP RAW image in DNG format stuck delete API. I need to wait the task finished and restart device to reset stuck status. But I can not know when the DNG is ready to delete, it looks like my app hangs I think the better behavior is completion block should return a error to tell user what happens instead of not calling completion block.
Replies
1
Boosts
0
Views
823
Activity
3w
Custom AVVideoCompositing on a composition-backed AVPlayerItem fails with AVErrorUnknown Xcode 27 beta 2 / beta 3
Trivial pass-through compositor fails on Xcode 27 (beta 2, beta 3); error code -11800 underlying error -12784. Repro included https://github.com/BugorBN/avplayer-custom-compositor-repro It works well on Xcode26 and lower
Replies
1
Boosts
2
Views
518
Activity
3w
Turn my iPhone to silent mode via Code (Swift)
Hi All,I am working on a project to turn my iPhone to silent mode via Code (Swift), Can someone ,plz, help to put on the right direction as I am very new to Xcode and Swift.Regards
Replies
2
Boosts
0
Views
3.0k
Activity
3w
VPIO Audio Ducking
Hey y'all, I'm new here and in the process of building some audio software. I'm hitting a roadblock trying to incorporate VPIO into audio playback states without it ducking what's currently playing in my DAW. I have a few questions: Can VPIO other-audio ducking be completely disabled on macOS, beyond fixed/minimum? Minimum is not enough for professional audio environments. Is attenuation of an unrelated application routed through a different Core Audio output device expected? Is split-device VPIO—built-in microphone input with Apollo/Universal Audio output—supported? Why can AVAudioEngine.start() succeed while the engine remains stopped and immediately emits a configuration-change notification? Thanks for any insight into this!
Replies
0
Boosts
0
Views
700
Activity
3w
Apple Music API - Credits Endpoint
Hi! I was wondering if there is currently a method that you have been using to retrieve information on credits (i.e. mixers, producers, engineers etc.) via the Apple Music API as an endpoint. I know it is possible to retrieve performing artists but would find it very useful to export data on the "Composition & Lyrics" and "Production & Engineering" sections when you view a songs credits on the front end as seen in the attached image. If not, is this a feature that is being currently worked on? Would be so useful for developers working with large catalogues. Thanks! Spencer
Replies
0
Boosts
0
Views
595
Activity
3w
ShazamKit max calls per minute
Hello, I cannot find reference to any possible limitation on ShazamKit. How many calls can I make per minute? Is there any limit at all? Thanks
Replies
0
Boosts
0
Views
205
Activity
3w
Why does an edited 4K 60 FPS video become significantly smaller than the original when exported from the Photos library?
I'm observing an interesting behavior on iOS when uploading edited videos from the Photos library. Scenario Device: iPhone Video: 4K, 60 FPS Original video size (Photos app): 660 MB Uploaded original asset: 660 MB After applying a simple edit (e.g., a filter) in the Photos app: Photos app still shows the edited video. When my app uploads the current/edited asset, the uploaded file size becomes 167 MB. So the edited version is approximately 75% smaller than the original (660 MB → 167 MB), even though the duration appears unchanged. Questions Is this expected behavior for edited videos in the Photos library? Does iOS automatically re-encode edited videos using a lower bitrate or a different codec (e.g., HEVC) when generating the current rendition? Does the Photos app continue to display the size of the original asset rather than the size of the edited rendition? I'm aware that PhotoKit allows retrieving both the original and the current (edited) versions of a PHAsset. In this case, I'm intentionally retrieving the current version, and this behavior is observed only for the edited asset.
Replies
1
Boosts
0
Views
554
Activity
4w
ProResRAW shooting issue with AVCaptureMovieFileOutput with the first video
On iOS 26, the first ProRes RAW recording after launching the app consistently stalls for the entire take: audio records normally, but video contains only a few frames (for example, an 11.8-second clip at approximately 0.25 fps instead of 30 fps). Every subsequent recording works correctly. Before startRecording, the Bayer format is active, ProRes RAW is available, white balance is locked, and frame duration is pinned to 1/30. Reordering setOutputSettings and reasserting configuration have not resolved it; only discarding the first recording acts as a reliable warm-up. Is this a known one-time ProRes RAW encoder initialisation issue, and is there a supported way to prepare the encoder before the first user takes? I have a full working sample code if anyone needs but here is the setup function: import CoreMedia import CoreVideo @available(iOS 26.0, *) final class ProResRAWRecorder: NSObject, AVCaptureFileOutputRecordingDelegate { let session = AVCaptureSession() private let movieOutput = AVCaptureMovieFileOutput() private var camera: AVCaptureDevice! // Call on a serial capture queue. func configure() throws { session.beginConfiguration() defer { session.commitConfiguration() } session.sessionPreset = .inputPriority session.automaticallyConfiguresCaptureDeviceForWideColor = false guard let device = AVCaptureDevice.default( .builtInWideAngleCamera, for: .video, position: .back ) else { throw SampleError.noCamera } let cameraInput = try AVCaptureDeviceInput(device: device) guard session.canAddInput(cameraInput) else { throw SampleError.cannotAddInput } session.addInput(cameraInput) camera = device // Optional, but reproduces the real topology where audio remains healthy. if let microphone = AVCaptureDevice.default(for: .audio), let microphoneInput = try? AVCaptureDeviceInput(device: microphone), session.canAddInput(microphoneInput) { session.addInput(microphoneInput) } // Find a 12-bit packed Bayer format supporting 30 fps. guard let rawFormat = device.formats .filter({ CMFormatDescriptionGetMediaSubType($0.formatDescription) == kCVPixelFormatType_96VersatileBayerPacked12 && $0.videoSupportedFrameRateRanges.contains { $0.minFrameRate <= 30 && $0.maxFrameRate >= 30 } }) .max(by: { let a = CMVideoFormatDescriptionGetDimensions($0.formatDescription) let b = CMVideoFormatDescriptionGetDimensions($1.formatDescription) return Int(a.width) * Int(a.height) < Int(b.width) * Int(b.height) }) else { throw SampleError.noRAWFormat } try device.lockForConfiguration() device.activeFormat = rawFormat if rawFormat.supportedColorSpaces.contains(.appleLog) { device.activeColorSpace = .appleLog } let frameDuration = CMTime(value: 1, timescale: 30) device.activeVideoMinFrameDuration = frameDuration device.activeVideoMaxFrameDuration = frameDuration if device.isWhiteBalanceModeSupported(.locked) { device.whiteBalanceMode = .locked } device.unlockForConfiguration() guard session.canAddOutput(movieOutput) else { throw SampleError.cannotAddOutput } session.addOutput(movieOutput) session.startRunning() } // Call on the same serial capture queue after startRunning() returns. func record(to url: URL) throws { guard let connection = movieOutput.connection(with: .video) else { throw SampleError.noVideoConnection } // Reassert the required device state at the take boundary. try camera.lockForConfiguration() if camera.isWhiteBalanceModeSupported(.locked) { camera.whiteBalanceMode = .locked } let frameDuration = CMTime(value: 1, timescale: 30) camera.activeVideoMinFrameDuration = frameDuration camera.activeVideoMaxFrameDuration = frameDuration camera.unlockForConfiguration() guard movieOutput.availableVideoCodecTypes.contains(.proResRAW) else { throw SampleError.rawCodecUnavailable } movieOutput.setOutputSettings( [AVVideoCodecKey: AVVideoCodecType.proResRAW], for: connection ) movieOutput.startRecording(to: url, recordingDelegate: self) } func stop() { if movieOutput.isRecording { movieOutput.stopRecording() } } func fileOutput( _ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error? ) { print("Finished:", outputFileURL, "error:", error as Any) } enum SampleError: Error { case noCamera case cannotAddInput case noRAWFormat case cannotAddOutput case noVideoConnection case rawCodecUnavailable } }
Replies
1
Boosts
0
Views
1.2k
Activity
Jul ’26
AVPlayer does not switch up from SDR to HDR (Dolby Vision) variants during HLS ABR playback
Hello, I am developing a custom player SDK based on AVPlayer that supports HLS and LL-HLS playback on iOS. I have a question about AVPlayer's variant selection behavior with respect to the VIDEO-RANGE attribute. Setup Our multivariant playlist contains a ladder where the dynamic range differs per rung. Simplified example: #EXT-X-STREAM-INF:BANDWIDTH=1200000,RESOLUTION=854x480,CODECS="hvc1.2.4.L93.B0",VIDEO-RANGE=SDR,FRAME-RATE=30.000 sdr_480p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=3500000,RESOLUTION=1280x720,CODECS="dvh1.05.03",VIDEO-RANGE=PQ,FRAME-RATE=30.000 hdr_720p.m3u8 The lower rung(s) are SDR only, and HDR (Dolby Vision, VIDEO-RANGE=PQ) variants exist only at the higher rungs. There is no PQ variant at the low end and no SDR variant at the high end. Observed behavior On HDR-capable devices (AVPlayer.eligibleForHDRPlayback == true), playback starts on the SDR 480p variant and then never switches up to the HDR 720p variant, even when network throughput is clearly sufficient (verified via AVPlayerItemAccessLog.observedBitrate and variant switch events). ABR up-switching works as expected when all rungs share the same VIDEO-RANGE. Questions Is it expected behavior that AVPlayer confines ABR switching to variants of a single VIDEO-RANGE for the duration of an AVPlayerItem, i.e., it will not cross SDR <-> PQ/HLG boundaries at runtime? If so, is the VIDEO-RANGE group selected once at playback start based on display capability and the initially chosen variant, with all other ranges excluded from the eligible set? The HLS Authoring Specification for Apple devices requires parallel SDR ladders for backward compatibility (sections 1.24 / 6.16), which implies each VIDEO-RANGE should form a complete, self-contained ladder. Is a mixed-range ladder like the one above considered a non-conformant authoring pattern, and is completing the PQ ladder down to the lowest rungs the correct fix? Are there any public APIs that influence video-range selection for streaming playback (beyond eligibleForHDRPlayback, which is read-only)? I understand the ABR switching logic itself is not documented, but confirmation of the VIDEO-RANGE grouping behavior would help us author our ladders correctly. Thank you.
Replies
2
Boosts
0
Views
1.3k
Activity
Jul ’26
Manual legible (subtitle) selection not honored on live LL-HLS — select(_:in:) reverts to “off” within ~2s; automatic selection never displays non-forced subtitles
Environment: iOS 18 / iOS 26, AVPlayer + AVPlayerItem, live low-latency HLS (LL-HLS). Subtitle renditions are regular (non-forced) WebVTT: AUTOSELECT=YES, FORCED=NO. System captioning (Closed Captions + SDH) is OFF (default). Direct CDN, no P2P. Master playlist (subtitle part): #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Korean (AI)",AUTOSELECT=YES,FORCED=NO,LANGUAGE="kor",URI="..." #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English (AI)",AUTOSELECT=YES,FORCED=NO,LANGUAGE="eng",URI="..." #EXT-X-STREAM-INF:...,SUBTITLES="subs" Problem When the user picks a subtitle language we call playerItem.select(option, in: legibleGroup) with an option that is a genuine member of the item's current legible group. Right after the call, item.currentMediaSelection.selectedMediaOption(in:) returns the requested option. But within ~2 seconds, on a subset of real-user sessions, the selection spontaneously reverts with no further app interaction: most often to Off (no legible output is delivered afterwards), or it stays stuck on the previously selected language (a subsequent select to another language, or to Off, is silently ignored). It is intermittent and only appears under real conditions (frequent live playlist reloads / reconnects); it does not reproduce in a short, clean session. What we verified The option passed to select(_:in:) is a real member of the current group (re-resolved from item.asset); the call returns without error and reads back correctly immediately after. appliesMediaSelectionCriteriaAutomatically is the default true. Per the AV Foundation Release Notes ("Advice about subtitles"), automatic selection excludes options that are not AVMediaCharacteristicContainsOnlyForcedSubtitles. So on each live reload the automatic re-selection resolves non-forced subtitles to Off, appearing to override the manual select(_:in:). Reading the selected option against a freshly obtained group instance returns the same value as against the original instance — so this is a real state change, not a mismatched-group read. Questions On live HLS reloads with appliesMediaSelectionCriteriaAutomatically == true, is manual select(_:in:) for .legible expected to be overridden by automatic media selection? If so, is setMediaSelectionCriteria(_:forMediaCharacteristic:) the intended way to persist a user's choice? setMediaSelectionCriteria for subtitles is itself reported as unreliable (sometimes no subtitles) — see thread 108403. What is the recommended, deterministic way to keep a user-selected non-forced subtitle displayed across live playlist reloads, including turning subtitles Off? Is this the same underlying behavior as FB13344652 ("Auto (Recommended) doesn't display subtitles despite language match / DEFAULT=YES")? Related: https://developer.apple.com/forums/thread/722752 (FB13344652) , https://developer.apple.com/forums/thread/108403
Replies
1
Boosts
0
Views
509
Activity
Jul ’26
METrackReader subtitle tracks
Hi, I've written a Media Extension that adds support for .mkv and other file formats. I have it working for various audio and video codecs, but I'm stuck when it comes to adding support for subtitles. Some questions: How do I specify the language associated with a track? I have tried setting METrackInfo.extendedLanguageTag to e.g. "ja" or "jpn" and this value is reflected in AVAssetTrack.extendedLanguageTag, but AVAssetTrack.languageCode stays nil and AVAsset.availableMediaCharacteristicsWithMediaSelectionOptions is empty. How do I supply a subtitle track? I have tried returning a METrackInfo containing a CMFormatDescription of type kCMMediaType_Subtitle or kCMMediaType_Text with subtype kCMSubtitleFormatType_3GText or kCMSubtitleFormatType_WebVTT, but this causes AVFoundation to refuse to play the file at all. (There's some WIP code at https://github.com/Marginal/QuickLookVideo/blob/subtitles/formatreader/subtitletrackreader.swift) Anyone had any experience with either of these?
Replies
0
Boosts
0
Views
346
Activity
Jul ’26
iOS 27 beta: Opening Notification Center pauses AVPlayer playback
Since iOS 27 beta we are seeing a behavior change in our video streaming app and I would like to know whether others can reproduce it. Behavior on iOS 27 beta: Fully opening the Notification Center pauses playback. Audio continues for about 5 more seconds, then the app is suspended. Closing the Notification Center leaves the player paused. On iOS 26 the same build keeps playing in this situation. Setup: AVQueuePlayer playing video with audio, not muted audiovisualBackgroundPlaybackPolicy = .automatic (default) AVAudioSession category .playback, UIBackgroundModes: audio entitlement AVPictureInPictureController attached with canStartPictureInPictureAutomaticallyFromInline = true Filed as FB23893965 Questions: Can anyone reproduce this on iOS 27 beta? Is this intentional or a regression?
Replies
0
Boosts
2
Views
473
Activity
Jul ’26
Apple Music API - Heavy Rotation Endpoint Broken?
The endpoint: https://api.music.apple.com/v1/me/history/heavy-rotation seems to just be returning an empty data array. Is this a bug, or is the endpoint not supported anymore? I would like to display a user's recent listening history for my app, is there another way to do this?
Replies
4
Boosts
1
Views
1.4k
Activity
Jul ’26
Apple Music API - What am I missing?
So I'm digging through the Apple Music API trying to implement it into a music app. I feel like I have to be missing a huge piece of the puzzle. Did Apple really miss something this big?Let's take Apple Curators for instance, catalog/{storefront}/apple-curators/{id} Where do I get the list of all available Apple Curators? Same can be said for stations, artists, curators and activities. catalog/{storefront}/search looked promising for a second, until you realize you're required to supply a search term.At first glance, Top Chart Genres catalog/{storefront}/genres looked promising. Returns a full list of available Genres, but you then take one of those items and hit catalog/{storefront}/genres/{id} with it and you end up with the same exact json. Huh? Shouldn't that return me a list of albums and songs from that genre or at the very least, a link to get that information?Thus far the only thing that seems to return anything useful is /me/recent/played and /me/recommendations. /me/history/heavy-rotation is returning an empty data set, but I assume that's due to my lack of use of Apple Music (signed up a few weeks ago).Someone, please, tell me what I'm missing here. Is the API this lacking in functionality?
Replies
7
Boosts
0
Views
3.2k
Activity
Jul ’26
PHAsset Additional Properties
Following Metadata should be accessible from PHAsset Object: Title, caption, Keywords. Write now they are available in the SQLite Photo Library, but thats is not a clean solution.
Replies
2
Boosts
4
Views
883
Activity
Jul ’26
Why does retrieving the `PixelBuffer` of only one eye improve performance significantly on 2020 Mac mini?
Hi all! I'm maintaining a 3D video player, it's great to see we've developed MV-HEVC packed with great features that media industry love to use. This player uses macOS AV frameworks to decode MV-HEVC and plays time-interleaving signal on capable devices, such as DLP-Link projectors, 3D vision glasses syncing devices, etc. Previously, the player output was flickering, unstable when playing MV-HEVC, and I thought it was due to M1 didn't have hardware decoder for it, or 4K Dolby Vision decoding was too demanding for my Mac, but out of luck, I tried retrieving only 1 eye for each frame output during the DisplayLink call, and the flickering is gone. At least that's what I've seen with a 100Hz screen while testing. Why is the performance improvement so significant? And is there other ways I can improve the performance, and perhaps the energy consumption? The link to the change I've committed
Replies
0
Boosts
0
Views
407
Activity
Jul ’26
AVRoutePickerView's presented route list is automatically dismissed when CXProvider reports the call as connected (`reportOutgoingCall(with:connectedAt:)`)
Hi, I want my user to be able to change their audio output device while calling someone, even before the call is established. But I've run into an issue combining CallKit and AVRoutePickerView. On iOS 26 (Xcode 26.5, tested on iPhone 13 Mini): when my AVRoutePickerView's route list is presented while my call is still connecting (not yet established), the presented list is automatically dismissed the moment the app reports the call as connected via CXProvider.reportOutgoingCall(with:connectedAt:). That doesn't seem natural to me — it should stay open, since the user is actively interacting with unrelated system UI at that moment. This happens even when nothing about the AVAudioSession itself changes: no category change, no route change, no didActivate/didDeactivate callback fires around that time. The dismissal is caused by the CallKit "connected" state transition itself, but I don't know why, or whether it's intentional. Steps to reproduce (sample project below): Tap "Start Fake Call". Within 5 seconds, tap the small route picker button and leave its list open. Wait — at t+5s the app reports the call connected via reportOutgoingCall(connectedAt:), and the list closes itself right after. Is this normal? And is there an official, CallKit-sanctioned way to report a call's connected state without this side effect — some way to keep the route picker stable across that transition? The two workarounds I've found both have real downsides: Calling reportOutgoingCall(connectedAt:) at the very start of the call, before the callee has actually answered , but then CallKit no longer reflects the real call state (Recents/duration would include ringing time, and calls that are never answered would still show as "connected"). Disabling audio device selection entirely until the call is established... works, but hurts the user experience, since users may want to switch output before the call connects. Here's the minimal reproduction: import CallKit import SwiftUI struct ContentView: View { @StateObject private var demo = CallKitDemo() var body: some View { VStack(spacing: 24) { Text(demo.statusText) .font(.system(.body, design: .monospaced)) .multilineTextAlignment(.center) Button("Start Fake Call") { demo.startFakeCall() } .disabled(demo.isCallInProgress) RoutePickerView() .frame(width: 60, height: 60) } .padding() } } private struct RoutePickerView: UIViewRepresentable { func makeUIView(context: Context) -> AVRoutePickerView { let picker = AVRoutePickerView() picker.delegate = context.coordinator return picker } func updateUIView(_ uiView: AVRoutePickerView, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator() } final class Coordinator: NSObject, AVRoutePickerViewDelegate { func routePickerViewWillBeginPresentingRoutes(_ routePickerView: AVRoutePickerView) { print("[REPRO]", Date(), "picker WILL present routes") } func routePickerViewDidEndPresentingRoutes(_ routePickerView: AVRoutePickerView) { print("[REPRO]", Date(), "picker DID end presenting routes <- dismissed here") } } } @MainActor final class CallKitDemo: NSObject, ObservableObject { @Published var statusText = "Idle" @Published var isCallInProgress = false private let provider: CXProvider = { let configuration = CXProviderConfiguration() configuration.supportsVideo = false configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 configuration.supportedHandleTypes = [.generic] return CXProvider(configuration: configuration) }() private let callController = CXCallController() private var currentCallUUID: UUID? override init() { super.init() provider.setDelegate(self, queue: nil) } func startFakeCall() { let uuid = UUID() currentCallUUID = uuid isCallInProgress = true statusText = "Requesting CXStartCallAction..." let handle = CXHandle(type: .generic, value: "repro-call") let startAction = CXStartCallAction(call: uuid, handle: handle) callController.request(CXTransaction(action: startAction)) { error in if let error { print("[REPRO]", Date(), "CXStartCallAction request failed:", error) } } DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in guard let self, currentCallUUID == uuid else { return } print("[REPRO]", Date(), "reportOutgoingCall(connectedAt:)") statusText = "Reported connected at t+5s" provider.reportOutgoingCall(with: uuid, connectedAt: Date()) } DispatchQueue.main.asyncAfter(deadline: .now() + 8) { [weak self] in guard let self, currentCallUUID == uuid else { return } callController.request(CXTransaction(action: CXEndCallAction(call: uuid))) { _ in } currentCallUUID = nil isCallInProgress = false statusText = "Call ended" } } } extension CallKitDemo: CXProviderDelegate { func providerDidReset(_ provider: CXProvider) {} func provider(_ provider: CXProvider, perform action: CXStartCallAction) { action.fulfill() } func provider(_ provider: CXProvider, perform action: CXEndCallAction) { action.fulfill() } func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { print("[REPRO]", Date(), "didActivate") } func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) { print("[REPRO]", Date(), "didDeactivate") } } Thanks for your help !
Replies
1
Boosts
0
Views
644
Activity
Jul ’26