利用AVFoundation实现Blink拍照和录像的功能
by 伍雪颖
github代码
前几天偶然发现一个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文件.
等有空了,把服务器也写一下,或者谁有兴趣可以把它的服务器实现下.
当然Blink还有一些添加好友,分享等的功能,这些细节还是比较好实现的.