使用FFmpeg检索专辑封面

我正在开发一个依靠FFmpeg检索audio元数据的Android应用程序。 我知道这是可能的检索专辑封面使用FFMpeg编程。 但是,一旦你已经解码艺术品(MP3中的video帧),如何生成一个图像文件(PNG)在应用程序内使用? 我已经search了所有,但似乎无法find一个工作的例子。

编辑,这里是解决scheme:

#include <libavcodec/avcodec.h> #include <libavformat/avformat.h> void retrieve_album_art(const char *path, const char *album_art_file) { int i, ret = 0; if (!path) { printf("Path is NULL\n"); return; } AVFormatContext *pFormatCtx = avformat_alloc_context(); printf("Opening %s\n", path); // open the specified path if (avformat_open_input(&pFormatCtx, path, NULL, NULL) != 0) { printf("avformat_open_input() failed"); goto fail; } // read the format headers if (pFormatCtx->iformat->read_header(pFormatCtx) < 0) { printf("could not read the format header\n"); goto fail; } // find the first attached picture, if available for (i = 0; i < pFormatCtx->nb_streams; i++) if (pFormatCtx->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) { AVPacket pkt = pFormatCtx->streams[i]->attached_pic; FILE* album_art = fopen(album_art_file, "wb"); ret = fwrite(pkt.data, pkt.size, 1, album_art); fclose(album_art); av_free_packet(&pkt); break; } if (ret) { printf("Wrote album art to %s\n", album_art_file); } fail: av_free(pFormatCtx); // this line crashes for some reason... //avformat_free_context(pFormatCtx); } int main() { avformat_network_init(); av_register_all(); const char *path = "some url"; const char *album_art_file = "some path"; retrieve_album_art(path, album_art_file); return 0; } 

Solutions Collecting From Web of "使用FFmpeg检索专辑封面"

要以编程方式使用ffmpeg,我想你必须在libavformat(它是ffmpeg的一部分)中调用read_apic ()。

从命令行,你显然可以这样做:

 ffmpeg -i input.mp3 -an -vcodec copy cover.jpg 

命令行的行为意味着封面艺术图像被看作是另一个videostream(只包含一帧),所以使用libavformat以通常的方式去解码stream的video部分应该产生该图像。

示例代码demuxing: ffmpeg / docs / examples / demuxing.c第一个(也是唯一的)AVPacket将从一个MP3解复用videostream将包含JPEG文件(仍编码为JPEG,未解码)。

 AVFormatContext* fmt_ctx; // set up fmt_ctx to read first video stream AVPacket pkt; av_read_frame(fmt_ctx, &pkt); FILE* image_file = fopen("image.jpg", "wb"); int result = fwrite(pkt.data, pkt.size, 1, image_file); fclose(image_file); 

如果有多个图像,我认为他们将被视为独立的videostream,而不是作为单独的数据包在同一个stream。 第一个stream将是最大的分辨率。

所有这些都可能在read_apic()方面内部实现。

ID3v2规范允许使用任何图像格式,但推荐JPEG或PNG。 在实践中,ID3中的所有图像都是JPEG。

编辑 :移动一些不太有用的位到附言:

PS ffmpeg -i input.mp3 -f ffmetadata metadata.txt会产生一个包含元数据的类似ini的文件,但是图像甚至没有被引用到那里,所以这不是一个有用的方法。

PS ID3v2标签中可能有多个图像 。 当存在多个图像或多个图像types时,您可能需要处理这种情况。

PS ffmpeg可能不是最好的软件。 使用id3lib , TagLib或ID3的其他实现之一 。 这些可以作为库(可以从您select的语言中调用)或命令行工具使用。 这里有TagLib的示例C ++代码: 如何使用TagLib以不同的audio格式读/写coverart? 和id3lib在这里: 如何从audio文件使用id3lib专辑封面 。