手把手教你实现小视频iOS代码实现
这篇文章主要手把手教你实现小视频,iOS代码实现小视频功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
短视频分享网站源码前段时间项目要求需要在聊天模块中加入类似的小视频功能,这边博客主要是为了总结遇到的问题和解决方法,希望能够对有同样需求的朋友有所帮助。
这里先罗列遇到的主要问题:
1.视频剪裁 的小视频只是取了摄像头获取的一部分画面
2.滚动预览的卡顿问题 AVPlayer播放视频在滚动中会出现很卡的问题
接下来让我们一步步来实现。
Part 1 实现视频录制
1.录制类WKMovieRecorder实现
创建一个录制类WKMovieRecorder,负责视频录制。
@interface WKMovieRecorder : NSObject + (WKMovieRecorder*) sharedRecorder; - (instancetype)initWithMaxDuration:(NSTimeInterval)duration; @end
定义回调block
/** * 录制结束 * * @param info 回调信息 * @param isCancle YES:取消 NO:正常结束 */typedef void(^FinishRecordingBlock)(NSDictionary *info, WKRecorderFinishedReason finishReason);/** * 焦点改变 */typedef void(^FocusAreaDidChanged)();/** * 权限验证 * * @param success 是否成功 */typedef void(^AuthorizationResult)(BOOL success); @interface WKMovieRecorder : NSObject//回调@property (nonatomic, copy) FinishRecordingBlock finishBlock;//录制结束回调@property (nonatomic, copy) FocusAreaDidChanged focusAreaDidChangedBlock;@property (nonatomic, copy) AuthorizationResult authorizationResultBlock;@end
定义一个cropSize用于视频裁剪
@property (nonatomic, assign) CGSize cropSize;
接下来就是capture的实现了,这里代码有点长,懒得看的可以直接看后面的视频剪裁部分
录制配置:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
@interface WKMovieRecorder ()<AVCaptureVideoDataOutputSampleBufferDelegate,AVCaptureAudioDataOutputSampleBufferDelegate,WKMovieWriterDelegate> { AVCaptureSession* _session; AVCaptureVideoPreviewLayer* _preview; WKMovieWriter* _writer; //暂停录制 BOOL _isCapturing; BOOL _isPaused; BOOL _discont; int _currentFile; CMTime _timeOffset; CMTime _lastVideo; CMTime _lastAudio; NSTimeInterval _maxDuration;} // Session management.@property (nonatomic, strong) dispatch_queue_t sessionQueue;@property (nonatomic, strong) dispatch_queue_t videoDataOutputQueue;@property (nonatomic, strong) AVCaptureSessi
on *session;@property (nonatomic, strong) AVCaptureDevice *captureDevice;@property (nonatomic, strong) AVCaptureDeviceInput *videoDeviceInput;@property (nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput;@property (nonatomic, strong) AVCaptureConnection *videoConnection;@property (nonatomic, strong) AVCaptureConnection *audioConnection;@property (nonatomic, strong) NSDictionary *videoCompressionSettings;@property (nonatomic, strong) NSDictionary *audioCompressionSettings;@property (nonatomic, strong) AVAssetWriterInputPixelBufferAdaptor *adaptor;@property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput; //Utilities@property (nonatomic, strong) NSMutableArray *frames;//存储录制帧@property (nonatomic, assign) CaptureAVSetupResult result;@property (atomic, readwrite) BOOL isCapturing;@property (atomic, readwrite) BOOL isPaused;@property (nonatomic, strong) NSTimer *durationTimer; @property (nonatomic, assign) WKRecorderFinishedReason finishReason; @end
实例化方法:
+ (WKMovieRecorder *)sharedRecorder{ static WKMovieRecorder *recorder; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ recorder = [[WKMovieRecorder alloc] initWithMaxDuration:CGFLOAT_MAX]; }); return recorder;} - (instancetype)initWithMaxDuration:(NSTimeInterval)duration{ if(self = [self init]){ _maxDuration = duration; _duration = 0.f; } return self;} - (instancetype)init{ self = [super init]; if (self) { _maxDuration = CGFLOAT_MAX; _duration = 0.f; _sessionQueue = dispatch_queue_create("vieRecorder.queue", DISPATCH_QUEUE_SERIAL ); _videoDataOutputQueue = dispatch_queue_create( "wukong.www.hunanwangmovieRecorder.video", DISPATCH_QUEUE_SERIAL ); dispatch_set_target_queue( _videoDataOutputQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); } return self;}
2.初始化设置
初始化设置分别为session创建、权限检查以及session配置
1).session创建
self.session = [[AVCaptureSession alloc] init];
sult = CaptureAVSetupResultSuccess;
2).权限检查
//权限检查 switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) { case AVAuthorizationStatusNotDetermined: { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if (granted) { sult = CaptureAVSetupResultSuccess; } }]; break; } case AVAuthorizationStatusAuthorized: { break; } default:{ sult = CaptureAVSetupResultCameraNotAuthorized; } } if ( sult != CaptureAVSetupResultSuccess) { if (self.authorizationResultBlock) { self.authorizationResultBlock(NO); } return; }
3).session配置
session配置是需要注意的是AVCaptureSession的配置不能在主线程, 需要自行创建串行线程。
3.1.1 获取输入设备与输入流
AVCaptureDevice *captureDevice = [[self class] deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack]; _captureDevice = captureDevice; NSError *error = nil; _videoDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error]; if (!_videoDeviceInput) { NSLog(@"未到设备"); }
3.1.2 录制帧数设置
帧数设置的主要目的是适配iPhone4,毕竟是应该淘汰的机器了
int frameRate; if ( [NSProcessInfo processInfo].processorCount == 1 ) { if ([self.s
ession canSetSessionPreset:AVCaptureSessionPresetLow]) { [self.session setSessionPreset:AVCaptureSessionPresetLow]; } frameRate = 10; }else{ if ([self.session canSetSessionPreset:AVCaptureSessionPreset640x480]) { [self.session setSessionPreset:AVCaptureSessionPreset640x480]; } frameRate = 30; } CMTime frameDuration = CMTimeMake( 1, frameRate ); if ( [_captureDevice lockForConfiguration:&error] ) { _captureDevice.activeVideoMaxFrameDuration = frameDuration; _captureDevice.activeVideoMinFrameDuration = frameDuration; [_captureDevice unlockForConfiguration]; } else { NSLog( @"videoDevice lockForConfiguration returned error %@", error ); }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论