AVAssetWriter error when AVCaptureSession camera input is changed - ios

I use AVCaptureSession getting live data from camera and AVCaptureVideoDataOutput & AVCaptureAudioDataOutput delegates in order to get live data frame by frame. (-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection). I sent sample buffer frames (CMSampleBufferRef) that are taken from captureOutput:didOutputSampleBuffer:fromConnection: method to the AVAssetWriter's appendSampleBuffer: method in order to save the taken buffers as video file. But AVAssetWriter instance's status becomes to AVAssetWriterStatusFailed when back camera is toggled to front camera and try to appendSampleBuffer: with the sample buffer that is received from front camera.
The exact error message is:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x176573f0 {NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x175e9e50 "The operation couldn’t be completed. (OSStatus error -12710.)", NSLocalizedFailureReason=An unknown error occurred (-12710)}
What can be the problem?
Thanks in advance...

Related

CHHapticEngine not running

After a day of playing with the CHHapticEngine and custom haptic patterns, using AHAP files in particular (including adding sound samples), I have lost the sound and haptics in the deivce / iPhone. After a factory reset of the iPhone, there are still no haptics / sound in the device (no ringer, no vibrations etc.). When trying to start the haptics engine and play any pattern I can see the following output in the Xcode debugger:
2020-04-29 19:44:31.034051+0200 ProjectName[18431:5043001] [hapi] CHHapticEngine.mm:2354:-[CHHapticEngine doStartWithCompletionHandler:]_block_invoke: ERROR: Player start failed: The operation couldn’t be completed. (com.apple.CoreHaptics error 1852797029.)
2020-04-29 19:44:31.034398+0200 ProjectName[18431:5042880] [Feedback] failed to start core haptics engine for <_UIFeedbackCoreHapticsEngine: 0x28268f170>: Error Domain=com.apple.CoreHaptics Code=1852797029 "(null)"
2020-04-29 19:44:34.076491+0200 ProjectName[18431:5043124] [hapi] CHHapticEngine.mm:2354:-[CHHapticEngine doStartWithCompletionHandler:]_block_invoke: ERROR: Player start failed: The operation couldn’t be completed. (com.apple.CoreHaptics error 1852797029.)
2020-04-29 19:44:34.076703+0200 ProjectName[18431:5043124] [hapi] HapticUtils.h:56:_Haptic_Check: -[CHHapticEngine checkEngineState:]: self.running error -4805
2020-04-29 19:44:34.077641+0200 ProjectName[18431:5043124] error = Error Domain=com.apple.CoreHaptics Code=-4805 "(null)" UserInfo={Error =self.running}
The question is, is it probable to damage the hardware from code?

AVCapturePhotoCaptureDelegate Error When Capturing Image

I seem to get this error message randomly after a few cycles of capture:
Error finishing photo: Error Domain=AVFoundationErrorDomain
Code=-11800 "The operation could not be completed"
UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16802),
NSLocalizedDescription=The operation could not be completed,
NSUnderlyingError=0x281f20f30 {Error Domain=NSOSStatusErrorDomain
Code=-16802 "(null)"}}
Error occurs in:
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {}
Notes:
This Error never comes up on the first capture.
The image format is also a processed format: HEIF
iOS 13
Had the same issue, the culprit was stabilization. I was setting
settings.isAutoStillImageStabilizationEnabled = true
while capturing the image. Stabilization is a heavy process which on main thread which hinders the buffer allocation. Moved it to where camera was getting initialized, resolved the issue for me.

How do I stop AudioKit Inputs and Outputs efficiently and definitively?

