I tried configuring the preferredForwardBufferDuration on devices using 4G and Wi-Fi, and in these cases, AVPlayer works correctly according to the configured buffer duration. However, when the device is connected to a 5G network, the configuration value no longer works.
For example, if I set preferredForwardBufferDuration to 30 seconds, AVPlayer preloads with a buffer of over 100 seconds. I’m not sure how to resolve this, as it’s causing issues with my system.
                    
                  
                Explore the integration of media technologies within your app. Discuss working with audio, video, camera, and other media functionalities.
  
    
    Selecting any option will automatically load the page
  
  
  
  
    
  
  
          Post
Replies
Boosts
Views
Created
                    
                      Hello,
I.m deaf-blind programmer.
I'm experiencing memory issues in my app. Essentially, I'm writing a video.
In this output video, I get content from two sources.
The first source is an already recorded video of 18 seconds (just for testing). It will be shown at the beginning of the output video.
The second source is an array with photos and another array with audio buffers from AVSpeechSynthesizer.write(). The photos will be added along with the audio buffers to the output video, right after adding the 18-second video.
So, in the end, the output video should be:
18-second video + array of photos as video images and, for audio, the buffers from AVSpeechSynthesizer.write().
However, my app crashes as soon as I start the first process.
I'm using AVAssetWriter to write the video and AVAssetReader to read the video.
Below, I'll show the code where
I get the CMSampleBuffer.
I'd like an example of how to add the 18-second video to the beginning of the output video.
It doesn't need to be a big piece of code.
Here it is:
// Variables
var audioReaderBuffers = [CMSAMPLEBUFFER]()
var videoReaderBuffers = [(frame: CVPixelBuffer, time: CMTIME)]()
// Get CMSampleBuffer of a video asset
if let videoURL = videoURL {
let videoAsset = AVAsset(url: videoURL)
Task {
let videoAssetTrack = try await videoAsset.loadTracks(withMediaType: .video).first!
let audioTrack = try await videoAsset.loadTracks(withMediaType: .audio).first!
let reader = try AVAssetReader(asset: videoAsset)
let videoSettings = [
kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA,
kCVPixelBufferWidthKey: videoAssetTrack.naturalSize.width,
kCVPixelBufferHeightKey: videoAssetTrack.naturalSize.height
] as [String: Any]
let readerVideoOutput = AVAssetReaderTrackOutput(track: videoAssetTrack, outputSettings: videoSettings)
let audioSettings = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 2
] as [String : Any]
let readerAudioOutput = AVAssetReaderTrackOutput(track: audioTrack,
outputSettings: audioSettings)
reader.add(readerVideoOutput)
reader.add(readerAudioOutput)
reader.startReading()
// Video CMSampleBuffer
while let sampleBuffer = readerVideoOutput.copyNextSampleBuffer() {
autoreleasepool {
if let imgBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
let pixBuf = imgBuffer as CVPixelBuffer
let pTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
videoReaderBuffers.append((frame: pixBuf, time: pTime))
}
}
}
if let videoURL = videoURL {
let videoAsset = AVAsset(url: videoURL)
Task {
let videoAssetTrack = try await videoAsset.loadTracks(withMediaType: .video).first!
let audioTrack = try await videoAsset.loadTracks(withMediaType: .audio).first!
let reader = try AVAssetReader(asset: videoAsset)
let videoSettings = [
kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA,
kCVPixelBufferWidthKey: videoAssetTrack.naturalSize.width,
kCVPixelBufferHeightKey: videoAssetTrack.naturalSize.height
] as [String: Any]
let readerVideoOutput = AVAssetReaderTrackOutput(track: videoAssetTrack, outputSettings: videoSettings)
let audioSettings = [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 2
] as [String : Any]
let readerAudioOutput = AVAssetReaderTrackOutput(track: audioTrack,
outputSettings: audioSettings)
reader.add(readerVideoOutput)
reader.add(readerAudioOutput)
reader.startReading()
while let sampleBuffer = readerVideoOutput.copyNextSampleBuffer() {
autoreleasepool {
if let imgBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
let pixBuf = imgBuffer as CVPixelBuffer
let pTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
}
                    
                  
                
                    
                      Dear Apple,
I am currently working on Mental Health related research project supported by South Korea Government funding.
In addition to SensorKit access, we are working on the data from microphone. Is there any contact point aside SensorKit access application to discuss the possibility of research data collection from restricted participant samples?
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		Media Technologies
  	
                
                
                SubTopic:
                  
                    
	
		Audio
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      Hello,
I used AVPlayer in my project to play network movie.
Most movie could play normally, but I found the sound will disappear sometimes if I play specified 4K video network stream.
The video will continue playing but audio stops after video is played for a while.
If I pause player and then resume, the sound will be back but disappeared again after several seconds
Check AVPlayerItem status:
isPlaybackLikelyToKeepUp` == true
isPlaybackBufferEmpty` = false
player.volume > 0
According the value above, it seems not cause by empty playback buffer or volume issue. I am so confused for this situation.
Movie information
Video
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High L5.1
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Bit rate mode                            : Variable
Bit rate                                 : 100.0 Mb/s
Width                                    : 3 840 pixels
Height                                   : 2 160 pixels
Display aspect ratio                     : 16:9
Frame rate mode                          : Constant
Frame rate                               : 29.970 (30000/1001) FPS
Audio
Format                                   : AAC LC
Format/Info                              : Advanced Audio Codec Low Complexity
Codec ID                                 : mp4a-40-2
Duration                                 : 5 min 19 s
Bit rate mode                            : Constant
Bit rate                                 : 192 kb/s
Nominal bit rate                         : 48.0 kb/s
Channel(s)                               : 2 channels
Channel layout                           : L R
Sampling rate                            : 48.0 kHz
Frame rate                               : 46.875 FPS (1024 SPF)
Does anyone know if AVPlayer has this limitations when playing high-bitrate movie streams, and  are there any solutions?
                    
                  
                
                    
                      We are processing videos with Core Image filters in our apps, using an AVMutableVideoComposition (for playback/preview and export).
For older devices, we want to limit the resolution at which the video frames are processed for performance and memory reasons. Ideally, we would tell AVFoundation to give us video frames with a defined maximum size into our composition. We thought setting the renderSize property of the composition to the desired size would do that.
However, this only changes the size of output frames, not the size of the source frames that come into the composition's handler block. For example:
let composition = AVMutableVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request in
    let input = request.sourceImage // <- this still has the video's original size
    // ...
})
composition.renderSize = CGSize(width: 1280, heigth: 720) // for example
So if the user selects a 4K video, our filter chain gets 4K input frames. Sure, we can scale them down inside our pipeline, but this costs resources and especially a lot of memory. It would be way better if AVFoundation could decode the video frames in the desired size already before passing it into the composition handler.
Is there a way to tell AVFoundation to load smaller video frames?
                    
                  
                
                    
                      We develop a video playback app on Apple TV which has the two following features:
Its content browsing screen has installed a gesture recognizer for presses on the PlayPause Siri remote button in order to directly launch a playback. The gesture recognizer is attached to the content browsing UIViewController view.
It presents its own custom playback UI with an AVPlayerLayer for the video and supports MPNowPlayingSession in order to publish current playback information and respond to remote commands. It also supports switching between fullscreen and Picture in Picture playback.
Both features work fine, ie. the playback is launched when pressing the PlayPause Siri remote button and, during playback, the playback info are properly advertised on other devices and remote commands are also triggered as expected.
However, when pressing the PlayPause Siri remote button while the video is playing in PiP, the "pause" remote command is sometimes triggered instead of the .playPause gesture recognizer. The issue may not occur the first time but for subsequent PlayPause presses. Navigating a bit in the app UI seems to help preventing the issue to occur.
Finally, the issue only occurs if the video is playing. If the video is paused, the PlayPause Siri remote button gesture is always recognized instead of the remote command.
Please note that, before using MPNowPlayingSession (and the corresponding MPRemoteCommandCenter), the app was using the default MPRemoteCommandCenter to support remote commands and the issue did not occur.
We don't reproduce this issue with the Apple TV app so there's probably something we are not doing right. Has someone any clue?
                    
                  
                
                    
                      Hello,
To create a test project, I want to understand how the video and audio settings would look for a destination video whose content comes from a source video.
I obtained the output from the source video in the audio and video tracks as follows:
let audioSettings = [
    AVFormatIDKey: kAudioFormatLinearPCM,
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2
] as [String : Any]
var audioOutput = AVAssetReaderTrackOutput(track: audioTrack!,
                                           outputSettings: audioSettings)
// Video
let videoSettings = [
    kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA,
    kCVPixelBufferWidthKey: videoTrack!.naturalSize.width,
    kCVPixelBufferHeightKey: videoTrack!.naturalSize.height
] as [String: Any]
var videoOutput = AVAssetReaderTrackOutput(track: videoTrack!, outputSettings: videoSettings)
With this, I'm obtaining the
CMSampleBuffer
using
AVAssetReader.copyNextSampleBuffer
.
How can I add it to the destination video?
Should I use a while loop, considering I already have the
AVAssetWriter
set up?
Something like this:
while let buffer = videoOutput.copyNextSampleBuffer() {
    if let imgBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
        let frame = imgBuffer as CVPixelBuffer
        let time = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        adaptor.append(frame, withMediaTime: time)
    }
}
Lastly, regarding the destination video.
How should the
AVAssetWriterInput
for audio and PixelBuffer of the destination video be set up?
Provide an example, something like:
let audioSettings = […] as [String: Any]
Looking forward to your response.
                    
                  
                
                    
                      I’ve built a custom media player using AVSampleBufferAudioRenderer and AVSampleBufferRenderSynchronizer, and overall, it works great!
