程序员人生 网站导航

利用AVFoundation实现Blink拍照和录像的功能

栏目:综合技术时间:2015-09-09 08:39:24

利用AVFoundation实现Blink拍照和录相的功能

by 伍雪颖

github代码

头几天偶然发现1个app叫Blink,闲来无事,纯当练手,因而就尝试下自己实现它的功能.
页面都挺简单的

1.打开相机

- (void)openCamera:(AVCaptureDevicePosition)cameraPostion {
   
BOOL hasCamera = ([[AVCaptureDevice devices] count] > 0);
   
if (hasCamera) {
       
AVCaptureSession *session = [[AVCaptureSession alloc] init];
        session.
sessionPreset = AVCaptureSessionPresetHigh;
       
       
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
        [captureVideoPreviewLayer
setVideoGravity:AVLayerVideoGravityResizeAspectFill];
        [captureVideoPreviewLayer
setFrame:self.cameraImageView.bounds];
        [
self.cameraImageView.layer addSublayer:captureVideoPreviewLayer];
       
       
AVCaptureDevice *device = [self getCamera:cameraPostion];
       
NSError *error = nil;
       
       
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
        [session
addInput:input];
       
       
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
       
NSDictionary *outputSettings = @{ AVVideoCodecKey : AVVideoCodecJPEG};
        [
stillImageOutput setOutputSettings:outputSettings];
        [session
addOutput:stillImageOutput];
       
       
movieOutput = [[AVCaptureMovieFileOutput alloc] init];
        [session
addOutput:movieOutput];
       
        [session
startRunning];
    }
}

- (AVCaptureDevice *)getCamera:(AVCaptureDevicePosition)cameraPostion {
   
NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
   
for (AVCaptureDevice *device in cameras) {
       
if (device.position == cameraPostion)
           
return device;
    }
   
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}

2.获得静态图片

- (void)captureNow {
   
AVCaptureConnection *videoConnection = nil;
   
for (AVCaptureConnection *connection in stillImageOutput.connections) {
       
for (AVCaptureInputPort *port in [connection inputPorts]) {
           
if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
                videoConnection = connection;
               
break;
            }
        }
       
if (videoConnection) { break; }
    }
   
// 取静态图片
    [
stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection
             
completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
                 
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
                 
NSData *compressedData = [imageData gzippedDataWithCompressionLevel:1.0];
                 
NSData *outputData = [compressedData gunzippedData];
                 
UIImage *imageT = [[UIImage alloc] initWithData:outputData];
                 
_testImageView.image = imageT;
                 
_testImageView.hidden = NO;
                 
NSFileManager *fileManager = [NSFileManager defaultManager];
                 
NSString *filePath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(),@"main.png"];
                  [fileManager
createFileAtPath:filePath contents:imageData attributes:nil];
                 
                 
NSString *zipFile = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(),@"main.zip"];
                 
ZipArchive *za = [[ZipArchive alloc] init];
                  [za
CreateZipFile2:zipFile];
                  [za
addFileToZip:filePath newname:@"main.png"];
              }];
}

3.录相和播放录相

- (IBAction)beginRecord:(id)sender {
    [
movieOutput startRecordingToOutputFileURL:[self fileURLWithName:@"main.mp4"] recordingDelegate:self];
}

- (void)stopRecord {
    [
movieOutput stopRecording];
}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
        didFinishRecordingToOutputFileAtURL:(
NSURL *)outputFileURL
              fromConnections:(
NSArray *)connections
                        error:(
NSError *)error {
   
BOOL recordedSuccessfully = YES;
   
if (error == nil) {
        [
self playVideo:outputFileURL];
    }
   
if ([error code] != noErr) {
       
id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
       
if (value) {
            recordedSuccessfully = [value
boolValue];
           
        }
    }
}

- (void)playVideo:(NSURL *)url {
   
AVPlayer *player = [AVPlayer playerWithURL:url];
   
playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
   
   
playerLayer.frame = CGRectMake(0, 0, 160, 284);
   
playerLayer.position = self.view.center;
    [
self.view.layer addSublayer:playerLayer];
   
   
playerLayer.masksToBounds = YES;
   
playerLayer.cornerRadius = 20;
   
playerLayer.borderWidth = 1;
   
playerLayer.borderColor = [UIColor grayColor].CGColor;
   
    [player
play];
    [[
NSNotificationCenter defaultCenter]
                        
addObserver:self
                        
selector:@selector(removePlayer)
                        
name:AVPlayerItemDidPlayToEndTimeNotification
                        
object:nil];
}

- (void)removePlayer {
    [
playerLayer removeFromSuperlayer];
}

看了下它的网络数据格式方面,Blink主要是打包成zip文件,里面包括json,mp4,png文件.
等有空了,把服务器也写1下,或谁有兴趣可以把它的服务器实现下.

固然Blink还有1些添加好友,分享等的功能,这些细节还是比较好实现的.

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