如何在 C++ 中使用 ffmpeg 动态更改视频的音轨?

Posted

技术标签:

【中文标题】如何在 C++ 中使用 ffmpeg 动态更改视频的音轨?【英文标题】:How to change the audio track of a video on the fly using ffmpeg in c++? 【发布时间】:2012-07-19 05:15:35 【问题描述】:

我正在尝试在 android 中开发媒体播放器应用程序。我使用海豚播放器的代码作为参考。但我不知道如何在播放视频时动态更改音频和字幕轨道。使用 ffmpeg 的命令行是可能的,但是如何使用 ffmpeg c++ 代码呢?

【问题讨论】:

What have you tried? 【参考方案1】:

视频文件是一个包含一堆流的容器。首先,您必须打开视频文件并提取流信息(对于较小的代码避免错误检查):

AVFormatContext *pFormatCtx;
av_open_input_file( &pFormatCtx, argv[1], NULL, 0, NULL );
av_find_stream_info( pFormatCtx );

现在您可以迭代流并查找所有音频流:

for ( i=0; i != pFormatCtx->nb_streams; i++ )

   if (pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) audiostreams.push_back( i );

选择您要播放的流并获取指向编解码器的指针并打开它:

AVCodecContext* aCodecCtx = pFormatCtx->streams[SelectedAudioStream]->codec;
AVCodec* aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
avcodec_open(aCodecCtx, aCodec);

之后像往常一样解码流。

【讨论】:

感谢您的回复。上述场景是在视频文件中嵌入了多个音频流的情况。我还有一个疑问,我们是否可以选择外部音频文件并将其与视频播放同步。例如,如果我有一部英文电影,并且我有电影的其他语言的外部音轨,是否可以通过选择可用的语言音轨来更改音轨? 如果是外部文件,同步完全取决于您。粗略是可能的,但是问题中的细节太少,无法以这种方式回答。 假设我们在播放视频时选择了一个外部音轨,是不是我们会创建一个新的 AVFormatContext *pFormatCtx 对象; av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL); av_find_stream_info(pFormatCtx);并获取音频流索引并将其设置为当前播放视频的音频流并继续播放..我的理解对吗? 您能帮我从流中获取音轨的标题吗?即,如果它是多语言视频文件,那么我们可以选择“Language1”、“Language2”等。我们将如何获得该名称? 在 AVStream 结构 (dranger.com/ffmpeg/data.html#AVStream) 中有一个字段 char language [4] - 明智地使用它:)

以上是关于如何在 C++ 中使用 ffmpeg 动态更改视频的音轨?的主要内容,如果未能解决你的问题,请参考以下文章

如何在c ++中使用ffmpeg编码视频时设置moov原子位置

FFMPEG 如何将 MJPEG 编码数据复用到 mp4 或 avi 容器 c++

如何更改输入视频的ffmpeg缓冲区

C++ 在控制台应用程序中播放视频音频

ffmpeg - 添加和删除字幕而不更改视频

在 c++ 中以可变帧速率使用 FFmpeg 库(不是 libav 分支)以编程方式捕获视频