美文网首页
FFmpeg录制视频

FFmpeg录制视频

作者: lieon | 来源:发表于2021-07-12 15:41 被阅读0次

    视频录制步骤

    • 获取输入格式对象 av_find_input_format
    • 设置设备参数(视频三要素): video_size, pixel_format, framerate
    • 打开设备 avformat_open_input
    • 创建数据包 av_packet_alloc
    • while循环读取帧数据 av_read_frame
    • 将读取到的数据存入文件
    • 关闭设备
    • 关闭文件
    - (void)record {
        NSString *fmtname = @"avfoundation";
        NSString *deviceName = @"0";
        // 获取输入格式对象
        AVInputFormat *fmt = av_find_input_format(fmtname.UTF8String);
        if (!fmt) {
            NSLog(@"av_find_input_format error: %@",  fmtname);
            return;
        }
        // 格式上下文
        AVFormatContext *ctx = nullptr;
        // 设备参数
        AVDictionary *options = nullptr;
        av_dict_set(&options, "video_size", "640x480", 0);
        av_dict_set(&options, "pixel_format", "nv12", 0);
        av_dict_set(&options, "framerate", "30", 0);
        // 打开设备
        int ret = avformat_open_input(&ctx, deviceName.UTF8String, fmt, &options);
        if (ret < 0) {
            ERROR_BUF(ret);
            NSLog(@"avformat_open_input error :%s", errbuf);
            return;
        }
        NSString *filePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
        NSString *fileName = [filePath stringByAppendingPathComponent:@"out.yuv"];
        [[NSFileManager defaultManager]createFileAtPath:fileName contents:[NSData new] attributes:nil];
        NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:fileName];
        if (!file) {
            avformat_close_input(&ctx);
            return;
        }
        // 计算一帧的大小
        AVCodecParameters *params = ctx->streams[0]->codecpar;
        AVPixelFormat pixFmt = (AVPixelFormat)params->format;
        int imgeSize = av_image_get_buffer_size(pixFmt,
                                                params->width,
                                                params->height,
                                                1);
        // 数据包
        AVPacket *pkt = av_packet_alloc();
        while (!self.isStop) {
            ret = av_read_frame(ctx, pkt);
            if (ret == 0) { // 读取成功
                NSData *data = [NSData dataWithBytes:pkt->data length:imgeSize];
                [file writeData:data];
                [file seekToEndOfFile];
                av_packet_unref(pkt);
            } else if (ret == AVERROR(EAGAIN)) {
                continue;
            } else {
                break;
            }
        }
        av_packet_free(&pkt);
        [file closeFile];
        avformat_close_input(&ctx);
    }
    
    

    命令行录制与播放

    • ffpmg命令录制
    ffmpeg -f avfoundation -video_size 1280x720 -pixel_format uyvy422 -framerate 30  -i 0 out.yuv
    
    • 播放
    ffplay -video_size 1280x720 -pixel_format uyvy422 -framerate 30 out.yuv
    

    相关文章

      网友评论

          本文标题:FFmpeg录制视频

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