简体   繁体   English

使用 FFmpeg Libav 从网络摄像头获取视频

[英]Get video from webcam using FFmpeg Libav

I am trying to record webcam video using FFmpeg C libraries (libav), on a Mac computer.我正在尝试在 Mac 计算机上使用 FFmpeg C 库 (libav) 录制网络摄像头视频。 I made changes to the transcode.c example so that it opens a device instead of a file.我对 transcode.c 示例进行了更改,以便它打开设备而不是文件。 However, for some reason the code only receives a single packet and then closes.但是,由于某种原因,代码只接收一个数据包然后关闭。

static int open_input_source(const char *dev_name) {
int ret;
unsigned int i;
AVDictionary *p_av_options = NULL;
AVInputFormat *p_av_input_format = av_find_input_format("avfoundation");
av_dict_set(&p_av_options, "framerate", "30", 0);

ifmt_ctx = NULL;
if ((ret = avformat_open_input(&ifmt_ctx, dev_name, p_av_input_format, &p_av_options) < 0)) {
    av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
    return ret;
}

if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
    av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
    return ret;
}

stream_ctx = av_calloc(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
if (!stream_ctx)
    return AVERROR(ENOMEM);

for (i = 0; i < ifmt_ctx->nb_streams; i++) {
    AVStream *stream = ifmt_ctx->streams[i];
    const AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
    AVCodecContext *codec_ctx;
    if (!dec) {
        av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
        return AVERROR_DECODER_NOT_FOUND;
    }
    codec_ctx = avcodec_alloc_context3(dec);
    if (!codec_ctx) {
        av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
        return AVERROR(ENOMEM);
    }
    ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
                                   "for stream #%u\n", i);
        return ret;
    }
    /* Reencode video & audio and remux subtitles etc. */
    if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
        || codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
        if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
            codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL);
        /* Open decoder */
        ret = avcodec_open2(codec_ctx, dec, NULL);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
            return ret;
        }
    }
    stream_ctx[i].dec_ctx = codec_ctx;

    stream_ctx[i].dec_frame = av_frame_alloc();
        if (!stream_ctx[i].dec_frame)
            return AVERROR(ENOMEM);
    }

    av_dump_format(ifmt_ctx, 0, dev_name, 0);
    return 0;
}

I have looked for other code examples but they are all deprecated and no longer compile in updated FFmpeg.我一直在寻找其他代码示例,但它们都已被弃用,不再在更新的 FFmpeg 中编译。

Is there some missing setting in my open_input_source function?我的 open_input_source 函数中是否缺少一些设置? Alternatively, is the problem in using transcoding is my basis?或者,使用转码的问题是我的基础吗? Should I try to use some other example?我应该尝试使用其他示例吗?

In general, is there is a C source code reference which fulfills my requirements?一般来说,是否有满足我要求的 C 源代码参考?

Thanks谢谢

This is a pretty fleshed out example that might meet your requirements:这是一个非常充实的示例,可能满足您的要求:

https://github.com/argvk/ffmpeg-examples/blob/master/dshow_capture_video.c https://github.com/argvk/ffmpeg-examples/blob/master/dshow_capture_video.c

I don't think you need nearly as much code as is include there, but you might be able to just update lines 260 with how long you want it to run (that example is 300 frames) and line 83 to open your webcam (sounds like you've already successfully done this with ret = avformat_open_input(&ifmt_ctx, dev_name, p_av_input_format, &p_av_options) in your code.我不认为您需要的代码几乎与其中包含的代码一样多,但是您可以只更新第 260 行,让它运行多长时间(该示例为 300 帧)和第 83 行以打开您的网络摄像头(听起来就像您已经在代码中使用ret = avformat_open_input(&ifmt_ctx, dev_name, p_av_input_format, &p_av_options)成功完成了此操作。

There are lots of other options there which you might want to remove, keep, or change depending on the details which are not provided here.根据此处未提供的详细信息,您可能希望删除、保留或更改许多其他选项。 Unfortunately I don't have a simplified code sample I'm able to share on here, but this dshow example is doing everything I expect.不幸的是,我没有可以在这里分享的简化代码示例,但是这个 dshow 示例正在做我期望的一切。

Hope it helps some.希望对一些人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM