AVF 8 - 媒体捕捉

AVF 8 - 媒体捕捉

文章目录


  • 注意使用 NSCameraUsageDescription
  • iOS 的摄像头可能比 Mac 更多功能特性

@interface Capture ()<AVCaptureFileOutputRecordingDelegate>

@property (strong, nonatomic) AVCaptureSession *captureSession;
@property (weak, nonatomic) AVCaptureDeviceInput *activeVideoInput;

// AVCapturePhotoOutput
@property (strong, nonatomic) AVCaptureStillImageOutput *imageOutput;
@property (strong, nonatomic) AVCaptureMovieFileOutput *movieOutput;
@property (strong, nonatomic) NSURL *outputURL;

@property (nonatomic, strong) NSWindow *window;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewViewLayer;


@end

@implementation Capture

- (void)setup{
    
    [self setupSession:nil];
    [self setupPreviewLayer];
    [self startSession];
    
    
    //不能一进入程序就拍照或录像,否则照片可能为黑色,或者录像对象初始化失败
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//          [self captureStillImage];
        [self startRecording];
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopRecording];
    });
    
}

- (BOOL)setupSession:(NSError **)error {

    self.captureSession = [[AVCaptureSession alloc] init];                  // 1
    self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;

    // Set up default camera device
    AVCaptureDevice *videoDevice =                                          // 2
        [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    AVCaptureDeviceInput *videoInput =                                      // 3
        [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:error];
    
    if (videoInput) {
        if ([self.captureSession canAddInput:videoInput]) {                 // 4
            [self.captureSession addInput:videoInput];
            self.activeVideoInput = videoInput;
        }
    } else {
        return NO;
    }

    // Setup default microphone
    AVCaptureDevice *audioDevice =                                          // 5
        [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];

    AVCaptureDeviceInput *audioInput =                                      // 6
        [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:error];
    if (audioInput) {
        if ([self.captureSession canAddInput:audioInput]) {                 // 7
            [self.captureSession addInput:audioInput];
        }
    } else {
        return NO;
    }
 
    // Setup the still image output
    self.imageOutput = [[AVCaptureStillImageOutput alloc] init];
    self.imageOutput.outputSettings = @{AVVideoCodecKey : AVVideoCodecJPEG};

    if ([self.captureSession canAddOutput:self.imageOutput]) {
        [self.captureSession addOutput:self.imageOutput];
    }else{
        NSLog(@"can not add image output");
    }

    // Setup movie file output
    self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];             // 9

    if ([self.captureSession canAddOutput:self.movieOutput]) {
        [self.captureSession addOutput:self.movieOutput];
    }else{
        NSLog(@"can not add movie output");
    }

    return YES;
}

- (void)setupPreviewLayer{
    
    self.previewViewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
    
    self.previewViewLayer.frame = NSMakeRect(10, 10, 300, 300);
    
    [self.previewViewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    
    [self.window.contentView.layer addSublayer:self.previewViewLayer];
}

- (void)startSession {
    
    if (![self.captureSession isRunning]) {                                 // 1
        dispatch_async([self globalQueue], ^{
            [self.captureSession startRunning];
        });
    }
}

- (void)stopSession {
    if ([self.captureSession isRunning]) {                                  // 2
        dispatch_async([self globalQueue], ^{
            [self.captureSession stopRunning];
        });
    }
}

- (dispatch_queue_t)globalQueue {
    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}


#pragma mark - Image Capture Methods

//不能程序一运行,就拍照;否则捕捉到的图像k 可能是黑的。
- (void)captureStillImage {

    AVCaptureConnection *connection =
        [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
 
    id handler = ^(CMSampleBufferRef sampleBuffer, NSError *error) {
        if (sampleBuffer != NULL) {

            NSData *imageData =
                [AVCaptureStillImageOutput
                    jpegStillImageNSDataRepresentation:sampleBuffer];
           
//            NSImage *image = [[NSImage alloc] initWithData:imageData];
            [self writeImageToAssetsLibrary:imageData];                         // 1

        } else {
            NSLog(@"NULL sampleBuffer: %@", [error localizedDescription]);
        }
    };
    // Capture still image
    [self.imageOutput captureStillImageAsynchronouslyFromConnection:connection
                                                  completionHandler:handler];
    
   
}

#pragma mark - 保存图片
- (void)writeImageToAssetsLibrary:(NSData *)imageData {
    NSLog(@"imageData : %d",imageData.length);
    
    NSString *directory = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES).firstObject;
    NSTimeInterval currentTime= [[NSDate date] timeIntervalSince1970];
    NSString *path = [NSString stringWithFormat:@"%@/%f.png",directory,currentTime];
    
    [imageData writeToFile:path atomically:YES];
    
    [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:nil];
 
}


#pragma mark - Video Capture Methods

- (BOOL)isRecording {                                                       // 1
    return self.movieOutput.isRecording;
}

- (void)startRecording {

    if (![self isRecording]) {

        AVCaptureConnection *videoConnection = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];


        AVCaptureDevice *device = [self activeCamera];

        self.outputURL = [self uniqueURL];
        [self.movieOutput startRecordingToOutputFileURL:self.outputURL recordingDelegate:self];
        

    }
}

- (CMTime)recordedDuration {
    return self.movieOutput.recordedDuration;
}


- (NSURL *)uniqueURL {                                                      // 7
    NSString *directory = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES).firstObject;
    NSTimeInterval currentTime= [[NSDate date] timeIntervalSince1970];
    NSString *path = [NSString stringWithFormat:@"%@/%f.mov",directory,currentTime];
    
    return [NSURL fileURLWithPath:path];
}

- (void)stopRecording {                                                     // 9
    if ([self isRecording]) {
        [self.movieOutput stopRecording];
    }
}

#pragma mark - AVCaptureFileOutputRecordingDelegate

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
      fromConnections:(NSArray *)connections
                error:(NSError *)error {
    
    NSLog(@"didFinishRecordingToOutputFileAtURL : %@",outputFileURL);
    
    if (error) {
        NSLog(@"mediaCaptureFailedWithError : %@",error);
//        [self.delegate mediaCaptureFailedWithError:error];
    } else {
        [self writeVideoToAssetsLibrary:[self.outputURL copy]];
    }
    self.outputURL = nil;
}

- (void)writeVideoToAssetsLibrary:(NSURL *)videoURL {
 
                [self generateThumbnailForVideoAtURL:videoURL];
    
    [[NSWorkspace sharedWorkspace] selectFile:videoURL.path
                     inFileViewerRootedAtPath:nil];
    NSLog(@"videoURL : %@",videoURL);
    
}
发布了43 篇原创文章 · 获赞 8 · 访问量 4558

猜你喜欢

转载自blog.csdn.net/weixin_45390999/article/details/104591721