C语言结合ffmpeg打印音视频信息

一、通过此文可以得到什么

通过此练习:

1、知道了如何计算一个音频和视频的播放时间;

2、知道了音视频解码的思路的大体流程,之后无非就是在这个流程上进行扩充细节;

3、知道了如何通过C语言或者C++编程语言结合ffmpeg拿到一些音视频的关键信息,例如:帧率等;

二、实现思路

三、实现效果

zhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy$ make

make all

make[1]: 进入目录“/data/project/VSCProject/ffmpegStudy/src”

Compiling main.cpp to main.o ..

cp hello /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$ ./hello

Hello World !

decode video fileName=/home/zhenghui/视频/1080P.mp4

[NULL @ 0x5654cc332d80] Opening '/home/zhenghui/视频/1080P.mp4' for reading

[file @ 0x5654cc333380] Setting default whitelist 'file,crypto,data'

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Format mov,mp4,m4a,3gp,3g2,mj2 probed with size=2048 and score=100

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] ISO: File Type Major Brand: isom

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Unknown dref type 0x206c7275 size 12

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Processing st: 0, edit list 0 - media time: 1072, duration: 3621888

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Offset DTS by 1072 to make first pts zero.

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Setting codecpar->delay to 2 for stream st: 0

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Unknown dref type 0x206c7275 size 12

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Processing st: 1, edit list 0 - media time: 0, duration: 9990149

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 29.916667 0.006250

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 30.000000 0.000066

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 60.000000 0.000265

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 120.000000 0.001061

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 240.000000 0.004244

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 29.970030 0.000868

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] rfps: 59.940060 0.003473

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] Before avformat_find_stream_info() pos: 87425182 bytes read:315205 seeks:1 nb_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] Format yuv420p chosen by get_format().

[h264 @ 0x5654cc3340c0] Reinit context to 1920x1088, pix_fmt: yuv420p

[h264 @ 0x5654cc3340c0] no picture

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] All info found

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5654cc332d80] After avformat_find_stream_info() pos: 53231 bytes read:393067 seeks:2 frames:4

video_index=0

audio_index=1

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/zhenghui/视频/1080P.mp4':

Metadata:

major_brand : isom

minor_version : 512

compatible_brands: isomiso2avc1mp41

encoder : Lavf58.29.100

description : Packed by Bilibili XCoder v2.0.2

Duration: 00:03:46.53, start: 0.000000, bitrate: 3087 kb/s

Stream #0:0[0x1](und), 3, 1/16000: Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(progressive, left), 1920x1080 (1920x1088) [SAR 1:1 DAR 16:9], 0/1, 2951 kb/s, 30 fps, 30 tbr, 16k tbn (default)

Metadata:

handler_name : VideoHandler

vendor_id : [0][0][0][0]

Stream #0:1[0x2](und), 1, 1/44100: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)

Metadata:

handler_name : SoundHandler

vendor_id : [0][0][0][0]

media name =/home/zhenghui/视频/1080P.mp4

stream number: 2

media average ratio: 3015 kbps

media total time: 0:3:46

######## Video info: ########

stream index : 0

fps:29.999914 fps

video codec : H264

video_time : 00:03:46

######## Audio info: ########

stream index : 1

stream sample_rate : 44100 Hz

stream format : AV_SAMPLE_FMT_FLTP

channels number:2

audio codec:AAC

audio_time : 00:03:46

[AVIOContext @ 0x5654cc33b7c0] Statistics: 393067 bytes read, 2 seeks

zhenghui@zh-pc:/data/project/VSCProject/ffmpegStudy$

四、实现源代码 

视频教程

#include <iostream>

#include <stdio.h>

#ifdef __cplusplus //表示是一个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>

#ifdef __cplusplus

}

#endif

//g++ -I ../include/ hello_world.cpp -o hello_world -L../lib/ -lavcodec -lavdevice -lavfilter -lavformat -lavutil

void decode()

{

char *fileName = "/home/zhenghui/视频/1080P.mp4";

printf("decode video fileName=%s \n",fileName);

int ret = 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、获取音频流和视频流的索引

int video_index = -1;

int audio_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);

//打印媒体文件url

printf("media name =%s \n",ctx->url);

//打印流数量

printf("stream number: %d \n",ctx->nb_streams);

//打印码率

printf("media average ratio: %lld kbps\n",(int64_t)(ctx->bit_rate/1024));

//打印时长

int total_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("media total time: %d:%d:%d \n",hour,minute,second);

//老版本查找流索引

for(int i = 0;i < ctx->nb_streams;i++){

AVStream *av_stream = ctx->streams[i];

//判断流是什么类型

//视频流

if( AVMEDIA_TYPE_VIDEO == av_stream->codecpar->codec_type)

{

printf("######## Video info: ######## \n");

// 流索引

printf("stream index : %d \n",av_stream->index);

//帧率

printf("fps:%lf fps\n",av_q2d(av_stream->avg_frame_rate));

if(AV_CODEC_ID_MPEG4 == av_stream->codecpar->codec_id)

{

printf("video codec : MPEG4 \n");

}

else if(AV_CODEC_ID_H264 == av_stream->codecpar->codec_id)

{

printf("video codec : H264 \n");

}else

{

printf("video codec other value=%d \n", av_stream->codecpar->codec_id);

}

//获取视频总时长

if(AV_NOPTS_VALUE != av_stream->duration)

{

int video_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("audio duration unknown ! \n");

}

}

//音频流

else if(AVMEDIA_TYPE_AUDIO == av_stream->codecpar->codec_type)

{

printf("######## Audio info: ######## \n");

// 流索引

printf("stream index : %d \n",av_stream->index);

// 音频编解码器的采样率 单位Hz

printf("stream sample_rate : %d Hz \n",av_stream->codecpar->sample_rate);

//音频采样格式

if(AV_SAMPLE_FMT_FLTP == av_stream->codecpar->format)

{

printf("stream format : AV_SAMPLE_FMT_FLTP \n");

}

else if(AV_SAMPLE_FMT_S16P == av_stream->codecpar->format)

{

printf("stream format : AV_SAMPLE_FMT_S16P \n");

}else{

printf("stream format : other; value=%d \n",av_stream->codecpar->format);

}

// 音频信道数目

printf("channels number:%d \n",av_stream->codecpar->channels);

//音频压缩编码格式

if(AV_CODEC_ID_AAC == av_stream->codecpar->codec_id)

{

printf("audio codec:AAC \n");

}else if(AV_CODEC_ID_MP3 == av_stream->codecpar->codec_id)

{

printf("audio codec:MP3 \n");

}else{

printf("audio codec : other; value=%d \n",av_stream->codecpar->codec_id);

}

//获取视频总时长

if(AV_NOPTS_VALUE != av_stream->duration)

{

int audio_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("audio duration unknown ! \n");

}

audio_index = i;

}

}

if(ctx)

avformat_close_input(&ctx);

}

int main() {

// 设置控制台输出级别

av_log_set_level(AV_LOG_DEBUG);

// // 打印输出字符串Hello World !

av_log(NULL, AV_LOG_DEBUG, "%s", "Hello World !\n");

decode();

return 0;

}

到此这篇关于C语言结合ffmpeg打印音视频信息的文章就介绍到这了,更多相关C语言打印音视频信息内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

以上是 C语言结合ffmpeg打印音视频信息 的全部内容, 来源链接: utcz.com/p/248066.html

回到顶部