FFmpeg录制视频

视频录制步骤

  • 获取输入格式对象 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录制视频)