2

我是 iOS 和多媒体开发的新手,我正在尝试从 iPhone 的相机捕捉视频并将其显示在屏幕上,而不将其保存在内存中。

到目前为止,我在网上的示例代码的帮助下编写了以下代码:

头文件:

//  ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@class AVCamCaptureManager, AVCamPreviewView, AVCaptureVideoPreviewLayer;
@interface ViewController : UIViewController <UIImagePickerControllerDelegate>

@property (weak, nonatomic) IBOutlet UIView *previewView;

- (IBAction)StartCapture:(id)sender;
- (void)setCaptureSession;
@end

实施文件

//  ViewController.m

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureMovieFileOutput *captureOutput;
@property (nonatomic, weak) AVCaptureDeviceInput *activeVideoInput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;

@end

@implementation ViewController 

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning 
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)StartCapture:(id)sender
{
if ([sender isSelected])
{
    [sender setSelected:NO];
    [self.captureOutput stopRecording];

}
else
{
[sender setSelected:YES];

if (!self.captureOutput)
    {
    self.captureOutput = [[AVCaptureMovieFileOutput alloc] init];
    [self.captureSession addOutput:self.captureOutput];
}
    [self.captureSession startRunning];
}
}

- (void)setCaptureSession
{
self.captureSession = [[AVCaptureSession alloc] init];
NSError *error;

// Set up hardware devices
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (videoDevice)
{
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (input)
    {
        [self.captureSession addInput:input];
        self.activeVideoInput = input;
    }
}
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
if (audioDevice) {
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
    if (audioInput) {
        [self.captureSession addInput:audioInput];
    }
}

// Start running session so preview is available
[self.captureSession startRunning];

// Set up preview layer
dispatch_async(dispatch_get_main_queue(), ^{
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
    self.previewLayer.frame = self.previewView.bounds;
    self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

    //[[self.previewLayer connection] setVideoOrientation:[self currentVideoOrientation]];
    [self.previewView.layer addSublayer:self.previewLayer];
});
}

// Re-enable capture session if not running currently 
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (![self.captureSession isRunning])
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self.captureSession startRunning];
    });
}
}

// Stop running capture session when this view disappears
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self.captureSession isRunning])
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self.captureSession stopRunning];
    });
}
}
@end

请告诉我应该在 IBAction 方法中写什么(按下捕获视频按钮时调用该方法)以及如何使用 AVCaptureVideoPreviewLayer 使正在捕获的视频显示在屏幕上。

谢谢。

4

2 回答 2

3

我找到了我所缺少的。我这样做真的很愚蠢。我根本没有调用该函数setCapture。因此,屏幕上什么都看不到。

我刚刚调用setCapture了 viewDidLoad 函数并解决了问题。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self setCaptureSession];
}

当手机的方向发生变化时,视频仍然存在问题,我必须进行处理,但现在相机捕获的任何内容都可以在屏幕上看到。

于 2013-08-28T07:15:32.267 回答
0

你想要一个 AVCapturePreviewLayer。

https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html#//apple_ref/doc/uid/TP40010188-CH5-SW22

至于在您的 IBAction 方法中写什么,这将取决于您希望您的应用程序如何运行。如果您希望它在捕获会话和预览运行时加载,您实际上不需要按钮。如果您通过按钮开始捕获会话,只需将 PreviewLayer 代码放在相同的方法中(在您启动捕获会话之后)。

于 2013-08-27T18:31:27.100 回答