简体   繁体   English

如何使用AVCaptureSession流式传输实时预览视频,然后拍照,然后返回流式传输

[英]How to use AVCaptureSession to stream live preview video, then take a photo, then return to streaming

I have an application that creates its own live preview prior to taking a still photo. 我有一个应用程序,在拍摄静态照片之前创建自己的实时预览。 The app needs to run some processing on the image data and thus is not able to rely on AVCaptureVideoPreviewLayer. 应用程序需要对图像数据运行一些处理,因此无法依赖AVCaptureVideoPreviewLayer。 Getting the initial stream to work is going quite well, using Apple's example code. 使用Apple的示例代码,使初始流工作进展顺利。 The problem comes when I try to switch to the higher quality image to take the snapshot. 当我尝试切换到更高质量的图像拍摄快照时出现问题。 In response to a button press I attempt to reconfigure the session for taking a full resolution photo. 响应按钮按下,我尝试重新配置会话以拍摄全分辨率照片。 I've tried many variations but here is my latest example (which still does not work): 我尝试了很多变化,但这是我最新的例子(仍然不起作用):

- (void)sessionSetupForPhoto
{
 [session beginConfiguration];
 session.sessionPreset = AVCaptureSessionPresetPhoto;
 AVCaptureStillImageOutput *output = [[[AVCaptureStillImageOutput alloc] init] autorelease];
 for (AVCaptureOutput *output in [session outputs]) {
  [session removeOutput:output];
 }
 if ([session canAddOutput:output]){
  [session addOutput:output];
 } else {
  NSLog(@"Not able to add an AVCaptureStillImageOutput");
 }
 [session commitConfiguration];
}

I am consistently getting an error message just after the commitConfiguration line that looks like this: (that is to say, I am getting an AVCaptureSessionRuntimeErrorNotification sent to my registered observer) 我一直在commitConfiguration行之后收到一条错误消息,如下所示:(也就是说,我收到AVCaptureSessionRuntimeErrorNotification发送给我的注册观察者)

Received an error: NSConcreteNotification 0x19d870 {name = AVCaptureSessionRuntimeErrorNotification; 收到错误:NSConcreteNotification 0x19d870 {name = AVCaptureSessionRuntimeErrorNotification; object = ; object =; userInfo = { AVCaptureSessionErrorKey = "Error Domain=AVFoundationErrorDomain Code=-11800 \\"The operation couldn\\U2019t be completed. userInfo = {AVCaptureSessionErrorKey =“Error Domain = AVFoundationErrorDomain Code = -11800 \\”操作无法完成。 (AVFoundationErrorDomain error -11800.)\\" UserInfo=0x19d810 {}"; (AVFoundationErrorDomain错误-11800。)\\“UserInfo = 0x19d810 {}”;

The documentation in XCode ostensibly provides more information for the error number (-11800), "AVErrorUnknown - Reason for the error is unknown."; XCode中的文档表面上提供了有关错误编号(-11800)的更多信息,“AVErrorUnknown - 错误原因未知。”;

Previously I had also tried calls to stopRunning and startRunning, but no longer do that after watching WWDC Session 409, where it is discouraged. 以前我也尝试过调用stopRunning和startRunning,但是在观看WWDC Session 409之后不再这样做了,不鼓励这样做。 When I was stopping and starting, I was getting a different error message -11819, which corresponds to "AVErrorMediaServicesWereReset - The operation could not be completed because media services became unavailable.", which is much nicer than simply "unknown", but not necessarily any more helpful. 当我停止并开始时,我得到一个不同的错误消息-11819,它对应于“AVErrorMediaServicesWereReset - 操作无法完成,因为媒体服务变得不可用。”,这比简单的“未知”要好得多,但不一定更有帮助。

It successfully adds the AVCaptureStillImageOutput (ie, does NOT emit the log message). 它成功添加了AVCaptureStillImageOutput(即,不发出日志消息)。

I am testing on an iPhone 3g (w/4.1) and iPhone 4. 我正在测试iPhone 3g(w / 4.1)和iPhone 4。

This call is happening in the main thread, which is also where my original AVCaptureSession setup took place. 这个调用发生在主线程中,这也是我原来的AVCaptureSession设置发生的地方。

How can I avoid the error? 如何避免错误? How can I switch to the higher resolution to take the photo? 如何切换到更高的分辨率拍摄照片?

Thank you! 谢谢!

Since you're processing the video data coming out of the AVCaptureSession, I'm assuming you have an AVCaptureVideoDataOutput connected to it prior to calling sessionSetupForPhoto. 由于您正在处理来自AVCaptureSession的视频数据,我假设您在调用sessionSetupForPhoto之前已将AVCaptureVideoDataOutput连接到它

If so, can you elaborate on what you're doing in captureOutput:didOutputSampleBuffer: ? 如果是这样,你能详细说明你在captureOutput中做了什么:didOutputSampleBuffer : ? Without being able to see more, I'm guessing there may be a problem with removing the old outputs and subsequently setting the photo quality preset. 无法看到更多内容,我猜测删除旧输出并随后设置照片质量预设可能存在问题。

Also, the output variable you're using as an iterator when you remove your outputs is hiding the still image output . 此外,删除输出时用作迭代器的输出变量隐藏静止图像输出 Not a problem, but it makes the code a little harder to read. 不是问题,但它使代码更难阅读。

There is no need to switch sessions. 无需切换会话。 Just add AVCaptureStillImageOutput to your session on initialization and call the following when you are about to capture the image and use the CMSampleBufferRef accordingly: 只需在初始化时将AVCaptureStillImageOutput添加到会话中,并在要捕获图像时调用以下内容并相应地使用CMSampleBufferRef

captureStillImageAsynchronouslyFromConnection:videoConnection
   completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) 
{
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM