iOS框架AVFoundation实现相机拍照、录制视频

本文实例为大家分享了使用AVFoundation框架实现相机拍照、录制视频的具体代码,供大家参考,具体内容如下

这里是Demo

首先声明以下对象:

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

@interface CustomeCameraViewController ()<AVCaptureFileOutputRecordingDelegate> 

{
 // AVCaptureSession对象来执行输入设备和输出设备之间的数据传递
 AVCaptureSession *iSession;
 //当前设备
 AVCaptureDevice *iDevice;
 //输入设备
 AVCaptureDeviceInput *iDeviceInput;
 //照片输出流
 AVCaptureStillImageOutput *iStillImageOutput;
 //预览图层
 AVCaptureVideoPreviewLayer *iPreviewLayer; 

} 

初始化各对象:

-(void)viewDidLoad {
 [super viewDidLoad]; 

 //点击屏幕对焦
 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusTap:)];
 [self.view addGestureRecognizer:tap]; 

 iSession = [[AVCaptureSession alloc]init]; 

 NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
 for (AVCaptureDevice *device in deviceArray) { 

  //AVCaptureDevicePositionBack 后置摄像头
  //AVCaptureDevicePositionFront 前置摄像头
  if (device.position == AVCaptureDevicePositionBack) {
   iDevice = device;
  }
 } 

 iSession.sessionPreset = [self getSessionPresetForDevice:iDevice]; 

 iDeviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:iDevice error:nil]; 

 ////输出设置。AVVideoCodecJPEG 输出jpeg格式图片
 iStillImageOutput = [[AVCaptureStillImageOutput alloc]init];
 NSDictionary *outputDic = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil nil];
 [iStillImageOutput setOutputSettings:outputDic]; 

 //更改这个设备设置的时候必须先锁定设备,修改完后再解锁,否则崩溃
 [iDevice lockForConfiguration:nil];
 if ([iDevice isFlashModeSupported:AVCaptureFlashModeOff]) {
  [iDevice setFlashMode:AVCaptureFlashModeOff];
 }
 if ([iDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
  [iDevice setFocusMode:AVCaptureFocusModeAutoFocus];
 }
 if ([iDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeAutoWhiteBalance]) {
  [iDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeAutoWhiteBalance];
 }
 [iDevice unlockForConfiguration]; 

 if ([iSession canAddInput:iDeviceInput]) {
  [iSession addInput:iDeviceInput];
 }
 if ([iSession canAddOutput:iStillImageOutput]) {
  [iSession addOutput:iStillImageOutput];
 }
 if ([iSession canAddOutput:iVideoOutput]) {
  [iSession addOutput:iVideoOutput];
 } 

 //初始化预览图层
 iPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:iSession];
 [iPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
 iPreviewLayer.frame = CGRectMake(0, 60, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-160);
 [self.iCameraView.layer addSublayer:iPreviewLayer]; 

 [iSession startRunning];  

}

点击按钮拍照:

//拍照
-(void)takePictures{
 AVCaptureConnection *connection = [iStillImageOutput connectionWithMediaType:AVMediaTypeVideo];
 if (!connection) {
  NSLog(@"失败");
  return;
 }
 //设置焦距
 [connection setVideoScaleAndCropFactor:1]; 

 [iStillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
  if (imageDataSampleBuffer==NULL) {
   NSLog(@"NUll");
   return ;
  } 

  NSData *data = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
  UIImage *image = [UIImage imageWithData:data]; 

 }];
}

image即为拍照所得图片.

设置session的AVCaptureSessionPreset属性

-(NSString *)getSessionPresetForDevice:(AVCaptureDevice *)device{
 if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset3840x2160]) {
  return AVCaptureSessionPreset3840x2160;
 } else if([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1920x1080]){
  return AVCaptureSessionPreset1920x1080;
 } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]){
  return AVCaptureSessionPreset1280x720;
 } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]){
  return AVCaptureSessionPreset640x480;
 } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset352x288]){
  return AVCaptureSessionPreset352x288;
 } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPresetHigh]){
  return AVCaptureSessionPresetHigh;
 } else if ([device supportsAVCaptureSessionPreset:AVCaptureSessionPresetMedium]){
  return AVCaptureSessionPresetMedium;
 } else{
  return AVCaptureSessionPresetLow;
 }
}

