前言
最近刚做完一个直播类的项目,在视频这块也有一定研究,下面总结下。
过程
首先视频项目一般要求定制化,用UIImagePickerController不符合需求,所以基本上都是用AVFoundation自定义相机,在网上一搜,还是查到比较多参考博文的,其中简书上的这篇iOS-AVFoundation自定义相机详解比较详细(内含Demo),十分值得参考。
另外苹果官方也提供了一个Demo苹果官方Demo-RosyWriter,后来我对比过两个Demo发现,其实简书那篇的Demo也是参考苹果官方的再深入研究,所以在开发过程中以这两个Demo参考基本够用了。
AVFoundation 中视频相关类:
会话
AVCaptureSession
输入
AVCaptureDeviceInput
输出
AVCaptureConnection
AVCaptureConnection
AVCaptureVideoDataOutput
AVCaptureStillImageOutput
AVCaptureMovieFileOutput
文件写入
AVAssetWriter
AVAssetWriterInput
自定义AVFoundation主要为以下5个步骤:
1.创建session(捕捉会话)
2.创建device input(捕捉设备输入)
3.预览view
4.创建capture output(捕捉的输出)
5.拍照、录视频(元数据转成图片或文件)
详细代码就不说了,下面主要说下我做的过程中遇到的一下问题:
1.实时视频流AVCaptureVideoDataOutput和系统视频录制功能AVCaptureMovieFileOutput冲突,不能同时使用。AVCaptureMovieFileOutput是把音频和视频合成并输出一个完整的音视频文件,代码比较简单,但定制化功能少;而AVCaptureVideoDataOutput需要配合AVCaptureAudioDataOutput使用,分别输出音频和视频两条轨道的数据,并用AVAssetWriter写入,代码比较复杂,但定制功能多,推荐使用。
2.关于码率
以上苹果和简书上的demo都是通过分辨率计算码率,代码如下:
//计算像素
int numPixels = dimensions.width * dimensions.height;
int bitsPerSecond;
NSLog( @"No video settings provided, using default settings" );
// Assume that lower-than-SD resolutions are intended for streaming, and use a lower bitrate
if ( numPixels < ( 640 * 480 ) ) {
bitsPerPixel = 4.05; // This bitrate approximately matches the quality produced by AVCaptureSessionPresetMedium or Low.
}
else {
bitsPerPixel = 10.1; // This bitrate approximately matches the quality produced by AVCaptureSessionPresetHigh.
}
//码率
bitsPerSecond = numPixels * bitsPerPixel;
NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey : @(bitsPerSecond),
AVVideoExpectedSourceFrameRateKey : @(30),
AVVideoMaxKeyFrameIntervalKey : @(30) };
如想自定义码率可在以上代码处设置,另外奉上开发过程中找到的一篇关于码率的文章视频质量,分辨率以及码率之间的关系。
另外,关于视频的压缩,我还特意和微信的对比过,在网上搜到这篇文章Compress in iOS,我是参照以上这篇文章,把分辨率设为960*540,再调整码率,使视频文件大小与微信相仿。
3.关于切换摄像头
用上面说到的Demo,切换摄像头时,你会发现屏幕会黑一下,体验效果很不好,改良如下:
//切换摄像头之前,先停止session
[_captureSession stopRunning];
//给摄像头的切换添加翻转动画
CATransition *animation = [CATransition animation];
animation.duration = .5f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = @"oglFlip";
animation.subtype = kCATransitionFromLeft;//动画翻转方向
[self.previewLayer addAnimation:animation forKey:nil];
//接下来开始切换摄像头
......
由于我也是在别人的Demo基础上改的代码,所以我自己就不贴上代码,稍微研究下简书和苹果上的Demo,再结合自己的需求,相信很快就能做出来了。
结束
学习之路,与君共勉。