iOS 模仿微信的小视频功能开发

着急的朋友直接翻到最下面的GitHub链接

先说一下思路
  1. 创建捕获会话AVCaptureSession.
  2. 创建捕获输入设备(输入设备有两个:视频输入AVCaptureDeviceInput *videoInput;音频输入AVCaptureDeviceInput *audioInput)
  3. 创建捕获视频文件输入AVCaptureMovieFileOutput.
  4. 将输入、输出加入到捕获会话。
  5. 创建录像预览图层AVCaptureVideoPreviewLayer.

==这里只放主要代码,详细的看demo,小视频本人已封装好,使用不到5行代码就可以实现小视频功能==

1.创建各种捕获对象加入到捕获会话中

- (void)zh_buildSession {
    // 捕获会话
    _captureSession = [[AVCaptureSession alloc] init];
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh]) {
        [_captureSession setSessionPreset:AVCaptureSessionPresetHigh];
    }
    // 捕捉输入
    // 摄像头
    NSError *videoError = nil;
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo] error:&videoError];
    if (!videoInput || videoError) {
        NSLog(@"摄像头设备创建失败");
        return;
    }
    if ([_captureSession canAddInput:videoInput]) {
        [_captureSession addInput:videoInput];
        _videoInput = videoInput;
    } else {
        NSLog(@"会话无法加入摄像头");
        return;
    }
    // 麦克风
    NSError *audioError = nil;
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio] error:&audioError];
    if (!audioInput || audioError) {
        NSLog(@"麦克风设备创建失败");
        return;
    }
    if ([_captureSession canAddInput:audioInput]) {
        [_captureSession addInput:audioInput];
    } else {
        NSLog(@"会话无法加入麦克风");
        return;
    }
    // 视频输出
    _output = [[AVCaptureMovieFileOutput alloc] init];
    // 设置录制模式
    AVCaptureConnection *captureConnection = [_output connectionWithMediaType:AVMediaTypeVideo];
    // 设置防抖
    if ([captureConnection isVideoStabilizationSupported]) {
        captureConnection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
    }
    if ([_captureSession canAddOutput:_output]) {
        [_captureSession addOutput:_output];
    } else {
        NSLog(@"会话无法加入输出设备");
        return;
    }
    // 添加录像图层
    _previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
    _previewLayer.frame = CGRectMake(0.f, 0.f, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // 填充模式
    [self.view.layer addSublayer:_previewLayer];
}

2.创建3个操作按钮(录像、切换摄像头、取消),这步要在创建捕捉会话后面,否则按钮就添加到了预览图层下面

- (void)zh_buildUI {
    // 切换摄像头
    _switchCameraBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [_switchCameraBtn setImage:[UIImage imageNamed:@"video_camera_0104"] forState:UIControlStateNormal];
    [_switchCameraBtn sizeToFit];
    _switchCameraBtn.frame = CGRectMake(self.view.frame.size.width - 15.f - _switchCameraBtn.frame.size.width, 30.f, _switchCameraBtn.frame.size.width, _switchCameraBtn.frame.size.height);
    [_switchCameraBtn addTarget:self action:@selector(zh_switchCameraButtonClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_switchCameraBtn];
    // 录像按钮
    _recordBtn = [ZHRecordButton buttonWithType:UIButtonTypeCustom];
    CGFloat recordBtnW = 60.f;
    _recordBtn.frame = CGRectMake(self.view.frame.size.width / 2 - recordBtnW / 2, self.view.frame.size.height - recordBtnW - recordBtnW, recordBtnW, recordBtnW);
    _recordBtn.zh_delegate = self;
    [_recordBtn addTarget:self action:@selector(zh_startRecording:) forControlEvents:UIControlEventTouchDown];
    [_recordBtn addTarget:self action:@selector(zh_endRecord:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_recordBtn];
    // 取消按钮
    _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [_cancelBtn setImage:[UIImage imageNamed:@"video_close_0104"] forState:UIControlStateNormal];
    [_cancelBtn sizeToFit];
    _cancelBtn.center = _recordBtn.center;
    _cancelBtn.frame = CGRectMake(_recordBtn.frame.origin.x - 50.f * zScaleWidth - _cancelBtn.frame.size.width, _cancelBtn.frame.origin.y, _cancelBtn.frame.size.width, _cancelBtn.frame.size.height);
    [_cancelBtn addTarget:self action:@selector(zh_cancelButtonClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_cancelBtn];
}

3.封装录像时的按钮,录像时转动圆环

// 绘制转动圆环
- (void)zh_circleAnimation {
    CAShapeLayer *circleLayer = [CAShapeLayer layer];
    circleLayer.frame = _animationLayer.bounds;
    [_animationLayer addSublayer:circleLayer];
    _circleLayer = circleLayer; // 指向这个layer用来删除
    circleLayer.fillColor =  [UIColor clearColor].CGColor;
    circleLayer.strokeColor  = [UIColor greenColor].CGColor;
    circleLayer.lineWidth = 3.f;
    CGFloat radius = _animationLayer.bounds.size.width / 2 - circleLayer.lineWidth / 2;
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:circleLayer.position radius:radius startAngle:-M_PI / 2 endAngle:M_PI * 3 / 2 clockwise:true];
    circleLayer.path = path.CGPath;
    CABasicAnimation *checkAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    checkAnimation.duration = 10;
    checkAnimation.fromValue = @(0.0f);
    checkAnimation.toValue = @(1.0f);
    [checkAnimation setValue:@"checkAnimation" forKey:@"animationName"];
    [circleLayer addAnimation:checkAnimation forKey:nil];
}

4.封装小视频录制完的预览播放

- (instancetype)initWithFrame:(CGRect)frame url:(NSURL *)url {
    self = [super initWithFrame:frame];
    if (self) {
        self.userInteractionEnabled = YES;
        // 监听播放完成通知,用来重复播放
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(zh_playFinish) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
        // 创建播放器
        _playerItem = [AVPlayerItem playerItemWithURL:url];
        _player = [AVPlayer playerWithPlayerItem:_playerItem];
        _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
        _playerLayer.frame = self.layer.bounds;
        _playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self.layer addSublayer:_playerLayer];
        [_player play];
        // 创建返回按钮
        UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        cancelBtn.tag = 1000;
        [cancelBtn setImage:[UIImage imageNamed:@"video_return_0104"] forState:UIControlStateNormal];
        CGFloat cancelBtnW = 60.f;
        cancelBtn.center = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
        cancelBtn.frame = CGRectMake(cancelBtn.frame.origin.x, self.frame.size.height - cancelBtnW * 2, cancelBtnW, cancelBtnW);
        [cancelBtn addTarget:self action:@selector(zh_buttonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:cancelBtn];
        // 创建使用按钮
        UIButton *confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        confirmBtn.tag = 1001;
        [confirmBtn setImage:[UIImage imageNamed:@"video_success_0104"] forState:UIControlStateNormal];
        [confirmBtn sizeToFit];
        confirmBtn.frame = cancelBtn.frame;
        [confirmBtn addTarget:self action:@selector(zh_buttonClick:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:confirmBtn];
        // 移动
        [self zh_moveButton:cancelBtn value:(-50 * zScaleWidth - cancelBtn.frame.size.width)]; // 左移需要多加一个按钮的距离
        [self zh_moveButton:confirmBtn value:50 * zScaleWidth];
    }
    return self;
}

最后附上GitHub

你可能感兴趣的:(iOS 模仿微信的小视频功能开发)