Одновременный AVCaptureVideoDataOutput и AVCaptureMovieFileOutput
Мне нужно уметь AVCaptureVideoDataOutput
а также AVCaptureMovieFileOutput
работая одновременно. Приведенный ниже код работает, однако запись видео - нет. didFinishRecordingToOutputFileAtURL
делегат вызывается сразу после startRecordingToOutputFileURL
называется. Теперь, если я удалю AVCaptureVideoDataOutput
от AVCaptureSession
просто закомментировав строку:
[captureSession addOutput:captureDataOutput];
Запись видео работает, но тогда SampleBufferDelegate не вызывается (что мне нужно).
Как я могу иметь AVCaptureVideoDataOutput
а также AVCaptureMovieFileOutput
работает одновременно.
- (void)initCapture {
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:NULL];
captureDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[captureDataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
m_captureFileOutput = [[AVCaptureMovieFileOutput alloc] init];
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key];
[captureDataOutput setVideoSettings:videoSettings];
captureSession = [[AVCaptureSession alloc] init];
[captureSession addInput:captureInput];
[captureSession addOutput:m_captureFileOutput];
[captureSession addOutput:captureDataOutput];
[captureSession beginConfiguration];
[captureSession setSessionPreset:AVCaptureSessionPresetLow];
[captureSession commitConfiguration];
[self performSelector:@selector(startRecording) withObject:nil afterDelay:10.0];
[self performSelector:@selector(stopRecording) withObject:nil afterDelay:15.0];
[captureSession startRunning];
}
- (void) startRecording
{
[m_captureFileOutput startRecordingToOutputFileURL:[self tempFileURL] recordingDelegate:self];
}
- (void) stopRecording
{
if([m_captureFileOutput isRecording])
[m_captureFileOutput stopRecording];
}
- (NSURL *) tempFileURL
{
NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"camera.mov"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:outputPath]) {
[[NSFileManager defaultManager] removeItemAtPath:outputPath error:nil];
[outputPath release];
return [outputURL autorelease];
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
{
NSLog(@"start record video");
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"end record");
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
// do stuff with sampleBuffer
}
Я должен добавить, что я получаю ошибку:
Error Domain=NSOSStatusErrorDomain Code=-12780 "The operation couldn’t be completed. (OSStatus error -12780.)" UserInfo=0x23fcd0 {AVErrorRecordingSuccessfullyFinishedKey=false}
от
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
ура
4 ответа
Я связался с инженером при поддержке Apple, и он сказал мне, что одновременно AVCaptureVideoDataOutput
+ AVCaptureMovieFileOutput
использование не поддерживается. Я не знаю, поддержат ли они это в будущем, но он использовал слово "не поддерживается в настоящее время".
Я призываю вас заполнить отчет об ошибке / запрос функции, как и я (bugreport.apple.com), так как они измеряют, насколько сильно люди хотят чего-то, и мы, возможно, увидим это в ближайшем будущем.
Тем не менее, 9 лет спустя Apple, похоже, не хочет, чтобы это работало вместе.
Но с AVAssetWriter легко работать.
Вы не можете использовать AVCaptureVideoDataOutput и AVCaptureMovieFileOutput одновременно. Но вы можете использовать AVCaptureVideoDataOutput и анализировать или изменять данные, а затем использовать AVAsseWriter для записи кадров в файл.
Источник: https://developer.apple.com/forums/thread/98113
Как сохранить видео с выводом с помощью AVAssetWriter:
Сохраните AVCaptureVideoDataOutput в файл фильма с помощью AVAssetWriter в Swift
Хотя вы не можете использовать AVCaptureVideoDataOutput
, вы можете использовать AVCaptureVideoPreviewLayer
одновременно с AVCaptureMovieFileOutput
, Смотрите пример "AVCam" на сайте Apple.
В Xamarin.iOS код выглядит так:
var session = new AVCaptureSession();
var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
var mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio);
if(camera == null || mic == null){
throw new Exception("Can't find devices");
}
if(session.CanAddInput(camera)){
session.AddInput(camera);
}
if(session.CanAddInput(mic)){
session.AddInput(mic);
}
var layer = new AVCaptureVideoPreviewLayer(session);
layer.LayerVideoGravity = AVLayerVideoGravity.ResizeAspectFill;
layer.VideoGravity = AVCaptureVideoPreviewLayer.GravityResizeAspectFill;
cameraView = new UIView();
cameraView.Layer.AddSublayer(layer);
var filePath = System.IO.Path.Combine( Path.GetTempPath(), "temporary.mov");
var fileUrl = NSUrl.FromFilename( filePath );
var movieFileOutput = new AVCaptureMovieFileOutput();
var recordingDelegate = new MyRecordingDelegate();
session.AddOutput(movieFileOutput);
movieFileOutput.StartRecordingToOutputFile( fileUrl, recordingDelegate);
XCode 14.1 уже поддерживает это.
- XCode 13.4: не работает
- XCode 14.1: работает