簡體   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