However, I’ve noticed some unusual logs popping up:
Domain: NSOSStatusErrorDomain
Error Codes: -16384, -16155, -16512
*That error -16512 keeps happening repeatedly for one of our users, preventing them from playing any media at all.
I’ve searched around but can’t find any documentation explaining what these errors mean.
Has anyone run into this issue or have any suggestions? Any help would be hugely appreciated!
Thanks!
                    
                  
                
                    
                      I am talking about AVCaptureVideoDataOutput.recommendedVideoSettings.
I found sometimes it return nil, there is my test result.
hevc .mov with activeColorSpace sRGB
60FPS -> ok
120FPS -> ok
hevc .mov with activeColorSpace displayP3_HLG
60FPS -> nil
120FPS -> nil
h264 .mov
30FPS -> ok
60FPS -> nil
120FPS -> nil
so, if you don't give a recommend setting, and you don't give a document, how does developer to use it?
                    
                  
                
                    
                      Hi fellow iOS developers! 👋
I've written a Swift code that converts a video (from a URL) into a Live Photo after downloading it. The conversion process seems fine, but when I try to set the generated Live Photo as a wallpaper on iOS 17+, it shows the message 'Motion not Available.'
Has anyone else experienced this issue or know why this might be happening? Could it be related to changes in iOS 17 Live Photo handling or the generated file structure? Any help or suggestions would be greatly appreciated! 🙏
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		Media Technologies
  	
                
                
                SubTopic:
                  
                    
	
		Photos & Camera
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            Photos and Imaging
          
        
        
      
      
    
      
      
      
        
          
            LivePhotosKit JS
          
        
        
      
      
    
      
      
      
        
          
            PhotoKit
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      Hi,
I'm developing a musicKit integration in my iOS App, and I want to select songs from recently played (done it), the problem is that the queue is not auto-generated and the user have to select other song if they want to go forward.
There is any method to ask for similar songs, or recommended songs, from a song that the user has already selected?
It will be really great :)
Also if you know it... There is any publisher for the music duration or I need to do a timer?? Thanks.
David.
                    
                  
                
                    
                      Hi. I encounter some random crashes of my camera app. After some investigations, I found that it's terminated by the system and the crash log did be generated but the information is not quite useful, and here is the log found via the Console app.
