ffmpeg解码之使用C语言打印音视频信息

一、通过此文可以得到什么
通过此练习:
1、知道了如何计算一个音频和视频的播放时间;2、知道了音视频解码的思路的大体流程,之后无非就是在这个流程上进行扩充细节;3、知道了如何通过C语言或者C++编程语言结合ffmpeg拿到一些音视频的关键信息,例如:帧率等;二、实现思路关注+私信扣1,无偿分享2022最新最全学习提升资料包,资料内容包括《Andoird音视频开发必备手册+音视频最新学习视频+大厂面试真题+2022最新学习路线图+项目实战源码》(C/C++,Linux,FFmpeg,webRTC,rtmp,hls,rtsp,ffplay,srs)等等
三、实现效果zhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy\(makemakeallmake[1]:进入目录“/data/project/VSCProject/ffmpegStudy/src”Compilingmain.cpptomain.o..cphello/data/project/VSCProject/ffmpegStudy/src/../#make【hello】finish!!! make[1]:离开目录“/data/project/VSCProject/ffmpegStudy/src”zhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy\)zhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy\(./helloHelloWorld!decodevideofileName=/home/zhenghui/视频/1080P.mp4[NULL@0x5654cc332d80]Opening'/home/zhenghui/视频/1080P.mp4'forreading[file@0x5654cc333380]Settingdefaultwhitelist'file,crypto,data'[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Formatmov,mp4,m4a,3gp,3g2,mj2probedwithsize=2048andscore=100[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]ISO:FileTypeMajorBrand:isom[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Unknowndreftype0x206c7275size12[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Processingst:0,editlist0-mediatime:1072,duration:3621888[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]OffsetDTSby1072tomakefirstptszero.[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Settingcodecpar->delayto2forstreamst:0[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Unknowndreftype0x206c7275size12[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Processingst:1,editlist0-mediatime:0,duration:9990149[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:29.9166670.006250[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:30.0000000.000066[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:60.0000000.000265[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:120.0000000.001061[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:240.0000000.004244[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:29.9700300.000868[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]rfps:59.9400600.003473[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Beforeavformat_find_stream_info()pos:87425182bytesread:315205seeks:1nb_streams:2[h264@0x5654cc3340c0]nal_unit_type:7(SPS),nal_ref_idc:3[h264@0x5654cc3340c0]nal_unit_type:8(PPS),nal_ref_idc:3[h264@0x5654cc3340c0]nal_unit_type:7(SPS),nal_ref_idc:3[h264@0x5654cc3340c0]nal_unit_type:8(PPS),nal_ref_idc:3[h264@0x5654cc3340c0]nal_unit_type:6(SEI),nal_ref_idc:0[h264@0x5654cc3340c0]nal_unit_type:5(IDR),nal_ref_idc:3[h264@0x5654cc3340c0]Formatyuv420pchosenbyget_format().[h264@0x5654cc3340c0]Reinitcontextto1920x1088,pix_fmt:yuv420p[h264@0x5654cc3340c0]nopicture[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Allinfofound[mov,mp4,m4a,3gp,3g2,mj2@0x5654cc332d80]Afteravformat_find_stream_info()pos:53231bytesread:393067seeks:2frames:4video_index=0audio_index=1Input#0,mov,mp4,m4a,3gp,3g2,mj2,from'/home/zhenghui/视频/1080P.mp4':Metadata:major_brand:isomminor_version:512compatible_brands:isomiso2avc1mp41encoder:Lavf58.29.100description:PackedbyBilibiliXCoderv2.0.2Duration:00:03:46.53,start:0.000000,bitrate:3087kb/sStream#0:0[0x1](und),3,1/16000:Video:h264(High),1referenceframe(avc1/0x31637661),yuv420p(progressive,left),1920x1080(1920x1088)[SAR1:1DAR16:9],0/1,2951kb/s,30fps,30tbr,16ktbn(default)Metadata:handler_name:VideoHandlervendor_id:[0][0][0][0]Stream#0:1[0x2](und),1,1/44100:Audio:aac(LC)(mp4a/0x6134706D),44100Hz,stereo,fltp,128kb/s(default)Metadata:handler_name:SoundHandlervendor_id:[0][0][0][0]medianame=/home/zhenghui/视频/1080P.mp4streamnumber:2mediaaverageratio:3015kbpsmediatotaltime:0:3:46########Videoinfo:########streamindex:0fps:29.999914fpsvideocodec:H264video_time:00:03:46########Audioinfo:########streamindex:1streamsample_rate:44100Hzstreamformat:AV_SAMPLE_FMT_FLTPchannelsnumber:2audiocodec:AACaudio_time:00:03:46[AVIOContext@0x5654cc33b7c0]Statistics:393067bytesread,2seekszhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy\)四、实现源代码
#include<iostream>#include<stdio.h>#ifdefcplusplus//表示是一个c++程序extern“C”{#endif#include<libavdevice/avdevice.h>#include<libavutil/frame.h>#include<libavutil/imgutils.h>#include<libavutil/log.h>#include<libswscale/swscale.h>#include<libavformat/avformat.h>#include<libavcodec/avcodec.h>#ifdefcplusplus}#endif//g++-I../include/hello_world.cpp-ohello_world-L../lib/-lavcodec-lavdevice-lavfilter-lavformat-lavutilvoiddecode(){char*fileName=“/home/zhenghui/视频/1080P.mp4”;printf(“decodevideofileName=%s\n”,fileName);intret=0;//1、分配解复用器上下文AVFormatContext*ctx=NULL;ctx=avformat_alloc_context();//2、根据url打开本地文件或网络流ret=avformat_open_input(&ctx,fileName,NULL,NULL);if(ret<0){printf(“打开%s失败!\n”,fileName);return;}//3、读取媒体的部分数据包,获取码流信息ret=avformat_find_stream_info(ctx,NULL);if(ret<0){printf(“获取码流信息失败!\n”);return;}//3、获取音频流和视频流的索引intvideo_index=-1;intaudio_index=-1;video_index=av_find_best_stream(ctx,AVMEDIA_TYPE_VIDEO,-1,-1,NULL,0);printf(“video_index=%d\n”,video_index);audio_index=av_find_best_stream(ctx,AVMEDIA_TYPE_AUDIO,-1,-1,NULL,0);printf(“audio_index=%d\n”,audio_index);//打印流信息av_dump_format(ctx,0,fileName,0);//打印媒体文件urlprintf(“medianame=%s\n”,ctx->url);//打印流数量printf(“streamnumber:%d\n”,ctx->nb_streams);//打印码率printf(“mediaaverageratio:%lldkbps\n”,(int64_t)(ctx->bit_rate/1024));//打印时长inttotal_seconds,hour,minute,second;//ctx->duration的单位是微妙,先转换成秒,再进行转换成其他的时间单位就比较简单了total_seconds=(ctx->duration)/AV_TIME_BASE;hour=total_seconds/3600;minute=(total_seconds%3600)/60;second=(total_seconds%60);//文件总时长printf(“mediatotaltime:%d:%d:%d\n”,hour,minute,second);//老版本查找流索引for(inti=0;i<ctx->nb_streams;i++){AVStream*av_stream=ctx->streams[i];//判断流是什么类型//视频流if(AVMEDIA_TYPE_VIDEO==av_stream->codecpar->codec_type){printf(“########Videoinfo:########\n”);//流索引printf(“streamindex:%d\n”,av_stream->index);//帧率printf(“fps:%lffps\n”,av_q2d(av_stream->avg_frame_rate));if(AV_CODEC_ID_MPEG4==av_stream->codecpar->codec_id){printf(“videocodec:MPEG4\n”);}elseif(AV_CODEC_ID_H264==av_stream->codecpar->codec_id){printf(“videocodec:H264\n”);}else{printf(“videocodecothervalue=%d\n”,av_stream->codecpar->codec_id);}//获取视频总时长if(AV_NOPTS_VALUE!=av_stream->duration){intvideo_time=av_stream->duration*av_q2d(av_stream->time_base);printf(“video_time:%02d:%02d:%02d\n”,(video_time/3600),(video_time%3600)/60,(video_time%60));}else{printf(“audiodurationunknown!\n”);}}//音频流elseif(AVMEDIA_TYPE_AUDIO==av_stream->codecpar->codec_type){printf(“########Audioinfo:########\n”);//流索引printf(“streamindex:%d\n”,av_stream->index);//音频编解码器的采样率单位Hzprintf(“streamsample_rate:%dHz\n”,av_stream->codecpar->sample_rate);//音频采样格式if(AV_SAMPLE_FMT_FLTP==av_stream->codecpar->format){printf(“streamformat:AV_SAMPLE_FMT_FLTP\n”);}elseif(AV_SAMPLE_FMT_S16P==av_stream->codecpar->format){printf(“streamformat:AV_SAMPLE_FMT_S16P\n”);}else{printf(“streamformat:other;value=%d\n”,av_stream->codecpar->format);}//音频信道数目printf(“channelsnumber:%d\n”,av_stream->codecpar->channels);//音频压缩编码格式if(AV_CODEC_ID_AAC==av_stream->codecpar->codec_id){printf(“audiocodec:AAC\n”);}elseif(AV_CODEC_ID_MP3==av_stream->codecpar->codec_id){printf(“audiocodec:MP3\n”);}else{printf(“audiocodec:other;value=%d\n”,av_stream->codecpar->codec_id);}//获取视频总时长if(AV_NOPTS_VALUE!=av_stream->duration){intaudio_time=av_stream->duration*av_q2d(av_stream->time_base);printf(“audio_time:%02d:%02d:%02d\n”,(audio_time/3600),(audio_time%3600)/60,(audio_time%60));}else{printf(“audiodurationunknown!\n”);}audio_index=i;}}if(ctx)avformat_close_input(&ctx);}intmain(){//设置控制台输出级别av_log_set_level(AV_LOG_DEBUG);////打印输出字符串HelloWorld!av_log(NULL,AV_LOG_DEBUG,“%s”,“HelloWorld!\n”);decode();return0;}