FFmpeg基础:获取音视频的各种编码参数

发布一下 0 0

获取视频编码参数

视频编码参数主要包括:帧率、分辨率、编码格式、码率等,对应的概念如下。

帧率(Frame Rate)

每秒显示帧数(Frames Per Second)。电影的帧率一般是25fps和29.97fps,3D游戏要保持流畅则需要30fps以上的效果。

分辨率

指视频宽高的像素数值。标准1080P的分辨率为1920×1080,帧率为60fps,也就是真高清。而最常见的网络传播的1080P高清片帧率通常为 23.976 fps。

封装格式

多媒体封装格式也称多媒体容器 (Multimedia Container),它不同于H.264、 AAC这类编码格式,它只是为多媒体编码提供了一个“外壳”,也就是所谓的视频格式。如MP4、AVI、MKV、FLV、WMA等。

码率(Bit Rate)

指视频或音频文件在单位时间内使用的数据流量(单位通常是Kbps也就是千比特每秒)。通常2000kbps~3000kbps就已经足以将画质效果表现到极致了。码率参数与视频文件最终体积大小有直接性的关系。

编码格式
所谓视频编码方式就是指通过压缩技术,将原始视频格式的文件转换成另一种视频格式文件的方式。视频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264。

通过ffmpeg获取视频编码参数的方法如下所示:

#include "libavutil/log.h"#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"//按照固定格式打印static void print_fps(double d, const char *postfix){	uint64_t v = lrintf(d * 100);	if (!v)		av_log(NULL, AV_LOG_INFO, "%1.4f %s", d, postfix);	else if (v % 100)		av_log(NULL, AV_LOG_INFO, "%3.2f %s", d, postfix);	else if (v % (100 * 1000))		av_log(NULL, AV_LOG_INFO, "%1.0f %s", d, postfix);	else		av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);}int main(int argc, char* argv[]){	int ret;	int streams;	char buf[256];	AVFormatContext *fmt_ctx = NULL;	AVCodecContext *avctx = NULL;	const AVInputFormat *fmt = NULL;		//设置日志的输出级别	av_log_set_level(AV_LOG_INFO);		//打开视频的上下文	//@1音视频上下文 	//@2文件路径 	//@3文件格式(不指定根据文件名判断)	//@4获取配置项的字典	ret = avformat_open_input(&fmt_ctx, "./test.mp4", fmt, NULL);	if (ret < 0)	{		av_log(NULL, AV_LOG_ERROR, "Can't open file:%s\n", av_err2str(ret));		return -1;	}	//获取封装格式	const char* format_name = fmt_ctx->iformat->name;	//通过上下文获取视频时长	if (fmt_ctx->duration != AV_NOPTS_VALUE)	{		int64_t hours, mins, secs, us;		int64_t duration = fmt_ctx->duration + (fmt_ctx->duration <= INT64_MAX - 5000 ? 5000 : 0);		secs = duration / AV_TIME_BASE;		us = duration % AV_TIME_BASE;		mins = secs / 60;		secs %= 60;		hours = mins / 60;		mins %= 60;		av_log(NULL, AV_LOG_INFO, "duration:  %02"PRId64":%02"PRId64":%02"PRId64".%02"PRId64"\n", hours, mins, secs,			(100 * us) / AV_TIME_BASE);	}	else 	{		av_log(NULL, AV_LOG_INFO, "N/A");	}	//查看视频文件中流的个数	streams = fmt_ctx->nb_streams;	av_log(NULL, AV_LOG_INFO, "file has:%d streams\n",streams);	//查看流的类型,判断是视频流还是音频流	for (int index = 0; index < streams; ++index)	{		const AVStream *stream = fmt_ctx->streams[index];		if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)		{			av_log(NULL, AV_LOG_INFO, "streams %d is Video Stream\n",index);		}		else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)		{			av_log(NULL, AV_LOG_INFO, "streams %d is Audio Stream\n",index);		}	}	//获取视频帧率fps	const AVStream *stream = fmt_ctx->streams[0];	double fps = av_q2d(stream->avg_frame_rate);	print_fps(fps, "fps\n");	//获取流的类型名称(video/audio)	avctx = avcodec_alloc_context3(NULL);	ret = avcodec_parameters_to_context(avctx, stream->codecpar);	const char* codec_type = av_get_media_type_string(avctx->codec_type);	//获取视频编码类型(h264/h265)	const char*codec_name = avcodec_get_name(avctx->codec_id);	av_log(NULL, AV_LOG_INFO, "stream type:%s, stream codec:%s\n", codec_type,codec_name);	//获得视频的码率	int bitrate = avctx->bit_rate;	av_log(NULL, AV_LOG_INFO,"%"PRId64" kb/s\n", bitrate / 1000);	//获取视频的分辨率	int width = avctx->width;	int height = avctx->height;	av_log(NULL, AV_LOG_INFO, "%dx%d\n", width, height);	avcodec_free_context(&avctx);	//关闭上下文	avformat_close_input(&fmt_ctx);	getchar();}

相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】

音视频免费学习地址:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

FFmpeg基础:获取音视频的各种编码参数

获取音频编码参数

音频编码参数主要包括:声道数、码率、采样率、采样位数等,对应的概念如下。
声道数
现在主要有单声道和双声道之分。双声道又称为立体声,在硬件中要占两条线路,音质、音色好,但立体声数字化后所占空间比单声道多一倍。

码率
比特率也叫码率,指音乐每秒播放的数据量,单位用bit表示。一般mp3在128比特率左右为益。

采样率
指每秒钟取得声音样本的次数,22050 的采样频率是常用的,44100已是CD音质。为了保证声音不失真,采样频率应该在40kHz左右。

采样位数

