首页 > 编程知识 正文

ffmpeg获取音频信息,ffmpeg获取视频文件信息

时间:2023-05-04 01:12:13 阅读:224449 作者:3425

获取mediainfo 首先调用av_register_all将所有的编码器和解码器注册好

来看下具体的注册实现

void av_register_all(void){ ff_thread_once(&av_format_next_init, av_format_init_next);}// 看下av_format_init_next的实现// 可以看到函数内部是实现了将编码器和解码器使用指针进行串联的操作// 如果有输出或者输入列表,将输出或输入列表也进行串联static void av_format_init_next(void){ AVOutputFormat *prevout = NULL, *out; AVInputFormat *previn = NULL, *in; ff_mutex_lock(&avpriv_register_devices_mutex);// 编码器串联 for (int i = 0; (out = (AVOutputFormat*)muxer_list[i]); i++) { if (prevout) prevout->next = out; prevout = out; }//实现输出列表的串联 if (outdev_list) { for (int i = 0; (out = (AVOutputFormat*)outdev_list[i]); i++) { if (prevout) prevout->next = out; prevout = out; } }//实现解码器的串联 for (int i = 0; (in = (AVInputFormat*)demuxer_list[i]); i++) { if (previn) previn->next = in; previn = in; }//实现输入列表的串联 if (indev_list) { for (int i = 0; (in = (AVInputFormat*)indev_list[i]); i++) { if (previn) previn->next = in; previn = in; } } ff_mutex_unlock(&avpriv_register_devices_mutex);} 调用avformat_open_input

调用 avformat_open_input根据输入的音视频内容构造 AVFormatContext结构体,函数功能如下:

/**打开一个流,并读取头部信息 * Open an input stream and read the header. The codecs are not opened. * The stream must be closed with avformat_close_input(). * ps可以用户提供,如果为NULL该函数会进行内存申请 * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). * May be a pointer to NULL, in which case an AVFormatContext is allocated by this * function and written into ps. * Note that a user-supplied AVFormatContext will be freed on failure. 指向要打开的多媒体文件 * @param url URL of the stream to open. 不指定,使用自动侦测 * @param fmt If non-NULL, this parameter forces a specific input format. * Otherwise the format is autodetected. * @param options A dictionary filled with AVFormatContext and demuxer-private options. * On return this parameter will be destroyed and replaced with a dict containing * options that were not found. May be NULL. * * @return 0 on success, a negative AVERROR on failure. * * @note If you want to use custom IO, preallocate the format context and set its pb field. */int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options); 调用av_dump_format打印文件信息 /** * Print detailed information about the input or output format, such as * duration, bitrate, streams, container, programs, metadata, side data, * codec and time base. * * @param ic the context to analyze * @param index index of the stream to dump information about * @param url the URL to print, such as source or destination file * @param is_output Select whether the specified context is an input(0) or output(1) */void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);

调用av_dump_format(pFmtCtx, 0, pSrcName, 0);实现对基本信息的打印,这里为了方便观看,可以自己实现一个函数,对多媒体数据进行打印。

这为了更好理解媒体信息记录的格式,自己实现了一个简单的打印接口,仅用于参考

//// Created by andrew on 2020/11/8.//#include <iostream>#include <string>extern "C" {#include <libavformat/avformat.h>#include <libavutil/log.h>#include <libavutil/dict.h>}using namespace std;// 声明一下 因为原函数是在.c中声明的结构体struct AVDictionary { int count; AVDictionaryEntry *elems;};// 打印媒体信息的简单示例void my_av_input_dump_format(AVFormatContext *ic, int index, const char *url, int is_output){ string pSrt = (is_output != 0) ? "output":"input"; cout << "音视频输入输出类型:" << pSrt <<endl; cout << "index = " << index << endl; if(is_output){ cout << "fromat name:" << ic->oformat->name << endl; }else cout << "fromat name:" << ic->iformat->name << endl; // url cout << "from :" << url << endl; //ic->metadata int i = 0; i = ic->metadata->count; for (i = 0; i < ic->metadata->count; i++){ cout << " " <<ic->metadata->elems[i].key << ":" <<ic->metadata->elems[i].value << endl; }}int main(int argc, char *argv[]){// 设置日志等级 av_log_set_level(AV_LOG_DEBUG); if(argc< 2) { av_log(NULL, AV_LOG_ERROR, "you should input media file!n"); return -1; }// 所有获取音视频信息都要首先注册 av_register_all(); int errCode = -1; AVFormatContext *pFmtCtx = NULL; const char *pSrcName = argv[1]; if((errCode = avformat_open_input(&pFmtCtx, pSrcName, NULL, NULL)) < 0){ av_log(NULL, AV_LOG_ERROR, "avformat open input failed.n"); exit(1); } //官方接口// av_dump_format(pFmtCtx, 0, pSrcName, 0); my_av_input_dump_format(pFmtCtx, 0, pSrcName, 0); //释放资源 avformat_close_input(&pFmtCtx); return 0;}

执行输出结果:

音视频输入输出类型:inputindex = 0fromat name:mov,mp4,m4a,3gp,3g2,聪慧的大山2from :/work/test/test.mp4 major_brand:isom minor_version:512 compatible_brands:isomiso2avc1mp41 track:0 artist:dbh album: comment:163 key(Don't modify):ZWxeTBkln0EQUjdDVUZQXrJzMh33POt0FgWTvjgge2X8BzXmyZaXb9C8+H2VGrdLG7XRTMrkXzzfV9VNH7sp0KlFimbjkVbsWksXY5YrzqFNXeJX1gvrBWCV+m3aYddkvy0HxucdcxCoCrYsrnzxL97sgxi0M2VHh6PREC3j6Uz4hfWkIMGhul9aszAuzEvbUUIQXSZRHgpkVW3g3oTEwqY5CexOWMIgIZAjlFIMxafAnGU8ujxA+ufq/l/r+dQMW9OmRQVt2n4Gz1t83TrPZg== title:元気满分 encoder:Lavf57.71.100[AVIOContext @ 0x55bf28f2d080] Statistics: 200364 bytes read, 0 seekslibgcov profiling error:/work/ffmpeg_doc/cmake-build-debug-coverage/src/CMakeFiles/ffmpeg_mediainfo.dir/ffmpeg_avformat/ffmpeg_mediainfo.cpp.gcda:overwriting an existing profile data with a different timestamp

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。