Termination & Crash log
"Camera not actively used; AVCaptureEventInteraction not installed":
Received termination request from [osservice<com.apple.SpringBoard>:10931] on <RBSProcessPredicate <RBSProcessInstancePredicate| [app<com.juniperphoton.PhotonCam]>> with context <RBSTerminateContext| explanation:Capture Application Requirements Unmet: "Camera not actively used; AVCaptureEventInteraction not installed" reportType:CrashLog maxTerminationResistance:Interactive>
The crash log exported from the device will have some common information like:
It's a EXC_CRASH (SIGKILL) type with no termination reason.
Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: RUNNINGBOARD 0 
It's triggered by the main thread, but it seems to be waiting for an event to process.
Triggered by Thread:  0
Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	       0x1ee165788 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1ee168e98 mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1ee168db0 mach_msg_overwrite + 424
3   libsystem_kernel.dylib        	       0x1ee168bfc mach_msg + 24
4   CoreFoundation                	       0x19cbe47f4 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x19cbe3ea0 __CFRunLoopRun + 1212
6   CoreFoundation                	       0x19cc36274 CFRunLoopRunSpecific + 588
7   GraphicsServices              	       0x1e9d6d4c0 GSEventRunModal + 164
8   UIKitCore                     	       0x19f783480 -[UIApplication _run] + 816
9   UIKitCore                     	       0x19f3a9410 UIApplicationMain + 340
10  UIKitCore                     	       0x19fae4bb0 0x19f394000 + 7670704
11  PhotonCam                     	       0x1002e7e3c 0x1002cc000 + 114236
12  dyld                          	       0x1c2d5ade8 start + 2724
Address size fault on the main thread
Thread 0 crashed with ARM Thread State (64-bit):
    ...
   far: 0x0000000000000000  esr: 0x56000080  Address size fault
