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

标签 c++ c ffmpeg webcam

我正在尝试在 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 示例正在做我期望的一切。
希望对一些人有所帮助。

关于c++ - 使用 FFmpeg Libav 从网络摄像头获取视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71546531/

相关文章:

C++ 树指针错误

c++ - 知道谁指向它的对象

c - const 不应该是常量吗?

audio - 如何将AC3音频转换为Wav音频?

ffmpeg - 使用 pkg-config 找不到编译 FFMPEG x265

c++ - 帮助 WinAPI 工具栏

c++ - opencv格式字符串

c - 为什么我在多维数组中不断收到消息 "Error: arr parameter is initialized."?

c - 如何避免不支持的帧速率错误?

ffmpeg 生成的电影 (png -> mp4) 没有视频