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,欢迎交流!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/608771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

透明OLED拼接屏:重塑大屏显示的新篇章

随着科技的快速发展&#xff0c;大屏显示技术已经逐渐渗透到我们生活的方方面面。作为显示技术领域的一大革新&#xff0c;透明OLED拼接屏以其独特的透明显示特性&#xff0c;正逐渐成为大屏显示市场的新宠。尼伽小编将深入探讨透明OLED拼接屏的技术特点、应用场景以及市场前景…

中国葡萄酒消费者的口味偏好

有一段时间&#xff0c;“中国口味”的问题是全世界葡萄酒销售者的热门话题&#xff0c;因为他们积极探索每一个线索&#xff0c;以发现让他们在市场上领先的秘密。为此进行了大量研究&#xff0c;多年前葡萄酒销售商或多或少形成了一个共识&#xff1a;尽管中国人的口味差异很…

系列十四、while do...while switch模板代码

一、while & do...while & switch模板代码 1.1、while /*** 需求&#xff1a;使用while循环打印5遍Hello World!*/ Test public void print5() {int i 1;while (i < 5) {System.out.println("Hello World! " LocalDateTime.now());// 线程休眠&#x…

Spring MVC学习之——了解MVC设计模式

MVC设计模式 MVC介绍 MVC 模式代表 Model-View-Controller&#xff08;模型-视图-控制器&#xff09; 模式。这种模式用于应用程序的分层开发。 Model&#xff08;模型&#xff09; - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑&#xff0c;在数据变化时更新…

Java项目:112SSM在线电影订票系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 在线电影订票系统基于SpringSpringMVCMybatis开发&#xff0c;系统分为前台和后台&#xff0c;前台主要用来用户浏览电影信息&#xff0c;订票&#xff0c…

人工智能任务2-读懂Transformer模型的十个灵魂拷问问题,深度理解Transformer模型架构

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务2-读懂Transformer模型的十个灵魂拷问问题&#xff0c;深度理解Transformer模型架构。Transformer模型是一种基于自注意力机制的神经网络架构&#xff0c;被广泛用于自然语言处理任务中&#xff0c;如机…

系分笔记数据库技术之数据库安全措施

文章目录 1、概要2、数据库的保护措施3、数据库的故障4、备份和日志5、总结 1、概要 数据库设计是考试重点&#xff0c;常考和必考内容&#xff0c;本篇主要记录了知识点&#xff1a;数据库故障及解决、数据库安全保护措施和数据库备份及恢复。 2、数据库的保护措施 数据库安全…

云卷云舒:【实战篇】云主机/虚拟机迁移

1. 简介 用户原有业务通过不同版本型号、不同操作系统的主机承载&#xff0c;形式上包括物理服务器、虚拟机、公有云主机等。随着业务不断扩张&#xff0c;需要将其业务云化转型&#xff0c;必须保证上云过程数据完整&#xff0c;业务平滑过度。 如果将所有业务系统都重新部署…

以太坊开发者会议回顾:坎昆升级、硬分叉与布拉格

作者&#xff1a;Christine Kim Galaxy研究副总裁 编译&#xff1a;秦晋 碳链价值 2024年1月4日&#xff0c;以太坊开发人员齐聚Zoom for All Core Developers Execution (ACDE) Call #178 上。ACDE电话会议通常由以太坊基金会协议负责人Tim Beiko主持&#xff0c;是一个开发人…

Orchestrator源码解读2-故障失败发现

目录 目录 前言 核心流程函数调用路径 GetReplicationAnalysis 故障类型和对应的处理函数 拓扑结构警告类型 与MHA相比 前言 Orchestrator另外一个重要的功能是监控集群&#xff0c;发现故障。根据从复制拓扑本身获得的信息&#xff0c;它可以识别各种故障场景。Orchest…

Apollo基础 - Frenet坐标系

Frenet与笛卡尔坐标系的转换详细推导见&#xff1a;b站老王 自动驾驶决策规划学习记录&#xff08;四&#xff09; Apollo相关代码&#xff1a; modules/common/math/cartesian_frenet_conversion.h #pragma once #include <array> #include "modules/common/mat…

怎么一边讲PPT一边录视频 如何一边录制PPT一边录制人像 录屏软件免费录屏 PPT录制怎么录制

随着新媒体技术的发展&#xff0c;短视频和直播越来越火。越来越多的小伙伴加入了视频制作的大军&#xff0c;那么你想知道怎么一边讲PPT一边录视频&#xff0c;如何一边录制PPT一边录制人像吗&#xff1f; 一、怎么一边讲PPT一边录视频 我们可以借助PPT本身自带的屏幕录制功能…

Linux的发展历程:从诞生到全球应用

一、前言 Linux作为一个开源操作系统&#xff0c;经历了令人瞩目的发展历程。从最初的创意到如今在全球范围内得到广泛应用&#xff0c;Linux不仅是技术的杰出代表&#xff0c;更是开源精神的典范。本文将追溯Linux的发展历程&#xff0c;深入了解它是如何从一个个人项目演变为…

【docker笔记】Docker容器数据卷

Docker容器数据卷 卷就是目录或者文件&#xff0c;存在于一个或多个容器中&#xff0c;由docker挂载到容器&#xff0c;但不属于联合文件系统&#xff0c;因此能够绕过Union File System提供一些用于持续存储或共享数据的特性 卷的设计目的就是数据的持久化&#xff0c;完全独…

VMware Workstation安装以及配置模板机

文章目录 一、VMware Workstation软件下载安装1、下载2、安装 二、CentOS7模板机安装1、创建虚拟机2、安装系统 三、网络配置 一、VMware Workstation软件下载安装 1、下载 下载地址&#xff1a;https://download3.vmware.com/software/wkst/file/VMware-workstation-full-15…

css中的变量和辅助函数

变量 --name 两个破折号加变量名称&#xff08;可以在当前的选择器内定义&#xff09;var(--*) 命名规则 body {--深蓝: #369;background-color: var(--深蓝); } 变量值只能做用属性值&#xff0c;不能用做属性名。变量命名不能包含 $,[,^,(,% 等字符 普通字符局限在只要是数…

软件测试|MySQL逻辑运算符使用详解

简介 在MySQL中&#xff0c;逻辑运算符用于处理布尔类型的数据&#xff0c;进行逻辑判断和组合条件。逻辑运算符主要包括AND、OR、NOT三种&#xff0c;它们可以帮助我们在查询和条件语句中进行复杂的逻辑操作。本文将详细介绍MySQL中逻辑运算符的使用方法和示例。 AND运算符 …

邮政快递单号查询入口,对快递单号进行提前签收分析

一款优秀的快递单号筛选软件能够给你的工作和生活带来极大的便利。通过合理选择和使用该软件&#xff0c;你将能够轻松管理、高效筛选快递单号&#xff0c;提升工作效率和生活品质。不妨试试我们的【快递批量查询高手】&#xff0c;让你的物流管理更加智能、便捷&#xff01; …

Pytest成魔之路 —— fixture 之大解剖!

1. 简介 fixture是pytest的一个闪光点&#xff0c;pytest要精通怎么能不学习fixture呢&#xff1f;跟着我一起深入学习fixture吧。其实unittest和nose都支持fixture&#xff0c;但是pytest做得更炫。 fixture是pytest特有的功能&#xff0c;它用pytest.fixture标识&#xff0c…

【算法Hot100系列】搜索插入位置

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…