问题 如何更改AVCaptureVideoDataOutput的视频方向



这是问题所在。我正在使用AVCaptureVideoDataOutput从相机获取视频帧并使用AVAssetWriter从它们制作视频。它工作正常,但我得到的视频是颠倒的,因为我的应用程序的设备的默认方向是横向左侧,而不是正确的右侧,如AVCaptureVideoDataOutput中默认的那样。我试图在AVCaptureConnection类中更改方向,但isVideoOrientationSupported始终为false,是否可以以某种方式修复它?

这是一些代码:

 AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput 
            deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] 
            error:nil];
 /*We setupt the output*/
 AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init]; 
 captureOutput.alwaysDiscardsLateVideoFrames = YES; 
 captureOutput.minFrameDuration = CMTimeMake(1.0, 24.0); //Uncomment it to specify a minimum duration for each video frame
 [captureOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

 // Set the video output to store frame in BGRA (It is supposed to be faster)
 NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey; 
 NSNumber* value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA]; 



 NSDictionary* videoSettings = [NSDictionary dictionaryWithObject:value forKey:key]; 
 [captureOutput setVideoSettings:videoSettings]; 


 /*And we create a capture session*/
 self.captureSession = [[AVCaptureSession alloc] init];
 self.captureSession.sessionPreset = AVCaptureSessionPresetLow;
 /*We add input and output*/
 if ([self.captureSession canAddInput:captureInput]) 
 {
  [self.captureSession addInput:captureInput];
 }
 if ([self.captureSession canAddOutput:captureOutput]) 
 {
  [self.captureSession addOutput:captureOutput];
 }

 /*We add the preview layer*/
 self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self.captureSession];

 if ([self.prevLayer isOrientationSupported]) 
 {
  [self.prevLayer setOrientation:AVCaptureVideoOrientationLandscapeLeft];
 }

 self.prevLayer.frame = self.view.bounds; 

 self.prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
 [self.view.layer addSublayer: self.prevLayer];

 AVCaptureConnection *videoConnection = NULL;

 [self.captureSession beginConfiguration];

 for ( AVCaptureConnection *connection in [captureOutput connections] ) 
 {
  for ( AVCaptureInputPort *port in [connection inputPorts] ) 
  {
   if ( [[port mediaType] isEqual:AVMediaTypeVideo] ) 
   {
    videoConnection = connection;

   }
  }
 }
    if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false**
     {
        [videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
     }

 [self.captureSession commitConfiguration];

 [self.captureSession startRunning]; 

Upd:认为在导出视频时,AVAssetExportSession会丢失preferredTransform信息。


8788
2017-09-29 16:02


起源

史蒂夫,你有这个工作吗?我想知道你如何使用AVAssetWriter。我希望能够从iphone流式传输视频。 - nickfox
希望能帮助到你。 pastebin.com/RVEqWnyN - Steve
当您使用以下URL时:“Pastebin”可能已过期或已被删除! - GM.
@Steve:嗨,现在我也有同样的问题。你有没有解决方案?如何使视频定位支持AVCaptureConnection ???? Plz帮助我 - Asta ni enohpi
拜托,检查一下 回答 在斯威夫特。它对我来说很完美。 - vkalit


答案:


我遇到了同样的问题,并从WWDC围绕AVCamDemo。我不知道为什么(还)但是如果你在创建所有输入/输出/连接后立即查询你的videoConnection,那么isVideoOrientationSupported和supportsVideoOrientation都返回NO。

然而, 如果您稍后查询supportsVideoOrientation或isVideoOrientationSupported (例如,在设置GUI之后),它将返回YES。例如,在我调用[[self movieFileOutput] startRecordingToOutputFileURL ...]之前,用户单击记录按钮后立即查询它

试一试,适合我。


10
2018-02-12 17:26



哦哇,这很棘手!但它的确有效。我认为Apple应该解决这个问题。 isVideoOrientationSupported属性应该能够在创建AVCaptureOutput的同一个runloop中设置。稍后在不必要的情况下执行此操作会使代码更复杂。即使背后有原因,至少文件应该谈论这个。在找到这篇文章之前,我必须手动转换我的坐标以读取像素! - Hlung
实际上,您不需要在以后的runloop中执行此操作。您可以在执行addOutput后立即执行此操作:到AVCaptureSession。 - Hlung
这是救命的答案。我真的不明白为什么文档中没有提到这些条件。 - aqs
这对我来说是救命的答案 - Kashif
大家好,我也有同样的问题使用该演示,我做了很多研发工作,但仍有同样的问题,请帮我摆脱这个问题。 - Jignesh Fadadu


从这里: http://developer.apple.com/library/ios/#qa/qa1744/_index.html#//apple_ref/doc/uid/DTS40011134

目前,电影文件的捕获输出   (AVCaptureMovieFileOutput)和静止图像(AVCaptureStillImageOutput)   支持设置方向,但数据输出进行处理   视频帧(AVCaptureVideoDataOutput)没有。


6
2017-11-14 11:21