FFmpeg获取音视频流信息
文章目录
- 前言
- 一、需求
- 二、源码
- 三、运行结果
前言
本文记录用 FFmpeg 获取视频流+音频流的信息(编码格式、分辨率、帧率、播放时长…),所用的工程基于上个博客编译成功的工程:使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c
一、需求
我们经常需要知道一个媒体文件所包含的媒体流的信息,比如文件格式、播放时长、码率、视音频编码格式,视频分辨率,帧率,音频属性等信息。
如何使用 FFmpeg API 获取这些信息呢?
- 媒体容器封装格式
- 文件播放时长
- 文件平均码率(视频+音频)
- 视频属性(编码器名称、视频分辨率、帧率、编码码率)
- 音频属性(编码器名称、采样率、声道数、编码码率)
二、源码
ffmepg.h 文件中添加我们自定义的结构体,我们后面会利用 ffmepg 的 API 函数将音视频流信息填充到各个字段:
typedef struct __AVGeneralMediaInfo {char filepath[1024]; // 文件路径int64_t duration; // 时长,单位:微秒 time_base:1,000,000int64_t totalBitrate; // 总码率int videoStreamIndex; // 视频流索引int audioStreamIndex; // 音频流索引char videoCodecName[256]; int width; // 视频宽int height; // 视频高double frameRate; // 视频帧率char audioCodecName[256];int sampleRate; // 采样率int channels; // 声道数
} AVGeneralMediaInfo;void get_avgeneral_mediainfo(AVGeneralMediaInfo* avmi, const char* filepath);
ffmepg.c 文件中添加获取音视频流的基本信息的接口
// 封装:查找解码器
// type:[0:video, 1:audio]
void get_decoder_name(AVGeneralMediaInfo *avmi, AVFormatContext *avFmtctx, int type)
{int nindex = -1;if (type == 0) { // videonindex = avmi->videoStreamIndex;}else if (type == 1) { // aduionindex = avmi->audioStreamIndex;}if (nindex >= 0) {AVCodecContext* avcodecCtx = NULL;AVCodec *avcodec = NULL;avcodecCtx = avFmtctx->streams[nindex]->codec;avcodec = avcodec_find_decoder(avcodecCtx->codec_id);if (type == 0) { // videostrcpy(avmi->videoCodecName, avcodec->name);printf("videoCodecName = %s\n", avmi->videoCodecName);}else if (type == 1) {strcpy(avmi->audioCodecName, avcodec->long_name);printf("audioCodecName = %s\n", avmi->audioCodecName);}}
}// 获取音视频流的基本信息
void get_avgeneral_mediainfo(AVGeneralMediaInfo *avmi, const char *filepath)
{int ret = -1;int i = 0;AVFormatContext* avFmtCtx = NULL; // 大管家if (avmi == NULL || filepath == NULL) {return;}// 1.打开音视频文件或网络流ret = avformat_open_input(&avFmtCtx, filepath, NULL, NULL);if (ret < 0) {printf("error avformat_open_input:%s\n", filepath);return;}// 2.打印音视频流信息av_dump_format(avFmtCtx, 0, filepath, 0);// 3.继续深入,读取更多的字段avmi->duration = avFmtCtx->duration; // 时长avmi->totalBitrate = avFmtCtx->bit_rate; // 总码率printf("duration = %lld, totalBitrate = %lld\n", avmi->duration, avmi->totalBitrate);// 分别读取音视频流,更多的参数for (i = 0; i < avFmtCtx->nb_streams; i++) {AVStream* avstmp = avFmtCtx->streams[i]; // 拿到具体的一路流if (avstmp->codec->codec_type == AVMEDIA_TYPE_VIDEO) {avmi->videoStreamIndex = i;avmi->width = avstmp->codec->width;avmi->height = avstmp->codec->height;// 视频帧率:avg_frame_rate// fps:frames per secondif (avstmp->avg_frame_rate.num != 0 && avstmp->avg_frame_rate.den != 0) {avmi->frameRate = (double)avstmp->avg_frame_rate.num / (double)avstmp->avg_frame_rate.den;}printf("width = %d, height = %d, frameRate = %.3lf\n", avmi->width,avmi->height,avmi->frameRate);}else if (avstmp->codec->codec_type == AVMEDIA_TYPE_AUDIO) {avmi->audioStreamIndex = i;avmi->channels = avstmp->codec->channels;avmi->sampleRate = avstmp->codec->sample_rate;printf("channel = %d, sampleRate = %d\n", avmi->channels, avmi->sampleRate);}}// 读取具体的解码器// avcodec_find_decoder()// 视频解码器get_decoder_name(avmi, avFmtCtx, 0);// 音频解码器get_decoder_name(avmi, avFmtCtx, 1);// releaseavformat_close_input(&avFmtCtx);
}
ffmpeg431_test.cpp 文件内容如下:
#include <iostream>
extern "C"
{
#include "ffmpeg.h"
}int main(int argc, char** argv)
{AVGeneralMediaInfo* avmi = new AVGeneralMediaInfo();if (avmi) {get_avgeneral_mediainfo(avmi, "SampleVideo_1280x720_20mb.mp4");delete avmi;avmi = NULL;}
}
三、运行结果
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'SampleVideo_1280x720_20mb.mp4':Metadata:major_brand : isomminor_version : 512compatible_brands: isomiso2avc1mp41creation_time : 1970-01-01T00:00:00.000000Zencoder : Lavf53.24.2Duration: 00:01:57.31, bitrate: N/AStream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1280x720, 1048 kb/s, 25 fps, 25 tbr, 12800 tbn (default)Metadata:creation_time : 1970-01-01T00:00:00.000000Zhandler_name : VideoHandlerStream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 6 channels, 383 kb/s (default)Metadata:creation_time : 1970-01-01T00:00:00.000000Zhandler_name : SoundHandler
duration = 117312000, totalBitrate = 0
width = 1280, height = 720, frameRate = 25.000
channel = 6, sampleRate = 48000
videoCodecName = h264
audioCodecName = AAC (Advanced Audio Coding)
使用 MediaInfo 打开 SampleVideo_1280x720_20mb.mp4 可以看到与上面打印对应的参数
我的qq:2442391036,欢迎交流!
相关文章:

FFmpeg获取音视频流信息
文章目录 前言一、需求二、源码三、运行结果 前言 本文记录用 FFmpeg 获取视频流音频流的信息(编码格式、分辨率、帧率、播放时长…),所用的工程基于上个博客编译成功的工程:使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c 一、需求…...
编程语言的走向又将如何呢?
编程语言的未来? 随着科技的飞速发展,编程语言在计算机领域中扮演着至关重要的角色。它们是软件开发的核心,为程序员提供了与机器沟通的桥梁。那么,在技术不断进步的未来,编程语言的走向又将如何呢? 1. 更…...
基于SpringBoot的电影评论网站
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的电影评论网站,java项目…...
粒子群算法优化支持向量SVM的供热量预测,粒子群优化支持向量机SVM回归分析
目录 背影 支持向量机SVM的详细原理 SVM的定义 SVM理论 粒子群算法原理 SVM应用实例,粒子群算法优化支持向量SVM的供热量预测,粒子群优化支持向量机SVM回归分析 代码 结果分析 展望 完整代码:粒子群算法优化支持向量SVM的供热量预测,粒子群优化支持向量机SVM回归分析_lssv…...

【Verilog】运算符
系列文章 数值(整数,实数,字符串)与数据类型(wire、reg、mem、parameter) 系列文章算术运算符关系运算符相等关系运算符逻辑运算符按位运算符归约运算符移位运算符条件运算符连接和复制运算符 算术运算符 …...

浅析ARMv8体系结构:A64指令集
文章目录 A64指令编码格式加载与存储指令寻址模式变基模式前变基模式后变基模式 PC相对地址模式 伪指令加载与存储指令的变种不同位宽的加载与存储指令多字节内存加载和存储指令基地址偏移量模式前变基模式后变基模式 跳转指令返回指令比较并跳转指令 其它指令内存独占访问指令…...
VSCode安装GitHub Copilot插件方法
VSCode安装GitHub Copilot插件的步骤及注意事项如下: 安装步骤: 确保系统要求: 确保你正在使用的Visual Studio Code版本是最新的,且支持GitHub Copilot。同时,Copilot需要你的操作系统是Windows、macOS或Linux&#x…...
实战:使用docker容器化服务
本文介绍使用docker安装mysql和redis,通过这两个的实战,了解一般的安装容器化服务的流程,体会服务容器化的好处 1.使用docker安装MySQL docker 拉取 mysql 镜像 docker pull mysql:5.7运行 mysql 镜像 docker run -p 3306:3306 --name mysql…...

借用GitHub将typora图片文件快速上传CSDN
前情概要 众所周知,程序员大佬们喜欢用typora软件写代码笔记,写了很多笔记想要放到CSDN上给其他大佬分享,但是在往csdn上搬运的时候,图片总是上传出错,一张一张搞有很麻烦,咋如何搞? 废话不多…...

外包公司干了2个月,技术退步明显了.......
先说一下自己的情况,本科毕业,18年通过校招进入南京某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能…...

PTA✨C语言 组合数的和
7-5 组合数的和 分数 15 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 给定 N 个非 0 的个位数字,用其中任意 2 个数字都可以组合成 1 个 2 位的数字。要求所有可能组合出来的 2 位数字的和。例如给定 2、5、8,则可以组合出:25、28、5…...

这些开源自动化测试框架,会用等于白嫖一个w
作者:黑马测试 链接:https://www.zhihu.com/question/19923336/answer/2585952461 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 随着计算机技术人员的大量增加,通过编写代码来…...
代码随想录第三十六天——无重叠区间,划分字母区间,合并区间
leetcode 435. 无重叠区间 题目链接:无重叠区间 方法一:按右边界排序 按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数。此时问题转化为求非交叉区间的最大个数。 版本一&#…...
Python数据分析:入门到实践
一、引言 (用手机写的,明天重新排版。) 在当今数据驱动的时代,数据分析已经成为各行各业不可或缺的一部分。Python作为一种高效、易学的编程语言,在数据分析领域具有广泛的应用。本文将带你从Python数据分析的入门知…...

第7章-第9节-Java中的Stream流(链式调用)
1、什么是Stream流 Lambda表达式,基于Lambda所带来的函数式编程,又引入了一个全新的Stream概念,用于解决集合类库既有的鼻端。 2、案例 假设现在有一个需求, 将list集合中姓张的元素过滤到一个新的集合中;然后将过滤…...

创建一个矩形中有两个三角形
#include <glad/glad.h> #include <GLFW/glfw3.h>#include <iostream>float vertices[] {// 第一个三角形0.5f, 0.5f, 0.0f, // 右上0.5f, -0.5f, 0.0f, // 右下-0.5f, -0.5f, 0.0f, // 左下-0.5f, 0.5f, 0.0f, // 左上 };unsigned i…...
Open3D 基于kdtree树的邻近点搜索(10)
Open3D 基于kdtree树的邻近点搜索(10) 一、算法简介二、算法实现1.K邻近点搜索2.R邻域点搜索三、结果释义一、算法简介 KD 树(k-dimensional tree)是一种用于组织 k 维空间中点的数据结构,旨在提供高效的 k 最近邻搜索和范围搜索(如半径邻域搜索)。KD 树通过递归地将空间…...

c++实现支持动态扩容的栈(stack)
1.在栈容量满时自动扩容: 支持自动扩容栈实现: // // myStack.hpp // algo_demo // // Created by Hacker X on 2024/1/9. //#ifndef myStack_hpp #define myStack_hpp #include <stdio.h> #include <string.h> //栈实现 //1.入栈 //2.出栈 //3.空栈 //4.满栈 …...
举例说明计算机视觉(CV)技术的优势和挑战。
计算机视觉(Computer Vision,CV)技术是指使计算机能够理解和解释视觉数据的能力。CV技术在很多领域都有广泛的应用,包括图像处理、目标检测、人脸识别、自动驾驶等。以下是CV技术的一些优势和挑战的例子: 优势&#x…...
如何利用docker来部署war包项目
首先编写dockerfile文件: # 使用官方的Tomcat镜像作为基础镜像 FROM tomcat:9.0# 将war包复制到容器的webapps目录下 COPY xxxx.war /usr/local/tomcat/webapps/# 暴露Tomcat的默认端口 EXPOSE 8080 编写docker-compose.yml文件: version: 3 services…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...