I have once tried to reproduce this issue when the app is attached with debugger, and it says:
Terminated due to signal 9
When the crash or termination happened, the app:
No AVCaptureSession is running.
The app is in the foreground and users are interacting with some functions like viewing photos or editing photos in the app. When users exit the camera view, like entering the gallery or settings, the camera session will be stopped.
Both TestFlight and Debug build will have the same issue.
No 3rd party crash reporter is installed(I deliberately disable it in Debug build and TestFlight build)
It has adopted the LockedCameraCapture, but current it's running on the main app target(if not, my app will have a button of unlock, so I can confirm about this).
Also, when it comes to the memory consumption,  there is no JetsamEvent around the crash time.
Device and app information
Additionally, some information about the tech stack and the current state of my device and my app:
iPhone 16 Pro with iOS 18.2 Beta 3.
The app is a camera based app(it's PhotonCam and you can find it on the App Store), its main functionality is the camera feature using AVFoundation + Core Image + Metal to deliver camera functionality.
It has adopted the Camera Control, AVCaptureEventInteraction and LockedCameraCapture features.
If I remember it right, it occurs in iOS 18.1 Release build, but currently I have no such device to confirm. But in iOS 17.x the issue has never happened.
Regarding to this termination, on top of my head is the "watchdog" mechanism that will terminate the process that is running on the LockedCameraCapture feature. However I can make sure that currently the app is running as the main target on the home screen.
Has anybody encountered this kind of issue and has found some solutions? Thanks in advance.
                    
                  
                
                    
                      We are experiencing thousands of crashes in our application when attempting to present the camera through a Web View. The app crashes during this process, and the crash logs point to
WebCore::AVVideoCaptureSource::create
WebCore::RealtimeMediaSourceCenter::getUserMediaDevices.
This issue has only been observed in iOS 18.2 beta versions (beta 1 - 22C5109p, beta 2 - 22C5125e, beta 3 - 22C5131e).
In iOS versions below 18.2, the functionality works and we haven't identified any correlation with specific device models. The problem seems to stem from a WebCore framework introduced in these beta releases 18.2.
We kindly request a review and fix for this issue in upcoming beta releases to restore functionality. Let us know if there are any workarounds or adjustments we can implement in the interim.
Thank you for your attention to this matter.
                    
                  
                
                    
                      Hello, I'm fairly new to AVAudioEngine and I'm trying to connect 2 mono nodes as left/right input to a stereo node. I was successful in splitting the input audio to 2 mono nodes using AVAudioConnectionPoint and channelMap.
But I can't figure out how to connect them back to a stereo node.
I'll post the code I have so far. The use case for this is that I'm trying to process the left/right channels with separate audio units.
Any ideas?
                let monoFormat = AVAudioFormat(standardFormatWithSampleRate: nativeFormat.sampleRate, channels: 1)!
                
                let leftInputMixer = AVAudioMixerNode()
                let rightInputMixer = AVAudioMixerNode()
                let leftOutputMixer = AVAudioMixerNode()
                let rightOutputMixer = AVAudioMixerNode()
                let channelMixer = AVAudioMixerNode()
                
                [leftInputMixer, rightInputMixer, leftOutputMixer, 
                 rightOutputMixer, channelMixer].forEach { engine.attach($0) }
                
                let leftConnectionR = AVAudioConnectionPoint(node: leftInputMixer, bus: 0)
                let rightConnectionR = AVAudioConnectionPoint(node: rightInputMixer, bus: 0)
                
                plugin.leftInputMixer = leftInputMixer
                plugin.rightInputMixer = rightInputMixer
                plugin.leftOutputMixer = leftOutputMixer
                plugin.rightOutputMixer = rightOutputMixer
                plugin.channelMixer = channelMixer
                leftInputMixer.auAudioUnit.channelMap = [0]
                rightInputMixer.auAudioUnit.channelMap = [1]
                engine.connect(previousNode, to: [leftConnectionR, rightConnectionR], fromBus: 0, format: monoFormat)
                
                // Process right channel, pass through left channel
                engine.connect(rightInputMixer, to: plugin.audioUnit, format: monoFormat)
                engine.connect(plugin.audioUnit, to: rightOutputMixer, format: monoFormat)
                engine.connect(leftInputMixer, to: leftOutputMixer, format: monoFormat)
                
                // Mix back to stereo?
                engine.connect(leftOutputMixer, to: channelMixer, format: stereoFormat)
                engine.connect(rightOutputMixer, to: channelMixer, format: stereoFormat)
                    
                  
                
                    
                      I am experiencing an issue while recording audio using AVAudioEngine with the installTap method. I convert the AVAudioPCMBuffer to Data and send it to a UDP server. However, when I receive the Data and play it back, there is continuous crackling noise during playback.
I am sending audio data using this library "https://github.com/mindAndroid/swift-rtp" by creating packet and send it.
Please help me resolve this issue. I have attached the code reference that I am currently using.
Thank you.
ViewController.swift
                    
                  
                
                    
                      Hi All, I'm working on a camera system extension where the main app is supposed to transfer a video stream using IOSurface memory sharing to the cam extension.
I have built a sample app that does contains all the logic, but without a camera extension. So I'm essentially using IOSurface to render a video in one SwiftUI view and show the result in another SwiftUI view. Just for testing purposes. And everything works fine so far.
Now, when moving the receiver code to the camera extensions, I'm having problems in accessing the IOSurface via ID. I am sharing the IOSurface ID via UserDefaults. I know from the logs the ID is correctly transferred.
Here is the code that uses IOSurfaceLookup to get the IOSurface. But this fails with the given message. The error message prints the surface ID which is the correct one. I know this from the main app where I get the ID and print it as well.
private var surfaceId: Int = -1 {
    didSet {
        logger.info("surfaceId has changed")
        if surfaceId == -1 {
            stopReceivingFrames()
            ioSurface = nil
        } else {
            guard let surface = IOSurfaceLookup(IOSurfaceID(surfaceId)) else {
                logger.error("failed to lookup IOSurface with ID: \(self.surfaceId)")
                return
            }
            self.ioSurface = surface
            logger.info("surface set, now starting receiving frames")
            startReceivingFrames()
        }
    }
}
My gut feeling says that this issue might be related to some missing entitlement, sandboxing. In general, I have a working camera extension. I'm just not able to render a video in the main app, and send it over to the camera extension to overlay another web cam.
Both, the main app and camera extension are in the same XCode workspace and share the same AppGroup.
In short, my actual questions are:
Is there any entitlement required for using IOSurface between app and camera system extension?
Is using IOSurface actually possible in system extensions?
Is there any specific setting/requirement that I need to handle to make this work?
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		Media Technologies
  	
                
                
                SubTopic:
                  
                    
	
		Photos & Camera
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            IOSurface
          
        
        
      
      
    
      
      
      
        
          
            System Extensions
          
        
        
      
      
    
      
      
      
        
          
            Camera
          
        
        
      
      
    
      
      
      
        
          
            Core Media
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      I have an app that allows the user to change a photo’s EXIF metadata. To do this, I request a content editing input, get the full size image, modify its properties, create a content editing output, write the output image to the rendered content URL, then call performChanges on the PHPhotoLibrary creating an asset change request for that asset setting its content editing output. This works as expected for regular photos but Live Photos get turned off converted to a regular photo.
To address this, I’m doing something similar by changing the properties of the .photo image in the Live Photo. I detect when the content editing input has a Live Photo, create a Live Photo editing context, set a frame processor that returns the frame’s image after setting its properties to the updated properties when the frame type is photo, then I create the content editing output and save the Live Photo to that output. It modifies the Live Photo successfully, but the metadata is not updated. If you get the full size image again the properties are the original properties. If you look at the EXIF metadata using an app like Metapho it remains unchanged. What am I doing wrong here? Thanks!
let imageURL = contentEditingInput.fullSizeImageURL!
let inputImage = CIImage(contentsOf: imageURL, options: [.applyOrientationProperty: true])!
var metadata: [AnyHashable: Any] = inputImage.properties
// Edit the metadata as desired...
let editingContext = PHLivePhotoEditingContext(livePhotoEditingInput: contentEditingInput)!
editingContext.frameProcessor = { frame, error -> CIImage? in
    // Edit only the still photo
    if frame.type == .photo {
        return frame.image.settingProperties(metadata)
    }
    return frame.image
}
let contentEditingOutput = try await withCheckedThrowingContinuation { continuation in
    let editingOutput = PHContentEditingOutput(contentEditingInput: contentEditingInput)
    editingOutput.adjustmentData = adjustmentData
    
    editingContext.saveLivePhoto(to: editingOutput) { success, error in
        if success {
            continuation.resume(returning: editingOutput)
        } else {
            continuation.resume(throwing: error!)
        }
    }
}
try await PHPhotoLibrary.shared().performChanges {
    let request = PHAssetChangeRequest(for: asset)
    request.contentEditingOutput = contentEditingOutput
}
                    
                  
                
                    
                      Case-ID: 10075936
PLATFORM AND VERSION
iOS
Development environment: Xcode Xcode15, macOS macOS 14.5
Run-time configuration: iOS iOS18.0.1
DESCRIPTION OF PROBLEM
Our customer experienced an one-way audio issue when switching from the built-in microphone to AirPods Pro (model: A2084, version: 6F21) during a VoIP call. The issue occurred when the customer's voice could not be heard by the other party, but the customer could hear the other party's voice.
STEPS TO REPRODUCE
Here are the details:
After the issue occurred, subsequent VoIP calls experienced the same issue when using AirPods Pro, but the issue did not occur when using the built-in microphone. The issue could only be resolved by restarting the system, and killing the app did not work.
Log and code analysis:
In WebRTC, it listens for AVAudioSessionRouteChangeNotification. In the above scenario, when webrtc receives the route change notification, it will print the audio session configuration information. At this point, the input channel count was 0, which was abnormal:
[Webrtc] (RTCLogging.mm:33): (audio_device_ios.mm:535 HandleValidRouteChange): RTC_OBJC_TYPE(RTCAudioSession):
{
category: AVAudioSessionCategoryPlayAndRecord
categoryOptions: 128
mode: AVAudioSessionModeVoiceChat
isActive: 1
sampleRate: 48000.00
IOBufferDuration: 0.020000
outputNumberOfChannels: 2
inputNumberOfChannels: 0
outputLatency: 0.021500
inputLatency: 0.005000
outputVolume: 0.600000
isPreferredSpeaker: 0
isCallkit: 0
}
If app tries to call API, setPreferredInputNumberOfChannels at this point, it will fail with an error code of -50:
setConfiguration:active:shouldSetActive:error:]): Failed to set preferred input number of channels(1): The operation couldn’t be completed. (OSStatus error -50.)
Our questions:
When AVAudioSession is active, the category and mode are as expected. Why is the input channel count 0?
Assuming that the AVAudioSession state is abnormal at this point, why does killing the app not resolve the issue, and why does the system need to be restarted to resolve the issue?
Is it possible that the category and mode of the AVAudioSession fetched by the app is currently wrong? Does it need to be reset again each time the callkit is started if the category and mode fetched are the same as the values to be set?
                    
                  
                
                    
                      Within my app, I have:
for try await update in LockedCameraCaptureManager.shared.sessionContentUpdates {
It seems that the first time my app opens from LockedCameraCapture (after enabling camera permissions etc...) this update is never called and the user will not see their capture (.added or .initial)
If I then try to take another picture/video through my LockedCameraCapture control, it takes the video, opens the app as before, but this time sessionContentUpdates is called twice, once for the first video and once for the second video!
After that it doesn't seem to occur again and all works perfectly!
My device is: iPhone 16 Pro Max, iOS 18.2 developer beta
Has anyone experienced this?
                    
                  
                
                    
                      Issue Description
When playing certain MIDI files using AVMIDIPlayer, the initial volume settings for individual tracks are being ignored during the first playback. This results in all tracks playing at the same volume level, regardless of their specified volume settings in the MIDI file.
Steps to Reproduce
Load a MIDI file that contains different volume settings for multiple tracks
Start playback using AVMIDIPlayer
Observe that all tracks play at the same volume level, ignoring their individual volume settings
Current Behavior
All tracks play at the same volume level during initial playback
Track volume settings specified in the MIDI file are not being respected
This behavior consistently occurs on first playback of affected MIDI files
Expected Behavior
Each track should play at its specified volume level from the beginning
Volume settings in the MIDI file should be respected from the first playback
Workaround
I discovered that the correct volume settings can be restored by:
Starting playback of the MIDI file
Setting the currentPosition property to (current time - 1 second)
After this operation, all tracks play at their intended volume levels
However, this is not an ideal solution as it requires manual intervention and may affect the playback experience.
Questions
Is there a way to ensure the track volume settings are respected during the initial playback?
Is this a known issue with AVMIDIPlayer?
Are there any configuration settings or alternative approaches that could resolve this issue?
Technical Details
iOS Version: 18.1.1 (22B91)
Xcode Version: 16.1 (16B40)