目前,我正在使用 Libav API 为我的软件开发一项新功能。我能够将视频文件与音频文件合并,输出为 MP4 文件,源代码完美运行。
现在,我有一个新要求:视频和音频流的开始时间相同。两者都从 00:00 开始。我的下一个挑战是添加一个选项来根据变量改变音频流的开始时间。例如,如果音频开始变量等于 10 秒,则音频流应在时间 00:10 播放。
所以我想知道,实现此功能的最佳方法是什么?我应该在达到音频开始时间之前插入静音数据包吗?还是应该在将每个音频流数据包写入输出容器之前修改其时间戳信息?
这是我用来将音频流写入 MP4 文件的一段代码。现在它就像一个魅力,但我想这是我应该实现新要求的地方。我将不胜感激任何建议。
while (1) {
AVStream *in_stream;
int ret = av_read_frame(audioInputFormatContext, pkt);
if (ret < 0)
break;
in_stream = audioInputFormatContext->streams[pkt->stream_index];
pkt->stream_index = outIndex;
AVRational out_time_base = audioStreamList.at(i)->time_base;
// copy packet
pkt->pts = av_rescale_q_rnd(pkt->pts, in_stream->time_base, audioStreamList.at(i)->time_base,
static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt->dts = av_rescale_q_rnd(pkt->dts, in_stream->time_base, audioStreamList.at(i)->time_base,
static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
pkt->duration = av_rescale_q(pkt->duration, in_stream->time_base, audioStreamList.at(i)->time_base);
pkt->pos = -1;
ret = av_interleaved_write_frame(formatContext, pkt);
if (ret < 0) {
fprintf(stderr, "Error muxing packet\n");
break;
}
av_packet_unref(pkt);
}
最佳答案
使用 Libav API 修改任何音频流的开始时间的最佳方法是实现“adelay”过滤器。
下面是一小段代码,展示了如何使用它:
AVFilterContext *adelay_ctx;
const AVFilter *adelay;
char args[512]; // This variable contains the filter parameters
int error;
adelay = avfilter_get_by_name("adelay");
if (!adelay) {
av_log(NULL, AV_LOG_ERROR, "Could not find the adelay filter.\n");
return AVERROR_FILTER_NOT_FOUND;
}
int delay_time = 8000; // delay in milliseconds
snprintf(args, sizeof(args), "delays=%d:all=1", delay_time);
error = avfilter_graph_create_filter(&adelay_ctx, adelay, "adelay", args,
NULL, filter_graph);
if (error < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create audio adelay filter\n");
return error;
}
关于audio - Libav API : How to modify the start time of an audio stream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71566736/