设置闪光灯:

- (IBAction)iFlashBtn:(id)sender { 

 [iDevice lockForConfiguration:nil];
 if (iDevice.flashMode == AVCaptureFlashModeOff) {
  if ([iDevice isFlashModeSupported:AVCaptureFlashModeOn]) {
   [iDevice setFlashMode:AVCaptureFlashModeOn]; 

   [self.iFlashBtn setBackgroundImage:[UIImage imageNamed:@"flashBtn"] forState:UIControlStateNormal];
  }
 } else if (iDevice.flashMode == AVCaptureFlashModeOn){
  if ([iDevice isFlashModeSupported:AVCaptureFlashModeOff]) {
   [iDevice setFlashMode:AVCaptureFlashModeOff]; 

    [self.iFlashBtn setBackgroundImage:[UIImage imageNamed:@"flashOffBtn"] forState:UIControlStateNormal];
  }
 }
 [iDevice unlockForConfiguration]; 

}

切换前置摄像头与后置摄像头:

- (IBAction)iChangeBtn:(id)sender { 

 NSArray *array = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
 AVCaptureDevice *newDevice = nil;
 AVCaptureDeviceInput *newDeviceInput = nil; 

 CATransition *animation = [CATransition animation];
 animation.duration = 0.5f;
 animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
 animation.type = @"oglFlip"; 

 if (iDevice.position == AVCaptureDevicePositionBack) {
  animation.subtype = kCATransitionFromLeft;
  for (AVCaptureDevice *device in array) {
   if (device.position == AVCaptureDevicePositionFront) {
    newDevice = device;
   }
  }
 } else if (iDevice.position == AVCaptureDevicePositionFront){
  animation.subtype = kCATransitionFromRight;
  for (AVCaptureDevice *device in array) {
   if (device.position == AVCaptureDevicePositionBack) {
    newDevice = device;
   }
  }
 } 

 newDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:newDevice error:nil];
 [iPreviewLayer addAnimation:animation forKey:nil];
 if (newDeviceInput!=nil) {
  [iSession beginConfiguration];
  [iSession removeInput:iDeviceInput];
   iSession.sessionPreset = [self getSessionPresetForDevice:newDevice];
  if ([iSession canAddInput:newDeviceInput]) {
   [iSession addInput:newDeviceInput];
   iDeviceInput = newDeviceInput;
   iDevice = newDevice;
  } else {
   [iSession addInput:iDeviceInput];
  }
  [iSession commitConfiguration];
 } 

}

点击屏幕对焦:

