当前位置: 代码网 > it编程>App开发>苹果IOS > 使用AVFoundation实现视频录制详解

使用AVFoundation实现视频录制详解

2024年05月19日 苹果IOS 我要评论
一、前言avcapturesession 是 avfoundation 的核心类,用于管理捕获对象 avcaptureinput 的视频和音频的输入,协调捕获的输出 avcaptureoutput。a

一、前言

avcapturesession 是 avfoundation 的核心类,用于管理捕获对象 avcaptureinput 的视频和音频的输入,协调捕获的输出 avcaptureoutput。

avcaptureoutput 的输出有两种方法:

  • 一种是直接以 moviefileurl 方式输出;
  • 一种是以原始数据流 data 的方式输出

流程对比图如下:

下面详细讲解录制视频的方案:

二、avcapturesession + avcapturemoviefileoutput

1.创建avcapturesession

//导入 avfoundation.framework 
#import <avfoundation/avfoundation.h>

//声明属性
@property (nonatomic, strong) avcapturesession *capturesession;

//懒加载 avcapturesession
- (avcapturesession *)capturesession {
    if (!_capturesession) {
        _capturesession = [[avcapturesession alloc] init];
        
        //设置分辨率
        if ([_capturesession cansetsessionpreset:avcapturesessionpresethigh]) {
            [_capturesession setsessionpreset:avcapturesessionpresethigh];
        }
    }
    return _capturesession;
}

注意:avcapturesession 的调用是会阻塞线程的,建议单独开辟子线程处理。2.设置音频、视频输入

//声明属性
@property (nonatomic, strong) avcapturedeviceinput *videoinput;
@property (nonatomic, strong) avcapturedeviceinput *audioinput;


//设置视频,音频输入源
- (void)setcapturedeviceinput {
    //1. 视频输入源
    //获取视频输入设备, 默认后置摄像头
    avcapturedevice *videocapturedevice = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo];
    
    nserror *error = nil;
    self.videoinput = [avcapturedeviceinput deviceinputwithdevice:videocapturedevice error:&error];
    
    if ([self.capturesession canaddinput:self.videoinput]) {
        [self.capturesession addinput:self.videoinput];
    }
    
    
    //2. 音频输入源
    avcapturedevice *audiocapturedevice = [[avcapturedevice deviceswithmediatype:avmediatypeaudio] firstobject];
    self.audioinput = [avcapturedeviceinput deviceinputwithdevice:audiocapturedevice error:&error];
    if ([self.capturesession canaddinput:self.audioinput]) {
        [self.capturesession addinput:self.audioinput];
    }
    
}

3.设置文件输出源

//声明属性
@property (nonatomic, strong) avcapturemoviefileoutput *moviefileoutput;
@property (nonatomic, strong) avcapturevideopreviewlayer *previewlayer;


//设置文件输出源
- (void)setdevicefileoutput {
    
    //初始化文件输出对象
    self.moviefileoutput = [[avcapturemoviefileoutput alloc] init];
    
    //捕获会话中特定捕获输入对象和捕获输出对象之间的连接
    avcaptureconnection *captureconnection = [self.moviefileoutput connectionwithmediatype:avmediatypevideo];
    
    //设置防抖
    if ([captureconnection isvideostabilizationsupported]) {
        captureconnection.preferredvideostabilizationmode = avcapturevideostabilizationmodeauto;
    }
    
    //预览图层和视频方向保持一致
    captureconnection.videoorientation = [self.previewlayer connection].videoorientation;
    
    //添加文件输出源
    if ([self.capturesession canaddoutput:self.moviefileoutput]) {
        [self.capturesession addoutput:self.moviefileoutput];
    }
    
}

4.添加视频预览层

- (void)setvideopreviewlayer {
    self.previewlayer.frame = [uiscreen mainscreen].bounds;
    
    [self.superview.layer addsublayer:self.previewlayer];
}


- (avcapturevideopreviewlayer *)previewlayer {
    if (!_previewlayer) {
        _previewlayer = [avcapturevideopreviewlayer layerwithsession:self.capturesession];
        _previewlayer.maskstobounds = yes;
        _previewlayer.videogravity = avlayervideogravityresizeaspectfill;//填充模式
    }
    return _previewlayer;
}

5. 开始采集

//声明属性
@property (nonatomic, strong) dispatch_queue_t sessionqueue;

//开始采集
- (void)startcapture {
    self.sessionqueue = dispatch_queue_create("com.capturesession.queue", dispatch_queue_concurrent);

    if (![self.capturesession isrunning]) {
        __weak __typeof(self) weakself = self;
        
        dispatch_async(self.sessionqueue, ^{
            [weakself.capturesession startrunning];
        });
        
    }
}

6. 开始录制

//开始录制
- (void)startrecord {
    
    [self.moviefileoutput startrecordingtooutputfileurl:[self createvideopath] recordingdelegate:self];
}

当实际的录制开始或停止时,系统会有代理回调。当开始录制之后,这时可能还没有真正写入,真正开始写入会回调下面代理,停止录制也是如此,所以如果你需要对录制视频起始点操作,建议通过系统的回调代理:

//实现协议 <avcapturefileoutputrecordingdelegate>中的方法


#pragma mark _ avcapturefileoutputrecordingdelegate

//起始点 - 开始录制
- (void)captureoutput:(avcapturefileoutput *)output didstartrecordingtooutputfileaturl:(nsurl *)fileurl fromconnections:(nsarray<avcaptureconnection *> *)connections {
    
}

//结束录制
-(void)captureoutput:(avcapturefileoutput *)captureoutput didfinishrecordingtooutputfileaturl:(nsurl *)outputfileurl fromconnections:(nsarray *)connections error:(nserror *)error
{
    nslog(@"视频录制完成. 文件路径:%@",[outputfileurl absolutestring]);
}

7.停止录制

//停止录制
- (void)stoprecord {
    if ([self.moviefileoutput isrecording]) {
        [self.moviefileoutput stoprecording];
    }
}

8.停止采集

//停止采集
- (void)stopcapture {
    if ([self.capturesession isrunning]) {
        __weak __typeof(self) weakself = self;
        dispatch_async(self.sessionqueue, ^{
            [weakself.capturesession stoprunning];
            weakself.capturesession = nil;
        });
    }
}

到此这篇关于使用avfoundation实现视频录制详解的文章就介绍到这了,更多相关avfoundation实现视频录制内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com