文章目录

  • 获取视频编码参数
  • 获取音频编码参数

上一篇文章中介绍了音视频的各种编码参数的概念,这里介绍一下如何通过ffmpeg库获取一个视频文件的各种音视频编码参数。在对视频文件进行处理和转码的时候这些参数很重要。

获取视频编码参数

视频编码参数主要包括:帧率、分辨率、编码格式、码率等,对应的概念如下。
帧率(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);elseav_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);}}//获取视频帧率fpsconst 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();
}

获取音频编码参数

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

码率
比特率也叫码率,指音乐每秒播放的数据量,单位用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);elseav_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基础:获取音视频的各种编码参数相关推荐

  1. 音视频编解码 -- 编码参数 CRF

    之前多多少少接触过一些编解码参数,CRF 参数也用过,但是最近在和朋友们聊天时,说到使用 FFMPEG 过程中碰到 CRF 参数,以及具体作用流程,这个之前一直没有跟踪过,也没有详细记录过,所以吊起了 ...

  2. FFmpeg之获取音视频信息(二十八)

    1.test.c #include <stdio.h> #include <libavutil/log.h> #include <libavformat/avformat ...

  3. FFmpeg学习(音视频理论知识)

    文章目录 1. 音视频理论知识 1.1 基本概念 1.1.1 音视频必备的基本概念 常用的视频封装格式 常用的视频编码器 常用的音频编程器: 视频流 裸数据YUV 1.1.2 音视频常见处理 采集 处 ...

  4. FFmpeg 工具:音视频开发都用它,快@你兄弟来看丨音视频工具

    (本文基本逻辑:ffmpeg 常用命令介绍 → ffplay 常用命令介绍 → ffprobe 常用命令介绍) 从事音视频开发的程序员几乎都应该知道或使用过 FFmpeg.FFmpeg 是一个开源软件 ...

  5. android音视频工程师,音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)...

    ## 音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源) ## 视音频编辑器 ## 前言 有时候我们想对音视频进行加工处理,比如视频编辑.添加字幕.裁剪等功能处 ...

  6. 使用FFmpeg命令处理音视频

    文章目录 前言 一.ffprobe相关命令 1.使用ffprobe查看音频文件的信息 2.使用ffprobe查看视频文件的信息 二.ffplay相关命令 1.基本的ffplay命令 2.音视频同步命令 ...

  7. 基于FFmpeg 实现RTSP, 音视频编解码,视频流添加文字,音视频合成MP4

    前言: 最近闲这没事,整理了一下之前开发过的音视频编解码库,主要基于ffmpeg,实现音视频的编解码.视频流添加文字,音视频同步到MP4等功能.有需要的小伙伴可以参考参考,如果写的有什么不对的地方,欢 ...

  8. Win10 使用python和ffmpeg批量合并音视频

    将m4a文件和mp4文件合并为MP4 具体代码如下 import os,sys import io import subprocess #在vscode运行时输出内容含中文不乱码,其他软件运行未知 s ...

  9. (二)音视频:MediaCodec编码桌面信息 完整Demo 进一步理解H264

    (一)音视频:解码H264文件流程 渲染和拿到解码后源数据YUV 完整Demo] (二)音视频:MediaCodec编码桌面信息 完整Demo 进一步理解H264 (三)音视频:解析H264 SPS ...

最新文章

  1. 《AI系统周刊》第5期:Cerebras发布可运行120万亿参数AI模型的CS-2芯片
  2. oracle中treat函数,Oracle 函数概览
  3. python2 队列的使用_python双端队列原理、实现与使用方法分析
  4. Spring Cloud 服务安全连接
  5. asp.net mvc 正常支持Fckeditor编辑器
  6. vim 编辑器命令整理
  7. JavaScript抽象类及Class.create备忘
  8. OAM深入解读:使用OAM定义与管理Kubernetes内置Workload
  9. MP 启动注入 SQL 原理分析
  10. 如何做到 jQuery-free?
  11. Hadoop介绍及最新稳定版Hadoop 2.4.1下载地址及单节点安装
  12. 电脑安装ubuntu linux操作系统
  13. C语言连接MySql数据库(CodeBlocks)
  14. Python自学电子书大全
  15. 无套路,鬼灭之刃同人游戏
  16. 股权和更高的薪资应该选哪个呢?
  17. STM32F105、107RB使用外部晶振8M时配置外设时钟为72M
  18. Mac系统如何进入mysql
  19. jvm attach原理分析总结~~~
  20. 天猫平台基础规则(一)

热门文章

  1. 广州DNA实验室功能区大改造
  2. 爬虫后如何进行数据存储和进行数据分析
  3. javascript添加空格
  4. Excel中把一列数据转换成逗号隔开的一行
  5. iOS 获取网络图片的尺寸
  6. 2004年最耐人寻味的言辞,最幽默的戏谑,最无奈的表白与最动听的情话。
  7. 谷歌联合创始人拉里·佩奇语录
  8. 电子工程师十大离职原因!
  9. Flink-SQL源码解读(一)window算子的创建的源码分析
  10. Carsim中路面附着系数设定