采样位数也叫采样大小或量化位数。它是用来衡量声音波动变化的一个参数,也就是声卡的分辨率或可以理解为声卡处理声音的解析度。它的数值越大,分辨率也就越高,常见的声卡主要有8位和16位两种。

通过ffmpeg获取音频编码参数方法如下所示:

#include "libavutil/log.h"#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"//按照固定格式打印static void print_fps(double d, const char *postfix){	uint64_t v = lrintf(d * 100);	if (!v)		av_log(NULL, AV_LOG_INFO, "%1.4f %s", d, postfix);	else if (v % 100)		av_log(NULL, AV_LOG_INFO, "%3.2f %s", d, postfix);	else if (v % (100 * 1000))		av_log(NULL, AV_LOG_INFO, "%1.0f %s", d, postfix);	else		av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);}int main(int argc, char* argv[]){	int ret;	int streams;	char buf[256];	AVFormatContext *fmt_ctx = NULL;	AVCodecContext *avctx = NULL;	const AVInputFormat *fmt = NULL;		//设置日志的输出级别	av_log_set_level(AV_LOG_INFO);		//打开视频的上下文	//@1音视频上下文 	//@2文件路径 	//@3文件格式(不指定根据文件名判断)	//@4获取配置项的字典	ret = avformat_open_input(&fmt_ctx, "./test.mp4", fmt, NULL);	if (ret < 0)	{		av_log(NULL, AV_LOG_ERROR, "Can't open file:%s\n", av_err2str(ret));		return -1;	}	//获取封装格式	const char* format_name = fmt_ctx->iformat->name;	//通过上下文获取视频时长	if (fmt_ctx->duration != AV_NOPTS_VALUE)	{		int64_t hours, mins, secs, us;		int64_t duration = fmt_ctx->duration + (fmt_ctx->duration <= INT64_MAX - 5000 ? 5000 : 0);		secs = duration / AV_TIME_BASE;		us = duration % AV_TIME_BASE;		mins = secs / 60;		secs %= 60;		hours = mins / 60;		mins %= 60;		av_log(NULL, AV_LOG_INFO, "duration:  %02"PRId64":%02"PRId64":%02"PRId64".%02"PRId64"\n", hours, mins, secs,			(100 * us) / AV_TIME_BASE);	}	else 	{		av_log(NULL, AV_LOG_INFO, "N/A");	}	//查看视频文件中流的个数	streams = fmt_ctx->nb_streams;	av_log(NULL, AV_LOG_INFO, "file has:%d streams\n",streams);	//查看流的类型,判断是视频流还是音频流	for (int index = 0; index < streams; ++index)	{		const AVStream *stream = fmt_ctx->streams[index];		if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)		{			av_log(NULL, AV_LOG_INFO, "streams %d is Video Stream\n",index);		}		else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)		{			av_log(NULL, AV_LOG_INFO, "streams %d is Audio Stream\n",index);		}	}	//获取音频流的类型名称(video/audio)	const AVStream *audio_stream = fmt_ctx->streams[1];	avctx = avcodec_alloc_context3(NULL);	ret = avcodec_parameters_to_context(avctx, audio_stream->codecpar);	const char* audio_codec_type = av_get_media_type_string(avctx->codec_type);	//获取音频流的编码类型	const char*audio_codec_name = avcodec_get_name(avctx->codec_id);	av_log(NULL, AV_LOG_INFO, "audio stream type:%s, stream codec:%s\n", audio_codec_type, audio_codec_name);	//获得音频流的码率	int audio_bitrate = avctx->bit_rate;	av_log(NULL, AV_LOG_INFO, "%"PRId64" kb/s\n", audio_bitrate / 1000);	//获得音频的采样率	int sample_rate = avctx->sample_rate;	av_log(NULL, AV_LOG_INFO, "%dHZ\n",sample_rate);	//采样位数	int sample_bits = avctx->bits_per_coded_sample;	av_log(NULL, AV_LOG_INFO, "%d\n", sample_bits);	//获取音频的通道数量	char channel_buf[512];	ret = av_channel_layout_describe(&avctx->ch_layout, channel_buf, sizeof(channel_buf));	avcodec_free_context(&avctx);	//关闭上下文	avformat_close_input(&fmt_ctx);	getchar();}

除了上面的方法之外,ffmpeg还提供了一个直接输出视频文件编码参数的接口,该接口可以直接输出音视频信息到终端,对应的接口调用方法如下:

#include "libavutil/log.h"#include "libavformat/avformat.h"#include "libavcodec/avcodec.h"int main(int argc, char* argv[]){	int ret;	int streams;	char buf[256];	AVFormatContext *fmt_ctx = NULL;	AVCodecContext *avctx = NULL;	const AVInputFormat *fmt = NULL;		//设置日志的输出级别	av_log_set_level(AV_LOG_INFO);		//打开视频的上下文	//@1音视频上下文 	//@2文件路径 	//@3文件格式(不指定根据文件名判断)	//@4获取配置项的字典	ret = avformat_open_input(&fmt_ctx, "./test.mp4", fmt, NULL);	if (ret < 0)	{		av_log(NULL, AV_LOG_ERROR, "Can't open file:%s\n", av_err2str(ret));		return -1;	}	//输出视频信息参数	//@1上下文	//@2文件索引	//@3文件路径	//@4输入流还是输出流	av_dump_format(fmt_ctx, 0, "./test.mp4", 0);	//关闭上下文	avformat_close_input(&fmt_ctx);	getchar();}

输出结果如下所示:

FFmpeg基础:获取音视频的各种编码参数


原文链接:FFmpeg基础:获取音视频的各种编码参数_ffmpeg 查看视频编码_码农飞飞的博客-CSDN博客

版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除

本文地址:http://0561fc.cn/206991.html