我正在尝试在 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/