美文网首页
音视频-视频录制编程

音视频-视频录制编程

作者: li_礼光 | 来源:发表于2021-07-14 23:38 被阅读0次
    Mac下ffmpeg视频录制
    ffmpeg -f avfoundation -framerate 30 -i 0 out.yuv
    
    Mac下ffmpeg音频录制
    ffmpeg -f avfoundation -i :0 out.wav
    

    对比命令行的录制音频和视频. 其实可以猜得到, 视频录制编程 跟音视频-ffmpeg录制PCM是一样的思路的.

    主要步骤

    注册设备 avdevice_register_all();
    获取输入格式对象 av_find_input_format
    打开设备 avformat_open_input
    采集数据 av_read_frame
    释放资源 avformat_close_input

    Mac平台添加info

    <key>NSCameraUsageDescription</key>
    <string>申请使用摄像头进行录制</string>
    

    如果添加了还报错, 删除之前编译好的工程.

    可能会遇到的格式支持方案的报错

    [avfoundation @ 0x10c0c5600] Selected framerate (29.970030) is not supported by the device.
    [avfoundation @ 0x10c0c5600] Supported modes:
    [avfoundation @ 0x10c0c5600]   1280x720@[1.000000 30.000000]fps
    [avfoundation @ 0x10c0c5600]   1280x720@[1.000000 30.000000]fps
    [avfoundation @ 0x10c0c5600]   1280x720@[1.000000 30.000000]fps
    

    设置符合规则的像素格式和视频大小, 如何设置

    通过API的注释中搜索, 可以搜索关键字"pixel_format" 或者是"pixel", 像素格式可以发现

     * @code
     * AVDictionary *options = NULL;
     * av_dict_set(&options, "video_size", "640x480", 0);
     * av_dict_set(&options, "pixel_format", "rgb24", 0);
     *
     * if (avformat_open_input(&s, url, NULL, &options) < 0)
     *     abort();
     * av_dict_free(&options);
    

    就知道了怎么设置视频参数格式


    代码实现

    // 格式名称,设备名称
    #ifdef Q_OS_WIN
        // todo win下的配置根据电脑来, 因为win没有摄像头, 用Mac的来实现先
    #else
        #define FMT_NAME "avfoundation"
        #define DEVICE_NAME "0"
        #define FILEPATH "/Users/liliguang/Desktop/"
        #define FILENAME "record_to_yuv.yuv"
        #define VEDIO_SIZE "1280x720"
        #define FRAMERATE "30"
        #define PIXEL_FORMAT "uyvy422"
    #endif
    
    void VedioThread::run() {
        qDebug() << this << "开始执行----------";
        // 获取输入格式对象
        AVInputFormat *fmt = av_find_input_format(FMT_NAME);
        if (!fmt) {
            qDebug() << "获取输入格式对象失败" << FMT_NAME;
            return;
        }
        qDebug() << "fmt : " << fmt;
        // 格式上下文(将来可以利用上下文操作设备)
    
    
        AVFormatContext *ctx = nullptr;
    
    
        AVDictionary *options = NULL;
        av_dict_set(&options, "video_size", VEDIO_SIZE, 0);
        av_dict_set(&options, "framerate", FRAMERATE, 0);
        av_dict_set(&options, "pixel_format", PIXEL_FORMAT , 0);
    
        // 打开设备
        int ret = avformat_open_input(&ctx, DEVICE_NAME, fmt, &options);
        if (ret < 0) {
            char errbuf[1024];
            av_strerror(ret, errbuf, sizeof (errbuf));
            qDebug() << "打开设备失败" << errbuf;
            return;
        }
        qDebug() << "ret : " << ret;
    
        // 文件名
        QString filename = FILEPATH;
        filename += FILENAME;
        QFile file(filename);
        if (!file.open(QFile::WriteOnly)) {
            qDebug() << "文件打开失败" << filename;
            // 关闭设备
            avformat_close_input(&ctx);
            return;
        }
        // 数据包
        AVPacket pkt;
        while (!isInterruptionRequested()) {
            // 不断采集数据
            ret = av_read_frame(ctx, &pkt);
            if (ret == 0) { // 读取成功
                // 将数据写入文件
                file.write((const char *) pkt.data, pkt.size);
            } else if (ret == AVERROR(EAGAIN)) { // 资源临时不可用
                continue;
            } else { // 其他错误
                char errbuf[1024];
                av_strerror(ret, errbuf, sizeof (errbuf));
                qDebug() << "av_read_frame error" << errbuf << ret;
                break;
            }
        }
        // 释放资源
        // 关闭文件
        file.close();
        // 关闭设备
        avformat_close_input(&ctx);
        qDebug() << this << "正常结束----------";
    }
    

    正常输出:
    2021-07-14 23:30:40.838608+0800 9_record_to_yuv[10634:364232] VedioThread(0x12583ba30) 开始执行----------
    2021-07-14 23:30:40.838828+0800 9_record_to_yuv[10634:364232] fmt :  0x10166fac0
    2021-07-14 23:30:40.841558+0800 9_record_to_yuv[10634:364232] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x1097673c0> F8BB1C28-BAE8-11D6-9C31-00039315CD46
    2021-07-14 23:30:40.865234+0800 9_record_to_yuv[10634:364232]  HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
    2021-07-14 23:30:40.865519+0800 9_record_to_yuv[10634:364232]  HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
    2021-07-14 23:30:40.886784+0800 9_record_to_yuv[10634:364232] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x12583f000> 30010C1C-93BF-11D8-8B5B-000A95AF9C6A
    2021-07-14 23:30:43.274195+0800 9_record_to_yuv[10634:364232] ret :  0
    2021-07-14 23:30:56.460552+0800 9_record_to_yuv[10634:364232] [] CMIO_DAL_PlugIn.cpp:269:StreamCopyBufferQueue Error: 1852797029, got an error from the plug-in routine
    2021-07-14 23:30:56.464971+0800 9_record_to_yuv[10634:364232] VedioThread(0x12583ba30) 正常结束----------
    2021-07-14 23:30:56.465248+0800 9_record_to_yuv[10634:364047] VedioThread(0x12583ba30) 析构(内存被回收)
    

    使用FFmpeg命令行播放

    ffplay -video_size 1280x720 -pixel_format uyvy422 -framerate 30 record_to_yuv.yuv 
    

    自测播放正常

    相关文章

      网友评论

          本文标题:音视频-视频录制编程

          本文链接:https://www.haomeiwen.com/subject/bqmupltx.html