音视频入门基础:FLV专题(5)——FFmpeg源码中,判断某文件是否为FLV文件的实现
一、引言
通过FFmpeg命令:
./ffmpeg -i XXX.flv
可以判断出某个文件是否为FLV文件:

所以FFmpeg是怎样判断出某个文件是否为FLV文件呢?它内部其实是通过flv_probe函数来判断的。从《FFmpeg源码:av_probe_input_format3函数和AVInputFormat结构体分析(FFmpeg源码5.0.3版本)》和《7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变》中我们可以知道:
FFmpeg源码中实现容器格式检测的函数是av_probe_input_format3函数,其内部通过循环while ((fmt1 = av_demuxer_iterate(&i))) 拿到所有容器格式对应的AVInputFormat结构,然后通过score = fmt1->read_probe(&lpd)语句执行不同容器格式对应的解析函数,根据是否能被解析,以及匹配程度,来判断出这是哪种容器格式。而FLV文件对应的解析函数就是flv_probe函数。
二、flv_probe函数的定义
flv_probe函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为7.0.1)的源文件libavformat/flvdec.c中,可以看到flv_probe函数内部调用了probe函数:
static int flv_probe(const AVProbeData *p)
{return probe(p, 0);
}
三、probe函数的定义
probe函数也定义在libavformat/flvdec.c中:
static int probe(const AVProbeData *p, int live)
{const uint8_t *d = p->buf;unsigned offset = AV_RB32(d + 5);if (d[0] == 'F' &&d[1] == 'L' &&d[2] == 'V' &&d[3] < 5 && d[5] == 0 &&offset + 100 < p->buf_size &&offset > 8) {int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10);if (live == is_live)return AVPROBE_SCORE_MAX;}return 0;
}
probe函数的作用就是检测某个文件是否为flv文件或flv格式的直播流。
形参pd:输入型参数,为AVProbeData类型的指针。
AVProbeData结构体声明在libavformat/avformat.h中:
/*** This structure contains the data a format has to probe a file.*/
typedef struct AVProbeData {const char *filename;unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */int buf_size; /**< Size of buf except extra allocated bytes */const char *mime_type; /**< mime_type, when known. */
} AVProbeData;
p->filename为:需要被推测格式的文件/直播流的路径。
p->buf:指向“存放从路径为p->filename的FLV文件/直播流中读取出来的二进制数据”的缓冲区。
p->buf_size:缓冲区p->buf的大小,单位为字节。注:FFmpeg判断某个文件的格式时不会读取完整个文件,只会读取它前面的一部分,比如最开始的2048个字节。只要根据前面的这些字节就足够判断出它的格式了,所以p->buf_size的值一般就是2048。
p->mime_type:一般为NULL,可忽略。
返回值:返回一个类型为整形的分值。返回0表示该文件/直播流完全不符合FLV格式。返回AVPROBE_SCORE_MAX(100)表示该文件/直播流完全符合FLV格式。
形参live:值为1表示需要被推测格式的是直播流,值为0表示需要被推测格式的是本地媒体文件。
四、probe函数的内部实现原理
下面以需要被推测格式的是FLV文件为例,讲解probe函数的内部实现原理。FLV文件对应的解析函数是flv_probe函数,flv_probe函数内部调用了probe函数,这时probe函数的形参live的值为0。
probe函数内部,由于FLV文件的开头就是FLV header,所以指针d指向FLV header:
const uint8_t *d = p->buf;
通过AV_RB32宏定义读取FLV header中的DataOffset属性,得到整个FLV header的以字节为单位的长度,赋值给局部变量offset。关于AV_RB32宏定义的用法可以参考:《FFmpeg源码:AV_RB32、AV_RB16、AV_RB8宏定义分析》:
unsigned offset = AV_RB32(d + 5);
从《音视频入门基础:FLV专题(3)——FLV header简介》可以知道,FLV header的前3个字节固定为“FLV”,所有判断d[0] == 'F' && d[1] == 'L' && d[2] == 'V';FLV header的第4个字节为Version,对于FLV格式,值必须为1,所以判断d[3] < 5;整个FLV header的长度固定为9,所以判断offset > 8。不满足条件probe函数返回0,表示完全不符合FLV格式:
if (d[0] == 'F' &&d[1] == 'L' &&d[2] == 'V' &&d[3] < 5 && d[5] == 0 &&offset + 100 < p->buf_size &&offset > 8) {//...}return 0;
判断是否为直播流,变量is_live的值为1表示是直播流,值为0表示是FLV文件:
int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10);
返回AVPROBE_SCORE_MAX(100)表示该文件/直播流完全符合FLV格式。
if (live == is_live)return AVPROBE_SCORE_MAX;
相关文章:
音视频入门基础:FLV专题(5)——FFmpeg源码中,判断某文件是否为FLV文件的实现
一、引言 通过FFmpeg命令: ./ffmpeg -i XXX.flv 可以判断出某个文件是否为FLV文件: 所以FFmpeg是怎样判断出某个文件是否为FLV文件呢?它内部其实是通过flv_probe函数来判断的。从《FFmpeg源码:av_probe_input_format3函数和AVI…...
Tomcat 乱码问题彻底解决
1. 终端乱码问题 找到 tomcat 安装目录下的 conf ---> logging.properties .修改ConsoleHandler.endcoding GBK (如果在idea中设置了UTF-8字符集,这里就不需要修改) 2. CMD命令窗口设置编码 参考:WIN10的cmd查看编码方式&am…...
RGB颜色模型
RGB颜色模型是一种广泛应用于数字图像和计算机图形领域的颜色表示方法 一、基本概念 RGB 代表红色(Red)、绿色(Green)和蓝色(Blue)三种基本颜色。这些颜色被视为加色模型中的原色,意味着它们可…...
智能工厂的软件设计 创新型原始制造商(“创新工厂“)的Creator原型(统一行为理论)之2
Q8、今天我们继续昨天开始的 “智能工厂的软件设计”以“统一行为理论”为指导原则的 创新型原始制造商的Creator伪代码--创新工厂“原型”。这是在前述将“程序program”问题的三个体现“方面”(逻辑/语言/数学) 视为符号学的三分支(语用语义…...
【个人博客hexo版】hexo安装时会出现的一些问题
项目场景: 项目场景:在完成了GitHub仓库和git的连接之后,就要新建一个文件夹(例如hexo blog)进行下一步hexo的使用 问题描述 例如:如图所示 原因分析: 这些error不用看它到底是什么…...
道路裂缝,坑洼,病害数据集-包括无人机视角,摩托车视角,车辆视角覆盖道路
道路裂缝,坑洼,病害数据集 包括无人机视角,摩托车视角,车辆视角 覆盖道路所有问题 一共有八类16000张 1到7依次为: [横向裂缝, 纵向裂缝, 块状裂缝, 龟裂, 坑槽, 修补网状裂缝, 修补裂缝, 修补坑槽] 道路病害(如裂缝、…...
java接口文档配置
接口文档配置 一. swagger与knife4j 配置 1. 导入依赖 <!--swagger接口文档说明--> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId> </dependency> <dependency><groupId>…...
【服务器第二期】mobaxterm软件下载及连接
【服务器第二期】mobaxterm软件下载及连接 前言什么是SSH什么是FTP/SFTP mobaxterm软件介绍mobaxterm软件下载SSH登录使用方法1-新建ssh连接方法2-打开已有的ssh连接方法3-通过ssh命令建立连接 SFTP数据传输方法1-建立ssh连接后直接拖拽方法2-建立sftp连接再拖拽方法3-直接使用…...
排序-----计数排序(非比较排序)
原理: 存在的问题:数组空间浪费 所以要相对映射,不要绝对映射 calloc()函数的功能是:为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0. // 时间复杂度:O(Nrange) // 只适合整数/适合范围集中 // 空间范围度:…...
[Python]案例驱动最佳入门:Python数据可视化在气候研究中的应用
在全球气候问题日益受到关注的今天,气温变化成为了科学家、政府、公众讨论的热门话题。然而,全球气温究竟是如何变化的?我们能通过数据洞察到哪些趋势?本文将通过真实模拟的气温数据,结合Python数据分析和可视化技术&a…...
PyQt5 导入ui文件报错 AttributeError: type object ‘Qt‘ has no attribute
问题描述: 利用 PyQt5 编写可视化界面是较为普遍的做法,但是使用全新UI版本的 Pycharm 修改之前正常的UI文件时,在没有动其他代码的情况下发现出现以下报错 AttributeError: type object Qt has no attribute Qt::ContextMenuPolicy::Defaul…...
Unity中Rigidbody 刚体组件和Rigidbody类是什么?
Rigidbody 刚体组件 Rigidbody 是 Unity 中的一个组件,它可以让你的游戏对象像真实世界中的物体一样移动和碰撞。想象一下,你有一个小球,你希望它像真实世界中的球一样滚动、弹跳和碰撞,那么你就可以给这个小球添加一个 Rigidbod…...
MySQL学习笔记(持续更新中)
1、Mysql概述 1.1 数据库相关概念 三个概念:数据库、数据库管理系统、SQL 名称全称简称数据库存储数据的仓库,数据是有组织的进行存储DataBase(DB)数据库管理系统操纵和管理数据库的大型软件DataBase Mangement System…...
sqlserver插入数据删除数据
1、插入数据 1.1 直接插入 1.1.1 方式一 insert into test values(001,黎明,1),(002,冯绍峰,1),(003,菲菲,2);1.1.2 方式二 insert into test(ID,Name,Sex) values(004,丽丽,2),(005,凌晨,2),(006,虾米,1);1.2 插入部分行 insert into test(ID,Name) values(007,红)2、删除…...
[51单片机] 简单介绍 (一)
文章目录 1.单片机介绍2.单片机内部三大资源3.单片机最小系统4.STC89C52单片机 1.单片机介绍 兼容Intel的MCS-51体系架构的一系列单片机。 STC89C52:8K FLASH、512字节RAM、32个IO口、3个定时器、1个UART、8个中断源。 单片机简称MCU单片机内部集成了CPU、RAM、RO…...
6个岗位抢1个人,百万年薪抢毕业生?大厂打响AI人才战
前言 “24岁毕业时年薪50万元,到了30岁大概能升到P7(注:职级名称),那时就能年薪百万了。” 从上海交大硕士毕业后,出生于2000年的赵宏在今年入职腾讯,担任AI算法工程师,成为AI风口下第一批就业…...
erlang学习:Linux命令学习3
shell基本输出 创建一个test.sh文件,并开放他的权限,之后向其中编辑以下内容 touch test.sh chmod 777 test.sh vim test.shecho "hello linux"之后运行相应shell程序得到输出 ./test.sh变量 单引号特点: 单引号里的任何字符都…...
力扣41 缺失的第一个正数 Java版本
文章目录 题目描述代码 题目描述 给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除…...
第五篇:Linux进程的相关知识总结(1)
目录 第四章:进程 4.1进程管理 4.1.1进程管理需要的学习目标 4.1.1.1了解进程的相关信息 4.1.1.2僵尸进程的概念和处理方法: 4.1.1.3PID、PPID的概念以及特性: 4.1.1.4进程状态 4.1.2进程管理PS 4.1.2.1静态查看进程 4.1.2.1.1自定义…...
企业级Windows server服务器技术(1)
windows server服务器安装 准备工作: 1.准备安装的镜像 2.安装好虚拟机VMware或者virtual box 3.准备安装的位置(选择你的电脑的磁盘上比较空闲的位置,新建一个文件夹并命名) 4.开始安装(按步骤)----…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
