如何确定编解码器/容器组合是否与 FFmpeg 兼容?

Dan*_*Dan 4 audio ffmpeg libavcodec libav libavformat

我正在考虑重新混合一些保存音频和视频的容器,以便提取最好的第一个音频流,并将其存储在一个新容器中,例如存在音频流。

\n\n

FFmpeg 的输出上下文是这样创建的:

\n\n
AVFormatContext* output_context = NULL;\navformat_alloc_output_context2( &output_context, NULL, "mp4", NULL );\n
Run Code Online (Sandbox Code Playgroud)\n\n

我有一个可接受的输出的候选列表,例如 MP4、M4A 等 \xe2\x80\xa6 基本上是 Apple 的音频文件服务可读的输出:

\n\n
kAudioFileAIFFType              = \'AIFF\',\nkAudioFileAIFCType              = \'AIFC\',\nkAudioFileWAVEType              = \'WAVE\',\nkAudioFileSoundDesigner2Type    = \'Sd2f\',\nkAudioFileNextType              = \'NeXT\',\nkAudioFileMP3Type               = \'MPG3\',   // mpeg layer 3\nkAudioFileMP2Type               = \'MPG2\',   // mpeg layer 2\nkAudioFileMP1Type               = \'MPG1\',   // mpeg layer 1\nkAudioFileAC3Type               = \'ac-3\',\nkAudioFileAAC_ADTSType          = \'adts\',\nkAudioFileMPEG4Type             = \'mp4f\',\nkAudioFileM4AType               = \'m4af\',\nkAudioFileM4BType               = \'m4bf\',\nkAudioFileCAFType               = \'caff\',\nkAudioFile3GPType               = \'3gpp\',\nkAudioFile3GP2Type              = \'3gp2\',\nkAudioFileAMRType               = \'amrf\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的问题是:FFmpeg 中是否有一个简单的 API,可以根据音频流所在的编解码器来选择兼容的输出容器?

\n

Bim*_*Bim 5

有一个动态的方法可以解决这个问题。这枚举了每个容器的编解码器,但您也得到了相反的结果:

// enumerate all codecs and put into list
std::vector<AVCodec*> encoderList;
AVCodec * codec = nullptr;
while (codec = av_codec_next(codec))
{
    // try to get an encoder from the system
    auto encoder = avcodec_find_encoder(codec->id);
    if (encoder)
    {
        encoderList.push_back(encoder);
    }
}
// enumerate all containers
AVOutputFormat * outputFormat = nullptr;
while (outputFormat = av_oformat_next(outputFormat))
{
    for (auto codec : encoderList)
    {
        // only add the codec if it can be used with this container
        if (avformat_query_codec(outputFormat, codec->id, FF_COMPLIANCE_STRICT) == 1)
        {
            // add codec for container
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您只需要特定的容器或编解码器,您可以将白名单与它们nameid字段一起使用,并在枚举时使用它。