iOS视频——录制视频

两种主要技术:UIImagePickerController、AVFoundation框架。

使用UIImagePickerController

#import "ViewController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

<UIImagePickerControllerDelegate,
UINavigationControllerDelegate>

- (IBAction)videoRecod:(id)sender;

-(void)video:(NSString *)videoPath
didFinishSavingWithError:(NSError *)error
 contextInfo:(NSString *)contextInfo;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
}

- (IBAction)videoRecod:(id)sender
{
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
        imagePickerController.delegate = self;
        imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
        imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
        //录制质量设定
        imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
        //只允许最多录制30秒时间
        imagePickerController.videoMaximumDuration = 30.0f;
        [self presentViewController:imagePickerController animated:YES completion:nil];
    }
    else
    {
        NSLog(@"摄像头不可用。");
    }
}

-(void)video:(NSString *)videoPath
didFinishSavingWithError:(NSError *)error
 contextInfo:(NSString *)contextInfo
{
    NSString *title;
    NSString *message;
    if (!error)
    {
        title = @"视频保存";
        message = @"视频已经保存到设备的相机胶卷中";
    }
    else
    {
        title = @"保存失败";
        message = [error description];
    }
    UIAlertController *alertC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *alertA = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
    [alertC addAction:alertA];
    [self presentViewController:alertC animated:YES completion:nil];
}

#pragma mark - UIImagePickerController代理方法
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info
{
    NSString *tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
    if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath))
    {
        UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), (__bridge void *)(tempFilePath));
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark -UINavigationControllerDelegate方法
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog(@"选择器将要显示");
}

-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog(@"选择器显示结束");
}

@end

使用AVFoundation框架

更加细粒度的控制,可以获得来自设备的输入流,实时采集、捕获和播放视频技术。

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

@interface ViewController ()

<AVCaptureFileOutputRecordingDelegate>

{
    BOOL isRecording;
}

@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) AVCaptureMovieFileOutput *output;

- (IBAction)recordPressed:(id)sender;
-(NSURL *)p_fileURL;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _session = [[AVCaptureSession alloc] init];
    _session.sessionPreset = AVCaptureSessionPresetMedium;
    
    AVCaptureDevice *cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    AVCaptureDeviceInput *camera = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&error];
    
    AVCaptureDevice *micDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    AVCaptureDeviceInput *mic = [AVCaptureDeviceInput deviceInputWithDevice:micDevice error:&error];
    
    if (error || !camera || !mic)
    {
        NSLog(@"Input Error");
    }
    else
    {
        [_session addInput:camera];
        [_session addInput:mic];
    }
    
    _output = [[AVCaptureMovieFileOutput alloc] init];
    if ([_session canAddOutput:_output])
    {
        [_session addOutput:_output];
    }
    
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
    previewLayer.frame = CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height - 70);
    [self.view.layer insertSublayer:previewLayer atIndex:0];
    [_session startRunning];
    
    isRecording = NO;
    _label.text = @"";
}

- (IBAction)recordPressed:(id)sender
{
    if (!isRecording)
    {
        [_button setTitle:@"停止" forState:UIControlStateNormal];
        _label.text = @"录制中……";
        isRecording = YES;
        NSURL *fileURL = [self p_fileURL];
        [_output startRecordingToOutputFileURL:fileURL recordingDelegate:self];
    }
    else
    {
        [_button setTitle:@"录制" forState:UIControlStateNormal];
        _label.text = @"停止";
        [_output stopRecording];
        isRecording = NO;
    }
}

-(NSURL *)p_fileURL
{
    NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"movie.mov"];
    NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
    NSFileManager *manager = [[NSFileManager alloc] init];
    if ([manager fileExistsAtPath:outputPath])
    {
        [manager removeItemAtPath:outputPath error:nil];
    }
    return outputURL;
}

#pragma mark - AVCaptureFileOutputRecordingDelegate协议方法
-(void)captureOutput:(AVCaptureFileOutput *)output
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
     fromConnections:(NSArray<AVCaptureConnection *> *)connections
               error:(NSError *)error
{
    if (error == nil)
    {
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error)
        {
            if (error)
            {
                NSLog(@"写入错误。");
            }
        }];
    }
}

@end

猜你喜欢

转载自blog.csdn.net/run_in_road/article/details/113587826