AVFoundation自定义录制视频
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
@interface ViewController ()<AVCaptureFileOutputRecordingDelegate>
@property(nonatomic,strong)AVCaptureSession *session;
@property(nonatomic,strong)AVCaptureDevice *videoDevice;
@property(nonatomic,strong)AVCaptureDevice *audioDevice;
@property(nonatomic,strong)AVCaptureDeviceInput *videoInput;
@property(nonatomic,strong)AVCaptureDeviceInput *audioInput;
@property(nonatomic,strong)AVCaptureMovieFileOutput *movieFileOutput;
@property(nonatomic,strong)AVCaptureVideoPreviewLayer *videoLayer;
@property(nonatomic,assign)UIBackgroundTaskIdentifier backgroundTaskIdentifier;
@property (weak, nonatomic) IBOutlet UIButton *RecordButton;
@end
@implementation ViewController
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self initWithSession];
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self.session startRunning];
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.session stopRunning];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor orangeColor];
}
#pragma mark -初始化
- (void)initWithSession{
_session = [[AVCaptureSession alloc]init];
if ([_session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
[_session setSessionPreset:AVCaptureSessionPreset1280x720];
}
NSArray *deviceArray = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in deviceArray) {
if (device.position == AVCaptureDevicePositionBack) {
_videoDevice = device;
}
}
_audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]firstObject];
NSError *error = nil;
_videoInput = [[AVCaptureDeviceInput alloc]initWithDevice:_videoDevice error:&error];
_audioInput = [[AVCaptureDeviceInput alloc]initWithDevice:_audioDevice error:&error];
if ([_session canAddInput:_videoInput]) {
[_session addInput:_videoInput];
}
if ([_session canAddInput:_audioInput]) {
[_session addInput:_audioInput];
}
_movieFileOutput = [[AVCaptureMovieFileOutput alloc]init];
if ([_session canAddOutput:_movieFileOutput]) {
[_session addOutput:_movieFileOutput];
}
AVCaptureConnection *connection = [_movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
//此处是为了设置视频防抖动在iOS8以后才有,需要加系统判断
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0){
if ([connection isVideoStabilizationSupported]) {
connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeCinematic;//在iOS8以后才有效,要加判断
}
}
_videoLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_videoLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 500);
self.view.layer.masksToBounds = YES;
_videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:_videoLayer];
_RecordButton.selected = NO;
}
#pragma mark --当 拍摄 按钮点击
- (IBAction)takePhoto:(id)sender {
_RecordButton.selected = !_RecordButton.selected; //改变按钮状态切换上面文字
AVCaptureConnection *captureConnection = [self.movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
if (![self.movieFileOutput isRecording]) {
//如果支持多任务则开始多任务
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
self.backgroundTaskIdentifier = [[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:nil];
}
//预览层和视频方向保持一致
captureConnection.videoOrientation = [self.videoLayer connection].videoOrientation;
//建立录制缓存文件
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingString:@"mMovie.mov"];
NSURL *fileUrl = [NSURL fileURLWithPath:outputFilePath];
//此句是为了开始录制,并设置代理
[self.movieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
}
else
{
[self.movieFileOutput stopRecording];
}
}
#pragma mark 视频输出代理
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
{
NSLog(@"开始录制");
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"视频录制完成");
UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier = self.backgroundTaskIdentifier;
self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc]init];
[assetLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"保存视频到相薄发生错误");
}
if(lastBackgroundTaskIdentifier != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication]endBackgroundTask:lastBackgroundTaskIdentifier];
}
NSLog(@"成功保存视频到相薄");
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingString:@"mMovie.mov"];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath]) {
[[NSFileManager defaultManager]removeItemAtPath:outputFilePath error:nil];
}
}];
}
AVFoundation自定义录制视频的更多相关文章
- Android自定义view之仿微信录制视频按钮
本文章只写了个类似微信的录制视频的按钮,效果图如下: 一.主要的功能: 1.长按显示进度条,单击事件,录制完成回调 2.最大时间和最小时间控制 3.进度条宽度,颜色设置 二.实 ...
- iOS 三种录制视频方式
随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...
- 根据分析查看相关知识点分析iOS 三种录制视频方式
这篇文章讨论了关于如何配置视频捕获管线 (pipeline) 和最大限度地利用硬件性能的一些不同选择. 这里有个使用了不同管线的样例 app,可以在 GitHub 查看. 第一种:UIImagePic ...
- iOS录制视频
随着每一代 iPhone 处理能力和相机硬件配置的提高,使用它来捕获视频也变得更加有意思.它们小巧,轻便,低调,而且与专业摄像机之间的差距已经变得非常小,小到在某些情况下,iPhone 可以真正替代它 ...
- iOS AVCaptureVideoDataOutputSampleBufferDelegate 录制视频
iOS AVCaptureVideoDataOutputSampleBufferDelegate 录制视频 应用场景: 使用AVFoundation提供的API, 我们可以从 AVCaptureVid ...
- 3D图片采集与展示(SurfaceView 自适应 Camera, 录制视频, 抽取帧)
最近在做一个3D图片采集与展示. 主要功能为:自定义Camera(google 已经摈弃了Camera, 推荐使用Camera2,后续篇幅,我将会用Camera2取代Camera),围绕一个物体360 ...
- iOS 录制视频MOV格式转MP4
使用UIImagePickerController系统控制器录制视频时,默认生成的格式是MOV,如果要转成MP4格式的,我们需要使用AVAssetExportSession; 支持转换的视频质量:低, ...
- bandicam如何录制视频
我们一般都很熟悉这类软件:屏幕录制专家和kk录制等,这些都是国内比较优秀的作品.不过exe的封装格式以及录制的清晰度让人很纠结.所以这里要为大家分享的是一款韩国人写录制软件Bandicam.Bandi ...
- Android手机录制视频 实时传输(转载)
最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...
随机推荐
- Java线程:同步
一 同步的概念 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. MyRunnab ...
- sql server停止和重启命令
http://www.ynpxrz.com/n822732c2024.aspx 我们知道:sql server重启分分两步走 1.停止 net stop mssqlserver 2.重启 net st ...
- pureMVC简单示例及其原理讲解五(Facade)
本节将讲述Facade,Proxy.Mediator.Command的统一管家.自定义Facade必须继承Facade,在本示例中自定义Facade名称为ApplicationFacade,这个名称也 ...
- 在Flex中定义移动设备应用程序和启动屏幕
创建移动设备应用程序容器 移动设备应用程序中的第一个标签通常是以下标签之一: <s:ViewNavigatorApplication> 标签用于定义只有一个部分的移动设备应用程序. < ...
- localStorage的黑科技-js和css缓存机制
一.发现黑科技的起因 今天在微信公众号看到一篇技术博文,想用印象笔记收藏,所以发送了文章链接到pc上.然后习惯性地打开控制台,看看源码,想了解下最近微信用了什么新技术. 呵呵,以下勾起了我侦探的欲 ...
- Linux笔记(十一) - 文件系统管理
(1)文件系统查看命令:df [选项] [挂载点]-a 显示所有文件系统信息,包括特殊文件系统,如/proc /sysfs-h 使用习惯单位显示容量,如KB,MB或GB-T 显示文件系统类型-m 以M ...
- CodeForces 721A
A. One-dimensional Japanese Crossword time limit per test:1 second memory limit per test:256 megabyt ...
- CODEFORCES 125E MST Company 巧用Kruskal算法
题意:给定一个带权边无向图,求最小生成树,且满足第一个节点的度为固定的k 无解则输出-1 数据规模: 节点数n和限制k<=5000 边数m<=10^5 时限8sec 思路: 首先时限比较宽 ...
- (四)Hololens Unity 开发之 凝视系统
学习源于官方文档 Gaze in Unity 笔记一部分是直接翻译官方文档,部分各人理解不一致的和一些比较浅显的保留英文原文 HoloLens 有三大输入系统,凝视点.手势和声音 ~ 本文主要记录凝视 ...
- iOS实现白板、画板功能,有趣的涂鸦工具,已封装,简单快捷使用
一.效果图: 二.选择颜色: 分[固定颜色模式]和[自由取模式]. 三.操作栏功能: 1.撤销:撤销上一步操作,可一直往上进行,直到全部清空. 2.清空:直接清除所有绘画. 3.橡皮擦:去除不要的绘 ...