手把手教你实现小视频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小时内删除。