I've been using Audiokit.stop() to reasonable effect, and some minor issues that I'd like to resolve now. With the recent update to Audiokit 4.2, I'm now getting a (very useful) error message from the following code:
do {
try AudioKit.stop()
} catch {
AKLog("AudioKit did not stop!")
}
My error code is this:
2018-04-24 16:14:48.099606+0100 MyProject[517:62626] [avas] AVAudioSession.mm:1142:
-[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has
running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
AudioKit.swift:stop():299:couldn't stop session
Error Domain=NSOSStatusErrorDomain Code=560030580 "(null)"
GameScene.swift:update:755:AudioKit did not stop!
So my question is - how do I properly stop or pause all inputs and outputs (I/O) as suggested by the error message?

AVAssetWriter::append() returns false with no extra info (How to do segmenting of captured input to video-chunks with AVFoundation?)

I am building a feature where I record video and audio using AVFoundation. I will record for hours, but I want to upload chunks to our backend so that we can build a live HLS-playlist (after som processing of the segments).
First of all, is there a sample somewhere doing this? I haven't found any reference implementations so to say...
Here is my take on it:
It's pretty straight-forward to setup a AVCaptureSession following the docs and examples on the web.
I implement AVCaptureVideoDataOutputSampleBufferDelegate and AVCaptureAudioDataOutputSampleBufferDelegate to get access to the sample buffers
I have two AVAssetWriters and switch between, one with mediaType == AVMediaTypeVideo and one with mediaType == AVMediaTypeAudio.
Using CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer) I switch between the writers after typically 5 seconds.
Problems:
Sometimes, the when calling AVAssetWriter::append(), it just fails
and returns false
According to the documentation, one shall check AVAssetWriter.status.
In this situation it is set to AVAssetWriterStatusFailed and more information should be available in AVAssetWriter.error
AVAssetWriter.error is set to
Optional(Error Domain=AVFoundationErrorDomain Code=-11800 \"The operation could not be completed\" UserInfo={NSUnderlyingError=0x14e73dc10 {Error Domain=NSOSStatusErrorDomain Code=-16364 \"(null)\"},NSLocalizedFailureReason=An unknown error occurred (-16364), NSLocalizedDescription=The operation could not be completed})
AVFoundationErrorDomain.code 11800 means AVErrorUnknown
Anyone that has had the same problems or knows how to find more info?
Finally, when I switch between writers, there is a period from when I call AVAssetWriter.startWriting() (I do this when I create my idle writer, before it its time to switch to a new segment) to when I have called AVAssetWriter.startSession(atSourceTime: startTime). During this time I need to hold on to sampleBuffers (typically audio). I just make a copy
var copiedBuffer: CMSampleBuffer?
CMSampleBufferCreateCopy(nil, sampleBuffer, &copiedBuffer)
guard copiedBuffer != nil else {
throw VideoWriterError.failedToCopyBuffer
}
pendingSampleBuffers.append((isVideo, copiedBuffer))
After AVAssetWriter.StartSession(), I write them to the new writer:
while !pendingSampleBuffers.isEmpty {
let (isVideo, sampleBufferOpt) = pendingSampleBuffers.removeFirst()
guard let sampleBuffer = sampleBufferOpt else {
throw VideoWriterError.failedToCopyBuffer
}
try capturedFrame(sampleBuffer: sampleBuffer, isVideo: isVideo)
}
Seems to work, but there is a lot of posts about copying is shallow. I wonder if that can be related to my problems? Sample buffers exist in some kind of pool?
If false is returned, clients can check the value of the AVAssetWriter
status property to determine whether the writing operation completed,
failed, or was cancelled. If the status is failed, The AVAssetWriter
error property will contain an instance of NSErrorß that describes the
failure.
From append(_:).
I hope this helps. Please do comment for improvements.

AVCaptureDevice flashMode not working

In an app using AVCaptureSession and AVCaptureDevice, I am taking pictures and it goes as expected.
I decided to implement the use of the flash and there troubles are coming.
Here is the code I added, after searching on the net on how to use the flash in an iOS app:
if captureDevice.hasFlash && captureDevice.isFlashModeSupported(.On) {
do {try captureDevice.lockForConfiguration()
} catch let error as NSError {
print("captureDevice.lockForConfiguration FAILED")
print(error.code)
}
captureDevice.flashMode = .On
captureDevice.unlockForConfiguration()
captureSession.commitConfiguration()
}
It compiles OK but when I try to take a photo, the app crashes with the following error:
Error on taking a picture:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation couldn’t be completed." UserInfo={NSUnderlyingError=0x14e176f40 {Error Domain=NSOSStatusErrorDomain Code=-16800 "(null)"}, NSLocalizedFailureReason=Undefined error(-16800), NSLocalizedDescription=The operation couldn’t be completed.}
Since I have never used the flash before, it may well be a newbie error. But I haven’t, at this point, been able to figure out what was wrong.
If anyone has experience using the flash in an app, please let me know what may be the issue.

Resources