[英]How can I determine if a codec / container combination is compatible with FFmpeg?
我正在考慮重新混合一些包含音頻和視頻的容器,以便我提取最好的第一個音頻流,並將其存儲在一個新的容器中,例如只有音頻流存在。
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 可以利用它來選擇兼容的輸出容器給定音頻流所在的編解碼器?
有一種動態方法可以解決這個問題。 這枚舉了每個容器的編解碼器,但您也會得到相反的結果:
// 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
}
}
}
如果您只想要特定的容器或編解碼器,您可以使用帶有name
或id
字段的白名單,並在枚舉時使用它。
對於每個單獨的多路復用器,通常有一個編解碼器標記寫入函數。該函數將檢查另一個源文件中的列表或通過相同的switch
語句工作。 沒有中央花名冊或容器匹配效用函數。 最好的辦法是在libavcodec/allcodecs.c
識別編解碼器 ID,然后在libavformat/
grep 為該 ID,特別是在后綴為 enc 的文件中,例如matroskaenc.c
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.