//点击屏幕对焦
-(void)focusTap:(UIGestureRecognizer *)tap{
 CGPoint tapPoint = [tap locationInView:self.view]; 

 float Y = tapPoint.y;
 if (Y<60 || Y>([UIScreen mainScreen].bounds.size.height-100)) {
  return;
 } 

 [iDevice lockForConfiguration:nil];
 if ([iDevice isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
  [iDevice setFocusPointOfInterest:CGPointMake(tapPoint.x/self.view.frame.origin.x, tapPoint.y/self.view.frame.origin.y)];
  [iDevice setFocusMode:AVCaptureFocusModeAutoFocus];
 }
 [iDevice unlockForConfiguration]; 

 self.iFocusImgView.center = tapPoint;
 self.iFocusImgView.hidden = NO;
 [UIView animateWithDuration:0.3 animations:^{
  self.iFocusImgView.transform = CGAffineTransformMakeScale(1.25, 1.25);
 }completion:^(BOOL finished) {
  [UIView animateWithDuration:0.5 animations:^{
   self.iFocusImgView.transform = CGAffineTransformIdentity;
  } completion:^(BOOL finished) {
   self.iFocusImgView.hidden = YES;
  }];
 }];
}

关于视频录制可以在Demo中查看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2018-05-08

iOS8调用相机报警告Snapshotting a view的解决方法

因为我这也报了这个警告,所以把解决方法写到这个地方看是否其他人用的到,具体解决方法: 错误代码:Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates. 问题分析:iOS8在调用系统相机拍照时,会有

IOS打开系统相机的闪光灯

IOS有两种的拍照和视频的方式: 1.直接使用UIImagePickerController,这个类提供了一个简单便捷的拍照与选择图片库里图片的功能. 2.另一种是通过AVFoundation.framework框架完全自定义拍照的界面和选择图片库界面.我只做了第一种,就先给大家介绍第一种做法: 一.首先调用接口前,我们需要先判断当前设备是否支持UIImagePickerController,用isSourceTypeAvailable:来判断是否可用 二.查看符合的媒体类型,这个时候我们调用a

iOS自定义相机实现拍照、录制视频

本文实例为大家分享了iOS自定义相机实现拍照.录制视频的具体代码,供大家参考,具体内容如下 使用AVFoundation框架. 这里是Demo 首先声明以下对象: #import "CustomeCameraViewController.h" #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> @interface CustomeCameraViewContr

iOS开发技巧之自定义相机

最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以.就花时间简单研究了一下相机的自定义. 相机属于系统硬件,这就需要我们来手动调用iPhone的相机硬件,分为以下步骤: 1.首先声明以下对象 #import <AVFoundation/AVFoundation.h> //捕获设备,通常是前置摄像头,后置摄像头,麦克风(音频输入) @property (nonatomic, strong) AVCaptureDevice *device; //AVCaptureD

IOS打开照相机与本地相册选择图片实例详解

IOS打开照相机与本地相册选择图片 最近正好项目里面要集成"打开照相机与本地相册选择图片"的功能,今天就在这边给大家写一个演示程序:打开相机拍摄后或者在相册中选择一张照片,然后将它显示在界面上.好了废话不多说,因为比较简单直接上源码. 首先,我们在头文件中添加需要用到的actionSheet控件,显示图片的UIImageView控件,并且加上所需要的协议 #import <UIKit/UIKit.h> @interface ImagePickerViewController

iOS 10自定义相机功能

本文实例为大家分享了iOS 10自定义相机功能的具体代码,供大家参考,具体内容如下 直接上代码 // // TGCameraVC.swift // TGPhotoPicker // // Created by targetcloud on 2017/7/25. // Copyright © 2017年 targetcloud. All rights reserved. // import UIKit import AVFoundation import Photos @available(iOS

iOS开发-自定义相机实例(仿微信)

网上有很多自定义相机的例子,这里只是我临时写的一个小demo,仅供参考: 用到了下面几个库: #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> 在使用的时候需要在Info.plist中把相关权限写进去: Privacy - Microphone Usage Description Privacy - Photo Library Usage Description Privacy

iOS仿微信相机拍照、视频录制功能

网上有很多自定义相机的例子,这里只是我临时写的一个iOS自定义相机(仿微信)拍照.视频录制demo,仅供参考: 用到了下面几个库: #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/AssetsLibrary.h> 在使用的时候需要在Info.plist中把相关权限写进去: Privacy - Microphone Usage Description Privacy - Photo Library Usage

IOS10 相册相机闪退bug解决办法

iOS10系统下调用系统相册.相机功能,遇到闪退的情况,描述如下: This app has crashed because it attempted to access privacy-sensitive data without a usage description.The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the use

iOS开发-调用系统相机和相册获取照片示例

前言:相信大家都知道大部分的app都是有我的模块的,而在我的模块基本都有用户的头像等信息,并且是可以更改头像的.那么今天小编给大家简单介绍一下iOS开发中如何调用系统相机拍照或者相册获取照片.要获取系统相机或者相册,我们需要使用到 UIImagePickerController 这个类.下面我们来看一下如何实现: 首先,需要遵循 UIImagePickerController 代理的两个协议: <UIImagePickerControllerDelegate, UINavigationContr

iOS 10 使用相机相簿闪退的bug修正方法

iOS 10 新规定,在取用相机,相簿,联络资讯,麦克风需要在 Info.plist 加入指定的 key,否则闪退: Info.plist <key>NSPhotoLibraryUsageDescription</key> <string>使用相簿需要您的同意</string> <key>NSCameraUsageDescription</key> <string>使用相机需要您的同意</string> <

直接双击启动tomcat中的startup.bat闪退原因及解决方法

免安装的tomcat双击startup.bat后,启动窗口一闪而过,而且tomcat服务未启动. 原因是:在启动tomcat是,需要读取环境变量和配置信息,缺少了这些信息,就不能登记环境变量,导致了tomcat的闪退. 解决办法: 1.在已解压的tomcat的bin文件夹下找到startup.bat,右击->编辑.在文件头加入下面两行: SET JAVA_HOME=D:\Java\jdk1.6.0_10 (java jdk目录) SET TOMCAT_HOME=E:\tomcat-6.0.35

MySQL数据库输入密码后闪退问题的解决方法

MySQL数据库输入密码后闪退的问题及解决方案分享 1 案例说明 最近一直在用 MySQL 数据库演示基础功能,但是这两天忽然出现了一个问题,那就是:在启动 MySQL 服务端并输入密码后,出现闪退现象. 之后,在网上搜了搜,发现出现这种问题很常见,大多数原因可能是在咱们使用安全软件的时候,无意中关闭了 MySQL 服务.此外,如果 MySQL 服务已经启动了,但还是出现了闪退的现象,那就可能是 MySQL 的配置出现了问题. 2 解决方案 在出现上述问题的时候,咱们首先要查看 MySQL 服务

iOS 10新的通知机制中添加图片的方法详解

1.新建Target 2.实现UNNotificationServiceExtension 我这里用的是swift // // NotificationService.swift // NotificationServiceExtension // // Created by Heyuan Li on 17/2/26. // Copyright © 2017年 fenbi. All rights reserved. // import UserNotifications class Notifi

Web项目打成war包部署Tomcat时运行startup.bat直接闪退部署失败的快速解决方案

即上篇通过将web项目打成war包部署到Tomcat服务器,解决mysql问题后,又出现了新问题,真是一波三折,所以将解决过程分享给大家,希望能帮助到小伙伴们~ 将打好的war包拷贝到Tomcat的webapps目录,然后在Tomcat的bin目录找到startup.bat批处理文件,直接双击执行,结果运行几秒后直接闪退,顿时有种不好的预感,在浏览器访问web项目,结果连localhost:8080都无法访问,web项目未发布成功,一脸懵逼~ 没有日志看不到为啥发布不成功额,想了想,可以稍微修改

iOS App连续闪退时上报crash日志的方法详解

前言 当一个iOS应用程序崩溃时,系统会创建一份crash日志保存在设备上.这份crash日志记录着应用程序崩溃时的信息,通常包含着每个执行线程的栈调用信息(低内存闪退日志例外),对于开发人员定位问题很有帮助. 为保障线上 App 的用户体验,我们一般都会对线上 App 的 crash 率做实时监控,一旦检测到 spike,可以即刻调查原因,但这一切的前提是 crash 日志能够准确上报. crash 日志上报有两个难点: crash handler 安装之前的代码要绝对稳定 如果日志采集器还没

Unity3D实验室之iOS真机闪退的解决方法

问题的产生 这个问题一般发生在项目比较大,OO使用良好,泛型继承用的较多的时候.第一次真机测试时,项目终于进入真机测试阶段,之前都是在Unity编辑环境下开发测试,运行的都很良好,信心满满的打包安装,结果闪退...,各种代码调试,跟踪都没什么线索.这怎么办?问题很可能出在了AOT的设置上. 解决方案 这个通常是因为你的程序编译的时候给 trampoline 分配的空间太小,而你的程序中又大量使用了泛型.泛型方法调用和接口实现导致的.具体的解决方法就是在 Unity3D 的编译选项 Player

react native android6+拍照闪退或重启的解决方案

前言 android 6+权限使用的时候需要动态申请,那么在使用rn的时候要怎么处理拍照权限问题呢?本文提供的是一揽子rn操作相册.拍照的解决方案,请看正文的提高班部分. 解决步骤 1.AndroidManifest.xml设置拍照权限: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="andr