Концептуально, вы должны выделить основные функциональные области: одну, которая генерирует видеокадры - это AVCaptureSession
и все, что к ней прикреплено, и другую, которая записывает эти кадры в файл - в вашем случае AVAssetWriter
с подключенными входами.
Проблема с вашим кодом: между этими двумя нет связи.Никакие видеокадры / изображения, выходящие из сеанса захвата, не передаются на входы средства записи ресурсов.
Кроме того, метод AVCaptureStillImageOutput
-captureStillImageAsynchronouslyFromConnection:completionHandler:
нигде не вызывается, поэтому сеанс захвата фактически не создает кадров.
Итак, как минимум, реализуйте что-то вроде этого:
-(IBAction)captureStillImageAndAppend:(id)sender
{
[stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageOutput.connections.firstObject completionHandler:
^(CMSampleBufferRef imageDataSampleBuffer, NSError* error)
{
// check error, omitted here
if (CMTIME_IS_INVALID( startTime)) // startTime is an ivar
[assetWriter startSessionAtSourceTime:(startTime = CMSampleBufferGetPresentationTimeStamp( imageDataSampleBuffer))];
[writerInput appendSampleBuffer:imageDataSampleBuffer];
}];
}
Удалите AVAssetWriterInputPixelBufferAdaptor
, он не используется.
Но есть проблемы с AVCaptureStillImageOutput
:
он предназначен только для создания неподвижных изображений, а не видео
он должен быть настроен на создание несжатых выборочных буферов, если вход средства записи ресурсанастроен для сжатия добавленных примеров буферов (stillImageOutput.outputSettings = @{ (NSString*)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)};
)
устарел под iOS
Если вы действительно хотите создать видео, каквместо последовательности неподвижных изображений вместо AVCaptureStillImageOutput
добавьте AVCaptureVideoDataOutput
к сеансу захвата.Для вывода примеров буфера необходимы делегат и очередь последовательной отправки.Делегат должен реализовать что-то вроде этого:
-(void)captureOutput:(AVCaptureOutput*)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection
{
if (CMTIME_IS_INVALID( startTime)) // startTime is an ivar
[assetWriter startSessionAtSourceTime:(startTime = CMSampleBufferGetPresentationTimeStamp( sampleBuffer))];
[writerInput appendSampleBuffer:sampleBuffer];
}
Обратите внимание, что
вы захотите убедиться, что AVCaptureVideoDataOutput
выводит только кадры, когда высобственно запись;добавьте / удалите его из сеанса захвата или включите / отключите его подключение в действии startStopVideoRecording
сбросьте startTime
в kCMTimeInvalid
перед началом другой записи