美文网首页
6. 【视频采集实战】

6. 【视频采集实战】

作者: 东也_ | 来源:发表于2022-04-26 12:34 被阅读0次

    1. 打开视频设备

    • 设置url,"0"表示使用摄像头,”1“表示录制桌面;
    • 需要设置分辨率、帧率、采样格式,每个设备支持的参数可能都不一样;

    2. 将数据写入文件

    • 在从包里面取数据时候,要自己根据采样的格式计算正确的size,如yuv420 = 分辨率宽 x 分辨率高 x 1.5;

    3. 实战代码

    • 打开设备
    static AVFormatContext* open_device() {
        
        avdevice_register_all();
        
        AVFormatContext *ctx = NULL;
        AVDictionary *options = NULL;
    
        AVInputFormat *fmt = av_find_input_format("avfoundation");
        // 0 表示摄像头   1 表示录制桌面
        char *device_name = "0";
        // 设置分辨率
        av_dict_set(&options, "video_size", "640*480", 0);
        // 设置帧率
        av_dict_set(&options, "framerate", "29.97", 0);
        // 设置采样格式
        av_dict_set(&options, "pixel_format", "nv12", 0);
        
        
        int result = avformat_open_input(&ctx, device_name, fmt, &options);
        
        if (result < 0 ) {
            char error[1024];
            av_make_error_string(error, 1024, result);
            printf("打开设备失败:%s", error);
            return NULL;
        }
        isRecording = 1;
        
        return ctx;
        
    }
    
    • 将采集的数据写入文件
    void start_video_recorder(void) {
        
        AVFormatContext *fmt_ctx = NULL;
        fmt_ctx = open_device();
        if (!fmt_ctx) {
            goto __ERROR;
        }
        
        AVPacket *packet = NULL;
        packet = av_packet_alloc();
        if (!packet) {
            goto __ERROR;
        }
        char *path = "/Users/cunw/Desktop/learning/音视频学习/音视频文件/video_recoder.yuv";
        FILE *file = fopen(path, "wb+");
        
        int rst = 0;
        while (isRecording) {
            rst = av_read_frame(fmt_ctx, packet);
            if (rst == 0 && packet->size > 0) {
                printf("packet size is %d\n", packet->size);
                // 因为采样格式420 所以size = 640 * 480 * 1.5
                fwrite(packet->data, 640 * 480 * 1.5, 1, file);
                av_packet_unref(packet);
                
            } else if (rst == -EAGAIN) {
                av_usleep(1);
            }
        }
        
    __ERROR:
        
        isRecording = 0;
        fflush(file);
        fclose(file);
        av_packet_free(&packet);
        avformat_close_input(&fmt_ctx);
    }
    
    • 使用命令工具ffplay播放:ffplay -pixel_format nv12 -video_size 640x480 video_recoder.yuv

    相关文章

      网友评论

          本文标题:6. 【视频采集实战】

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