JoJo的个人博客

记录精彩的程序人生

目录
音视频系统入门7之实战视频采集
/    

音视频系统入门7之实战视频采集

与采集音频相比要修改的点

  • 修改设备名称
  • 增加参数
  • 修改文件名及文件数据的大小

权限

info.list文件添加Camera Usage Description权限

设备名称

//[[video device]:[audio device]]
//0: 机器的摄像头
//1: 桌面
char *devicename = "0";

设置采集参数

//分辨率
av_dict_set(&options, "video_size""640x480"0);
//帧率
av_dict_set(&options, "framerate""30"0);
//设置采集的格式
av_dict_set(&options, "pixel_format""nv12"0);

输出文件大小计算

(宽 x 高) x (yuv420=1.5/ yuv422=2/ yuv444=3)

640 x 480 x 1.5 = 460800

nv12属于yuv420格式

fwrite(pkt.data, 1460800, outfile);

代码

static
AVFormatContext* open_dev() 
{
    
    int ret = 0;
    char errors[1024] = {0, };
    
    //ctx
    AVFormatContext *fmt_ctx = NULL;
    AVDictionary *options = NULL;
    
    //[[video device]:[audio device]]
    //0: 机器的摄像头
    //1: 桌面
    char *devicename = "0";
    
    //get format 采集格式
    AVInputFormat *iformat = av_find_input_format("avfoundation");
    
    //分辨率
    av_dict_set(&options, "video_size""640x480"0);
    //帧率
    av_dict_set(&options, "framerate""30"0);
    //设置采集的格式
    av_dict_set(&options, "pixel_format""nv12"0);

    //open device 打开设备
    if ((ret = avformat_open_input(&fmt_ctx, devicename, iformat, &options)) < 0) {
       av_strerror(ret, errors, 1024);
       av_log(NULL, AV_LOG_INFO,"Failed to open audio device, [%d]%s\n", ret, errors);
       return NULL;
    }
    
    return fmt_ctx;
}


void record_video() {
    
    AVFormatContext *fmt_ctx = NULL;

    //set log level
    av_log_set_level(AV_LOG_DEBUG);
    
    //register audio device
    avdevice_register_all();
    
    //start record 开始录制
    rec_status = 1;
    
    //create file
    char *out = "/Users/tianyang/Desktop/av_base/video.yuv";
    FILE *outfile = fopen(out, "wb+");
    if(!outfile) {
        printf("Error, Failed to open file!\n");
        goto __ERROR;
    }
    
    //打开设备
    fmt_ctx = open_dev();
    if (!fmt_ctx) {
        printf("Error, Failed to open devide!\n");
        goto __ERROR;
    }
    
    int ret = 0;
    //packet 从设备上读取的数据
    AVPacket pkt;

    //read data from device 读取数据
    while (rec_status) {
        ret = av_read_frame(fmt_ctx, &pkt);
        if (ret == -35) {
            usleep(100);
            continue;
        }

        if (ret != 0 || rec_status != 1) {
            break;
        }

        printf("packet size is %d(%p)\n", pkt.size, pkt.data);

        //640*480*1.5    (宽 x 高) x (yuv420=1.5/ yuv422=2/ yuv444=3)
        fwrite(pkt.data, 1460800, outfile);
        fflush(outfile);

        //release packet 释放packet
        av_packet_unref(&pkt);
    }
    
__ERROR:
    //close device and release ctx
    if (fmt_ctx) {
        avformat_close_input(&fmt_ctx);
    }
    
    if (outfile) {
        //close file
        fclose(outfile);
    }
    
    av_log(NULL, AV_LOG_DEBUG, "finish!\n");
    
    return;
}

代码仓

FFmpegProject


标题:音视频系统入门7之实战视频采集
作者:SunnySky
地址:https://www.tianyang.pub/articles/2020/11/17/1605610660118.html

评论