如何用FFmpeg-libav提取MP3的ID3标签?现有代码无效求助
用FFmpeg-libav提取MP3的ID3标签
当然可以通过FFmpeg-libav提取MP3的ID3标签。你的Kotlin代码可能存在封装库的调用细节问题,以下是修正后的实现方案:
可能的问题点
- 部分特殊格式的MP3文件,需要确保
avformat_find_stream_info执行完成,才能完整解析元数据 - org.bytedeco封装库中,
AVDictionaryEntry的字符串提取需指定编码格式,避免乱码或读取失败
修正后的Kotlin代码
fun extractMetadata(mp3FilePath: String) { avformat.av_register_all() val formatContext = AVFormatContext(null) val openRet = avformat.avformat_open_input(formatContext, mp3FilePath, null, null) if (openRet < 0) { println("无法打开输入文件,错误码: $openRet") return } // 强制获取流信息,确保元数据被完整解析 val streamRet = avformat.avformat_find_stream_info(formatContext, null) if (streamRet < 0) { println("无法获取流信息,错误码: $streamRet") } // 遍历所有元数据条目 var entry: AVDictionaryEntry? = avformat.av_dict_get(formatContext.metadata, "", null, avformat.AV_DICT_IGNORE_SUFFIX) while (entry != null) { val key = entry.key().getString(Charsets.UTF_8) val value = entry.value().getString(Charsets.UTF_8) println("Key: $key, Value: $value") entry = avformat.av_dict_get(formatContext.metadata, "", entry, avformat.AV_DICT_IGNORE_SUFFIX) } avformat.avformat_close_input(formatContext) }
对应的C++参考代码
如果你需要C++版本作为转换参考,以下是标准实现:
#include <iostream> #include <libavformat/avformat.h> void extractMetadata(const char* mp3FilePath) { av_register_all(); AVFormatContext* formatContext = nullptr; int ret = avformat_open_input(&formatContext, mp3FilePath, nullptr, nullptr); if (ret < 0) { std::cerr << "无法打开输入文件,错误码: " << ret << std::endl; return; } if (avformat_find_stream_info(formatContext, nullptr) < 0) { std::cerr << "无法获取流信息" << std::endl; } AVDictionaryEntry* entry = nullptr; while ((entry = av_dict_get(formatContext->metadata, "", entry, AV_DICT_IGNORE_SUFFIX))) { std::cout << "Key: " << entry->key << ", Value: " << entry->value << std::endl; } avformat_close_input(&formatContext); } int main() { extractMetadata("your-file.mp3"); return 0; }
额外提示
- 确保使用的FFmpeg库版本支持ID3v1和ID3v2标签解析(主流版本均支持)
- 若仍无法获取标签,可先用
ffmpeg -i your-file.mp3命令验证目标MP3文件是否确实包含ID3标签
内容的提问来源于stack exchange,提问作者Omid.N
相关产品推荐
相关产品推荐

