繁体   English   中英

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

[英]Get video from webcam using FFmpeg Libav

我正在尝试在 Mac 计算机上使用 FFmpeg C 库 (libav) 录制网络摄像头视频。 我对 transcode.c 示例进行了更改,以便它打开设备而不是文件。 但是,由于某种原因,代码只接收一个数据包然后关闭。

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;
}

我一直在寻找其他代码示例,但它们都已被弃用,不再在更新的 FFmpeg 中编译。

我的 open_input_source 函数中是否缺少一些设置? 或者,使用转码的问题是我的基础吗? 我应该尝试使用其他示例吗?

一般来说,是否有满足我要求的 C 源代码参考?

谢谢

这是一个非常充实的示例,可能满足您的要求:

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

我不认为您需要的代码几乎与其中包含的代码一样多,但是您可以只更新第 260 行,让它运行多长时间(该示例为 300 帧)和第 83 行以打开您的网络摄像头(听起来就像您已经在代码中使用ret = avformat_open_input(&ifmt_ctx, dev_name, p_av_input_format, &p_av_options)成功完成了此操作。

根据此处未提供的详细信息,您可能希望删除、保留或更改许多其他选项。 不幸的是,我没有可以在这里分享的简化代码示例,但是这个 dshow 示例正在做我期望的一切。

希望对一些人有所帮助。

暂无
暂无

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

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