AVFoundation

RSS for tag

Work with audiovisual assets, control device cameras, process audio, and configure system audio interactions using AVFoundation.

Posts under AVFoundation tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Issue while accessing file from another PC on local network using document picker with SMB.
We are trying to access and copy some files [e.g., video file] from another PC on local network using SMB protocol. We found some third party libraries like AMSMB2 for this. But we want to try to use Apple inbuilt features like File management mentioned in - https://developer.apple.com/videos/play/wwdc2019/719/ We could able to select file from SMB server using document picker in app manually. Also we got its url in debug which gets generated under "Shared" section in files app. The URL I get from document picker is -> /private/var/mobile/Library/LiveFiles/com.apple.filesystems.smbclientd/asd0QUsers/testuser/iOS/SMB_ShareFolder Now we want to avoid manual selection of file to user. We want directly open "/private/var/mobile/Library/LiveFiles/com.apple.filesystems.smbclientd/asd0QUsers/testuser/iOS/SMB_ShareFolder" path as soon as document picker opens. So that user can directly select file. But it is not working. It opens normal files app and all folders. Getting below error - Access Shared URL directly using documentPicker "Error - CFURLResourceIsReachable failed because it was passed a URL which has no scheme" Sharing the code which I tried to open this shared folder directly : let url = URL (string: "/private/var/mobile/Library/LiveFiles/com.apple.filesystems.smbclientd/asd0QUsers/TestUser/iOS/SMB_ShareFolder") let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.folder]) documentPicker.delegate = self documentPicker.allowsMultipleSelection = false documentPicker.modalPresentationStyle = .custom documentPicker.definesPresentationContext = true documentPicker.directoryURL = url! documentPicker.transitioningDelegate = customTransitioningDelegate present(documentPicker, animated: true, completion: nil) I get error in console - CFURLResourceIsReachable failed because it was passed a URL which has no scheme 2024-07-05 17:49:38.501059+0530 VideoImportPOC[1327:336989] [DocumentManager] revealDocumentAtURL encountered an error: Error Domain=NSCocoaErrorDomain Code=262 "The file couldn’t be opened because the specified URL type isn’t supported." Can you please provide inputs if it is possible access files directly in this way? or any other suggestions. like 1 What’s New in File Management and Quick Look - WWDC19 - Videos - Apple Developer Your iOS app can now access files stored on external devices via USB and SMB. Understand best practices for creating a document-based app...
0
0
41
4h
Location not visible in video recorded in third party app
I recently bought an insta360 flow gimbal. when recording video with the instaflow app, I cannot see the location in apple photos app and all other apple apps. However I can see the location in windows photos app once I downloaded the videos into my windows PC. The location is also visible in android app once I share it through google account. With an exif app, I can see the location meta data in exif table as well, but again not shown as location. exiftool in my pc can also see the meta data including location as in attached screenshot. Compared to video shot with built-in camera app, I cannot find any difference in terms of location meta data. What could be wrong? I contacted insta360 app support, they do not seem to understand what's going on, just asking for very simple questions again and again like do you enable GPS location access, are you shooting video? I also contacted apple support, they are just saying it's thirdparty issue and refusing to help further. If it's really thirdparty issue how come the location data is actually embeded as meta data, and windows pc and android device can see the location? BTW, I air drop this video to all my apple devices like iPhone 15 ultra and ipad air, and very old iPhone, all of them cannot see the location.
0
0
95
1d
FactoryInstall Unable to query results, error: 5
I am developing an iPhone application. When I start testing in a simulator or on an actual device, I get the following message depending on the model. I don't see any problem with the actual operation of the app, but I don't know how to resolve this error. #FactoryInstall Unable to query results, error: 5 Unable to list voice folder Unable to list voice folder Unable to list voice folder Unable to list voice folder Unable to list voice folder I have tried to resolve the problem by following the steps below, but it hasn’t had any affect on the error. Is it OK to leave this error as it is? If you know how to resolve it, please let me know. Clear the Xcode cache: Go to the path of the DerivedData folder and delete all of its contents. Clean Build folder: Select "Product" -> "Clean Build Folder" from the Xcode menu. Restart: Restart Xcode and the simulator. Software update: Make sure you are using the latest version of Xcode and macOS. Reinstallation: Uninstall Xcode once and reinstall it. Reset the simulator
0
0
62
1d
Issue with AVAsset access in iOS 18 beta
NSString *filePath = @"/var/mobile/Media/DCIM/100APPLE/IMG_0800.MP4"; NSURL *fileURL = [NSURL fileURLWithPath:filePath]; AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileURL options:nil]; Before iOS 18, you could access AVAsset using the method mentioned above, but starting from the iOS 18 beta version, the following error appears Error Domain=NSCocoaErrorDomain Code=257 "未能打开文件“IMG_0800.MP4”,因为你没有查看它的权限。" UserInfo={NSURL=file:///var/mobile/Media/DCIM/100APPLE/IMG_0800.MP4, AVErrorFailedDependenciesKey=( "assetProperty_AssetType" ), NSUnderlyingError=0x30c497f60 {Error Domain=NSOSStatusErrorDomain Code=-12203 "(null)"}}
0
0
82
2d
Voice recorder app recording in dual mono instead of stereo
Hi y'all, After getting mono recording working, I want to differentiate my app from the standard voice memos to allow for stereo recording. I followed this tutorial (https://developer.apple.com/documentation/avfaudio/capturing_stereo_audio_from_built-in_microphones) to get my voice recorder to record stereo audio. However, when I look at the waveform in Audacity, both channels are the same. If I look at the file info after sharing it, it says the file is in stereo. I don't exactly know what's going on here. What I suspect is happening is that the recorder is only using one microphone. Here is the relevant part of my recorder: // MARK: - Initialization override init() { super.init() do { try configureAudioSession() try enableBuiltInMicrophone() try setupAudioRecorder() } catch { // If any errors occur during initialization, // terminate the app with a fatalError. fatalError("Error: \(error)") } } // MARK: - Audio Session and Recorder Configuration private func enableBuiltInMicrophone() throws { let audioSession = AVAudioSession.sharedInstance() let availableInputs = audioSession.availableInputs guard let builtInMicInput = availableInputs?.first(where: { $0.portType == .builtInMic }) else { throw Errors.NoBuiltInMic } do { try audioSession.setPreferredInput(builtInMicInput) } catch { throw Errors.UnableToSetBuiltInMicrophone } } private func configureAudioSession() throws { let audioSession = AVAudioSession.sharedInstance() do { try audioSession.setCategory(.record, mode: .default, options: [.allowBluetooth]) try audioSession.setActive(true) } catch { throw Errors.FailedToInitSessionError } } private func setupAudioRecorder() throws { let date = Date() let dateFormatter = DateFormatter() dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.dateFormat = "yyyy-MM-dd, HH:mm:ss" let timestamp = dateFormatter.string(from: date) self.recording = Recording(name: timestamp) guard let fileURL = recording?.returnURL() else { fatalError("Failed to create file URL") } self.currentURL = fileURL print("Recording URL: \(fileURL)") do { let audioSettings: [String: Any] = [ AVFormatIDKey: Int(kAudioFormatMPEG4AAC), AVLinearPCMIsNonInterleaved: false, AVSampleRateKey: 44_100.0, AVNumberOfChannelsKey: isStereoSupported ? 2 : 1, AVLinearPCMBitDepthKey: 16, AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue ] audioRecorder = try AVAudioRecorder(url: fileURL, settings: audioSettings) } catch { throw Errors.UnableToCreateAudioRecorder } audioRecorder.delegate = self audioRecorder.prepareToRecord() } //MARK: update orientation public func updateOrientation(withDataSourceOrientation orientation: AVAudioSession.Orientation = .front, interfaceOrientation: UIInterfaceOrientation) async throws { let session = AVAudioSession.sharedInstance() guard let preferredInput = session.preferredInput, let dataSources = preferredInput.dataSources, let newDataSource = dataSources.first(where: { $0.orientation == orientation }), let supportedPolarPatterns = newDataSource.supportedPolarPatterns else { return } isStereoSupported = supportedPolarPatterns.contains(.stereo) if isStereoSupported { try newDataSource.setPreferredPolarPattern(.stereo) } try preferredInput.setPreferredDataSource(newDataSource) try session.setPreferredInputOrientation(interfaceOrientation.inputOrientation) } Here is the relevant part of my SwiftUI view: RecordView() .onAppear {             Task {                 if await AVAudioApplication.requestRecordPermission() {                     // The user grants access. Present recording interface.                     print("Permission granted")                 } else {                     // The user denies access. Present a message that indicates                     // that they can change their permission settings in the                     // Privacy & Security section of the Settings app.                     model.showAlert.toggle()                 }                 try await recorder.updateOrientation(interfaceOrientation: deviceOrientation)             }         }         .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in                     if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,                        let orientation = windowScene.windows.first?.windowScene?.interfaceOrientation {                         deviceOrientation = orientation                         Task {                             do {                                 try await recorder.updateOrientation(interfaceOrientation: deviceOrientation)                             } catch {                                 throw Errors.UnableToUpdateOrientation                             }                         }                     }                 } Here is the full repo: https://github.com/aabagdi/MemoMan/tree/MemoManStereo Thanks for any leads!
1
0
112
2d
Reading Files from USB-C Storage on iOS Devices
Hello, We are currently developing a device with a USB-C drive, and we want to connect it to iOS devices to import the stored files into our app. I have a few questions regarding this: MFi Certification Requirement We believe that MFi certification is not necessary for USB-C connections. Is this understanding correct? Implementation Method We prefer not to use standard components like UIDocumentPickerViewController. Are there any methods to access the file system directly, or any other suitable approaches you can recommend? If anyone has experience with this, your advice would be greatly appreciated. Thank you in advance.
3
0
89
1d
Exporting Audio with Scaled Segments Causes copyNextSampleBuffer to Hang
I am trying to export an AVMutableComposition with a single audio track. This track has a scaled AVCompositionTrackSegment to simulate speed changes up to 20x. I need to use AVAssetWriter and AVAssetReader classes for this task. When I scale the source duration up to a maximum of 5x, everything works fine. However, when I scale it to higher speeds, such as 20x, the app hangs on the copyNextSampleBuffer method. I'm not sure why this is happening and how to prevent it. Also, this often happens if the exported audio track has segments with different speeds. (The duration of the audio file in the example is 47 seconds.) Example of code: class Export { func startExport() { let inputURL = Bundle.main.url(forResource: "Piano", withExtension: ".m4a")! let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let outputURL = documentsDirectory.appendingPathComponent("Piano20x.m4a") try? FileManager.default.removeItem(at: outputURL) print("Output URL: \(outputURL)") changeAudioSpeed(inputURL: inputURL, outputURL: outputURL, speed: 20) } func changeAudioSpeed(inputURL: URL, outputURL: URL, speed: Float) { let urlAsset = AVAsset(url: inputURL) guard let assetTrack = urlAsset.tracks(withMediaType: .audio).first else { return } let composition = AVMutableComposition() let compositionAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) do { try compositionAudioTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: assetTrack.timeRange.duration), of: assetTrack, at: .zero) } catch { print("Failed to insert audio track: \(error)") return } let scaledDuration = CMTimeMultiplyByFloat64(assetTrack.timeRange.duration, multiplier: Double(1.0 / speed)) compositionAudioTrack?.scaleTimeRange(CMTimeRangeMake(start: .zero, duration: assetTrack.timeRange.duration), toDuration: scaledDuration) print("Scaled audio from \(assetTrack.timeRange.duration.seconds)sec to \(scaledDuration.seconds) sec") compositionAudioTrack?.segments do { let compositionAudioTracks = composition.tracks(withMediaType: .audio) let assetReader = try AVAssetReader(asset: composition) let audioSettings: [String: Any] = [ AVFormatIDKey: kAudioFormatLinearPCM, AVSampleRateKey: 44100, AVNumberOfChannelsKey: 2, AVLinearPCMBitDepthKey: 16, AVLinearPCMIsBigEndianKey: false, AVLinearPCMIsFloatKey: false, AVLinearPCMIsNonInterleaved: false ] let readerOutput = AVAssetReaderAudioMixOutput(audioTracks: compositionAudioTracks, audioSettings: audioSettings) assetReader.add(readerOutput) let assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: .m4a) let writerInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings) assetWriter.add(writerInput) assetReader.startReading() assetWriter.startWriting() assetWriter.startSession(atSourceTime: .zero) let conversionQueue = DispatchQueue(label: "ConversionQueue") writerInput.requestMediaDataWhenReady(on: conversionQueue) { while writerInput.isReadyForMoreMediaData { if let sampleBuffer = readerOutput.copyNextSampleBuffer() { // APP hangs here!!! writerInput.append(sampleBuffer) } else { writerInput.markAsFinished() assetWriter.finishWriting { print("Export completed successfully") } break } } } } catch { print("Failed with error: \(error)") } } }
0
0
62
3d
Spatial Video Capturing on iPhone 15 Pro
Hi all, I tried the "isSpatialVideoCaptureEnabled" with AVCaptureMovieFileOutput mentioned in WWDC24: Build compelling spatial photo and video experiences, and it works. But there are some issues and questions: Below codes, the change.newValue always nil so the code seems not work. let observation = videoDevice.observe(\.spatialCaptureDiscomfortReasons) { (device, change) in guard let newValue = change.newValue else { return } if newValue.contains(.subjectTooClose) { // Guide user to move back } if newValue.contains(.notEnoughLight) { // Guide user to find a brighter environment } } AVCaptureMovieFileOutput is support spatial video capturing. May I ask if AVCaptureVideoDataOutput will also support spatial video capturing?
0
1
105
4d
AVPlayer & Quicktime Player reporting incorrect total duration
I have an mp4 file (which is around 25min) which i need to play but if i open it in quick time player or AVplayer, it shows as around 55min in those two platfroms. I don't understand why this happens. It correctly shows the time when opening with a browser or VSCode built in video playback. Here is the link to the file: https://www.dropbox.com/scl/fi/hbg59uqx8xdpiqbnx5wz8/videoplayback-1.mp4?rlkey=7o8l8m7j8dhq0o6f3zssgv9bd&st=5lt6apug&dl=0
0
0
77
5d
-[AVCaptureSession init] has a watchdog issue in iOS 17
My app has encountered many watchdog issues on iOS 17, with stack traces as follows: Attributed: Call stack 0: mach_msg2_trap (in libsystem_kernel.dylib) + 7 mach_msg2_internal (in libsystem_kernel.dylib) + 79 mach_msg_overwrite (in libsystem_kernel.dylib) + 435 mach_msg (in libsystem_kernel.dylib) + 23 _dispatch_mach_send_and_wait_for_reply (in libdispatch.dylib) + 543 dispatch_mach_send_with_result_and_wait_for_reply (in libdispatch.dylib) + 59 xpc_connection_send_message_with_reply_sync (in libxpc.dylib) + 263 FigXPCConnectionSendSyncMessageCreatingReply (in CoreMedia) + 291 FigXPCRemoteClientSendSyncMessageCreatingReply (in CoreMedia) + 47 FigCaptureSessionRemoteCreate (in CMCapture) + 131 -[AVCaptureSession _createFigCaptureSession] (in AVFCapture) + 123 -[AVCaptureSession _initWithMediaEnvironment:] (in AVFCapture) + 619 -[AVCaptureSession init] (in AVFCapture) + 415 We also have many iOS 16 users, but have never encountered a watchdog issue with the AVCaptureSession init method in iOS 16. Is there any change in iOS 17 that could have caused this? How can I avoid this issue? The complete stack trace is attached avfoundation-watchdog.txt
1
0
125
6d
Ability to hide/show tvOS AVPlayerViewController's progress bar
I'm working on streaming tvOS app and as you know there are mostly two type of video streams - live and vod. AVPlayerViewController handles these types of streams by showing respective playback controls. Recently I got a task to implement synchronous vod playback(syncVod), it's when we need to simulate live playback while actual vod stream playback. In order to simulate live playback below things needs to be handled: Disabling scrubbing via remote. (Done. playerVc.requiresLinearPlayback = true) Disabling info panel view w/play "From beginning" button. (Done, playerVc.playbackControlsIncludeInfoViews = false) Disabling play/pause button.(Done, not ideally though. On rate change observer - if player.rate == 0 && playbackMode == .syncVod { player.play() return }). Why not ideal solution - tapping on remote causes quite short hiccup in playback - but playback resumes, no actual pause happens. Hiding progress bar and time labels. :( Point #4 is the main problem, we can't hide progress bar and it's related UI elements(time labels) particularly, but only hide all playback controls - playerVc.showsPlaybackControls = false. The thing is I have custom buttons in transportBarCustomMenuItems and hiding all playback controls is not the right option for me. Implementing custom playback controls panel is kind of heavy lift, but as of now it seems the only proper way of implementing syncVod playback ideally. Did anyone face similar issue and could resolve it w/out implementing custom playback controls panel ? Is there way to hide progress bar only in tvOS AVPlayerViewController?
0
0
116
1w
Black frames in recorded videos
While using the native AVfoundation for recording videos I am able to see black frames/ screen in the beginning and end of the video for 2 millisecond at the end and beginning . func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { guard isRecording, let assetWriter = assetWriter else { return } let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer) if recordingStartTime == nil { recordingStartTime = timestamp let adjustedStartTime = CMTimeAdd(timestamp, CMTimeMake(value: -2, timescale: 1000)) // Adjust start time slightly earlier assetWriter.startSession(atSourceTime: adjustedStartTime) print("Status: \(assetWriter.status.rawValue)") } if output == videoOutput { if videoInput?.isReadyForMoreMediaData == true { videoInput?.append(sampleBuffer) } } else if output == audioOutput { if audioInput?.isReadyForMoreMediaData == true { audioInput?.append(sampleBuffer) } } if let startTime = recordingStartTime, CMTimeSubtract(timestamp, startTime) >= recordingInterval { isRecording = false let adjustedEndTime = CMTimeAdd(timestamp, CMTimeMake(value: 2, timescale: 1000)) // Adjust end time slightly later assetWriter.finishWriting { [weak self] in print("Finished writing segment") self?.startRecording() // Start a new recording segment } recordingStartTime = nil } }
1
1
101
1w
TestFlight build upload with error ITMS-90338: Non-public API usage
Hello, today when we uploaded a new TestFlight Mac Catalyst build we received an email about the build being invalid: TMS-90338: Non-public API usage - The app references non-public symbols in {app name}: _AVCaptureDeviceTypeBuiltInTelephotoCamera, _AVCaptureDeviceTypeBuiltInTrueDepthCamera, _AVCaptureDeviceTypeBuiltInUltraWideCamera, _AVCaptureSessionInterruptionReasonKey, _AVCaptureSessionInterruptionSystemPressureStateKey, _AVCaptureSystemPressureLevelCritical, _AVCaptureSystemPressureLevelFair, _AVCaptureSystemPressureLevelNominal, _AVCaptureSystemPressureLevelSerious, _AVCaptureSystemPressureLevelShutdown. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed. For further information, visit the Technical Support Information at http://developer.apple.com/support/technical/ We've been uploading builds the same way for months, using the same Xcode 15.2 and dependency versions, and have checked our most recent commits since the last release and nothing was updated around AVFoundation, archiving, etc. Did anything change on Apple's side recently? We use Xcode 15.2 to build/archive/upload and xcodebuild to run all commands.
2
3
278
1w
Frame Discontinuity Reasons
I have an app that uses a MultiCamCaptureSession, the devices of which are builtInUltraWideCamera and builtInLiDARDepthCamera cameras. Occasionally when outside I get some frame drops due to discontinuity that end in the media services being reset: [06-24 11:27:13][CameraSession] Capture session runtime error: related decl 'e' for AVError(_nsError: Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo={NSLocalizedDescription=Cannot Complete Action, NSLocalizedRecoverySuggestion=Try again later.}) This runtime error notification is always superseded by 4-5 frame drops : [06-24 11:27:10][CaptureSession] Dropped frame because Discontinuity Logging the system temperature shows [06-24 11:27:10][CaptureSession] Temperature is 'Fair' I have some inclination that the frame discontinuity is being caused by the whileBalanceMode of the capture session, perhaps the algorithm requires 5 recent frames to work. I had a similar problem with the lidar depth camera where with filtering enabled exactly 5 frame drops would make the media services reset. When the whiteBalanceMode is locked I do slightly better with 10 frame drops before the mediaServices are reset. Is there any logging utility to determine the actual reason? All of these sampleBuffers come with no info attachment only the not so useful "Dropped frame because Discontinuity." Any ideas for solving this would be helpful as well. Maybe tuning the camera to work better with quickly varying lighting conditions?
1
0
152
6d
Crash with AVMutableComposition insertTimeRange Method
A small number of crashes are being reported on Firebase. When attempting to use the insertTimeRange:ofAsset:atTime:error: method of AVMutableComposition, a crash occurred with the error message -[__NSArrayM insertObject:atIndex:]: object cannot be nil. Most of them appear in versions of ios 17.0 and above. Here's my code: - (AVMutableComposition *)createtrimAsset:(AVAsset *)asset andStartTime:(CGFloat)startTime endTime:(CGFloat)endTime{ NSError *error = nil; CGFloat timescale = 1000000; AVMutableComposition *mutableComposition = [AVMutableComposition composition]; CMTime sStartTime = CMTimeMakeWithSeconds(CMTimeGetSeconds(asset.duration)*startTime, timescale); CMTime eEndTime = CMTimeMakeWithSeconds(CMTimeGetSeconds(asset.duration)*endTime, timescale); [mutableComposition insertTimeRange:CMTimeRangeMake(sStartTime, CMTimeSubtract(eEndTime, sStartTime)) ofAsset:asset atTime:kCMTimeZero error:&error]; return mutableComposition; } I attempted to reproduce this crash by deliberately setting the timeRange or asset to unusual values, such as asset=nil, or asset.duration=0, or asset.duration=NAN, but all attempts failed. What could be causing this exception? Any advice would be of great help to me.
0
0
90
1w
Focus Peaking/Contrast Detection as seen in Final Cut Camera App
Hello everyone, with the release of Apple's new Final Cut Camera App, we see the possibility to overlay a Focus Peaking indicator over the camera feed, showing focussed areas. We have already had a contrast based autofocus system for some time via the AVCaptureDevice.Format.AutoFocusSystem.contrastDetection, but I haven't found a way to actually present contrast areas to the user. Given that Apple now natively has such an algorithm for the Final Cut Camera App, I wonder if we devs now also get access to this. If not, does anybody know of implementations of focus peaking out there? Thanks and with best regards
0
0
191
1w
ProRes 4444 blocky compression artifacts
I’m creating a objective C command-line utility to encode RAW image sequences to ProRes 4444, but I’m encountering, blocky compression artifacts in the ProRes 4444 video output. To test the integrity of the image data before encoding to ProRes, I added a snippet in my encoding function that saves a 16-bit PNG before encoding to ProRes and the PNG looks perfect, I can see all detail in every part of the image dynamic range. Here’s a comparison between the 16-bit PNG(on the right) and the ProRes 4444 output. (on the left) As a further test, I re-encoded the ‘test PNG’ to ProRes 4444 using DaVinci Resolve, and the ProRes4444 output video from Resolve doesn’t have any blocky compression artifacts. Looks identical. In short, this is what the utility does: Unpacks the 12-bit raw data into 16-bit values. After unpacking, the raw data is debayered to convert it into a standard color image format (BGR) using OpenCV. Scale the debayered pixel values from their original 12-bit depth to fit into a 16-bit range. Up to this point everything is fine and confirmed by saving 16bit PNGs. The images are encoded to ProRes 4444 using the AVFoundation framework. The pixel buffers are created and managed using dictionary method with ‘kCVPixelFormatType_64RGBALE’. I need help figuring this out, I’m a real novice when it comes to AVfoundation/encoding to ProRes. See relevant parts of my 'encodeToProRes' function: void encodeToProRes(const std::string &outputPath, const std::vector<std::string> &rawPaths, const std::string &proResFlavor) { NSError *error = nil; NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:outputPath.c_str()]]; AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:url fileType:AVFileTypeQuickTimeMovie error:&error]; if (error) { std::cerr << "Error creating AVAssetWriter: " << error.localizedDescription.UTF8String << std::endl; return; } // Load the first image to get the dimensions std::cout << "Debayering the first image to get dimensions..." << std::endl; Mat firstImage; int width = 5320; int height = 3900; if (!debayer_image(rawPaths[0], firstImage, width, height)) { std::cerr << "Error debayering the first image" << std::endl; return; } width = firstImage.cols; height = firstImage.rows; // Save the first frame as a PNG 16-bit image for validation std::string pngFilePath = outputPath + "_frame1.png"; if (!imwrite(pngFilePath, firstImage)) { std::cerr << "Error: Failed to save the first frame as a PNG image" << std::endl; } else { std::cout << "First frame saved as PNG: " << pngFilePath << std::endl; } NSString *codecKey = nil; if (proResFlavor == "4444") { codecKey = AVVideoCodecTypeAppleProRes4444; } else if (proResFlavor == "422HQ") { codecKey = AVVideoCodecTypeAppleProRes422HQ; } else if (proResFlavor == "422") { codecKey = AVVideoCodecTypeAppleProRes422; } else if (proResFlavor == "LT") { codecKey = AVVideoCodecTypeAppleProRes422LT; } else { std::cerr << "Error: Invalid ProRes flavor specified: " << proResFlavor << std::endl; return; } NSDictionary *outputSettings = @{ AVVideoCodecKey: codecKey, AVVideoWidthKey: @(width), AVVideoHeightKey: @(height) }; AVAssetWriterInput *videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:outputSettings]; videoInput.expectsMediaDataInRealTime = YES; NSDictionary *pixelBufferAttributes = @{ (id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_64RGBALE), (id)kCVPixelBufferWidthKey: @(width), (id)kCVPixelBufferHeightKey: @(height) }; AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoInput sourcePixelBufferAttributes:pixelBufferAttributes]; ... [assetWriter startSessionAtSourceTime:kCMTimeZero]; CMTime frameDuration = CMTimeMake(1, 24); // Frame rate of 24 fps int numFrames = static_cast<int>(rawPaths.size()); ... // Encoding thread std::thread encoderThread([&]() { int frameIndex = 0; std::vector<CVPixelBufferRef> pixelBufferBuffer; while (frameIndex < numFrames) { std::unique_lock<std::mutex> lock(queueMutex); queueCondVar.wait(lock, [&]() { return !frameQueue.empty() || debayeringFinished; }); if (!frameQueue.empty()) { auto [index, debayeredImage] = frameQueue.front(); frameQueue.pop(); lock.unlock(); if (index == frameIndex) { cv::Mat rgbaImage; cv::cvtColor(debayeredImage, rgbaImage, cv::COLOR_BGR2RGBA); CVPixelBufferRef pixelBuffer = NULL; CVReturn result = CVPixelBufferPoolCreatePixelBuffer(NULL, adaptor.pixelBufferPool, &pixelBuffer); if (result != kCVReturnSuccess) { std::cerr << "Error: Could not create pixel buffer" << std::endl; dispatch_group_leave(dispatchGroup); return; } CVPixelBufferLockBaseAddress(pixelBuffer, 0); void *pxdata = CVPixelBufferGetBaseAddress(pixelBuffer); for (int row = 0; row < height; ++row) { memcpy(static_cast<uint8_t*>(pxdata) + row * CVPixelBufferGetBytesPerRow(pixelBuffer), rgbaImage.ptr(row), width * 8); } CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); pixelBufferBuffer.push_back(pixelBuffer); ... Thanks very much!
1
0
196
2w
How to identify audio and video AVCaptureDevices that are from the same hardware?
I'm working on a macOS application that captures audio and video. When the user selects a video capture source (most likely an elgato box), I would like the application to automatically select the audio input from the same device. I was achieving this by pairing video and audio sources that had the same name, but this doesn't work when the user plugs in two capture devices of the same make and model. With the command system_profiler SPUSBDataType I can list all the USB devices, and I can see that the two elgato boxes have different serial numbers. If I could find this serial number, then I could figure out which AVCaptureDevices come from the same hardware. Is there a way to get the manufacturer's serial number from the AVCaptureDevice object? Or a way to identify the USB device for an AVCaptureDevice, and from there I could get the serial or some other unique ID?
1
3
210
2w