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

问题描述 投票:1回答:2

我正在寻找重新复制一些容纳音频和视频的容器,以便我提取最好的第一音频流,并将其存储在一个新的容器中,例如,只有音频流存在。

FFmpeg的输出上下文的创建方式如下:

AVFormatContext* output_context = NULL;
avformat_alloc_output_context2( &output_context, NULL, "mp4", NULL );

我有一份可接受的输出名单,例如: MP4,M4A等......基本上是Apple的音频文件服务可读取的:

kAudioFileAIFFType              = 'AIFF',
kAudioFileAIFCType              = 'AIFC',
kAudioFileWAVEType              = 'WAVE',
kAudioFileSoundDesigner2Type    = 'Sd2f',
kAudioFileNextType              = 'NeXT',
kAudioFileMP3Type               = 'MPG3',   // mpeg layer 3
kAudioFileMP2Type               = 'MPG2',   // mpeg layer 2
kAudioFileMP1Type               = 'MPG1',   // mpeg layer 1
kAudioFileAC3Type               = 'ac-3',
kAudioFileAAC_ADTSType          = 'adts',
kAudioFileMPEG4Type             = 'mp4f',
kAudioFileM4AType               = 'm4af',
kAudioFileM4BType               = 'm4bf',
kAudioFileCAFType               = 'caff',
kAudioFile3GPType               = '3gpp',
kAudioFile3GP2Type              = '3gp2',
kAudioFileAMRType               = 'amrf'

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

audio ffmpeg libavcodec libav libavformat
2个回答
1
投票

对于每个单独的复用器,通常有一个编解码器标签写入功能。该功能将检查另一个源文件中的列表或通过相同的switch语句进行工作。没有中央名册或容器匹配效用函数。最好的办法是在libavcodec/allcodecs.c中识别编解码器ID,然后在libavformat/中为该ID识别grep,特别是在以enc为后缀的文件中。 matroskaenc.c


2
投票

有一个动态的方法来解决这个问题。这枚举了每个容器的编解码器,但你也得到了反转:

// 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
        }
    }
}

如果您只想要特定的容器或编解码器,可以使用带有nameid字段的白名单,并在枚举时使用它。

© www.soinside.com 2019 - 2024. All rights reserved.