当前位置: 首页 > news >正文

FLV 格式详解资料整理,关键帧格式解析写入库等等

FLV 是一种比较简单的视频封装格式。大致可以分为 FLV 文件头,Metadata元数据,然后一系列的音视频数据。

资料够多:

FLV格式解析图

知乎用户 @Linux服务器研究 画了一张格式解析图,比较全,但默认背景是白色,太过刺眼。我用 photopea 改为黑暗模式,更适合程序员参考(请拖拽到新标签页,放大食用):

在这里插入图片描述

一个 C# 写的FLV转录库,我把他转换为 Java

Flv-streamer-2-file

作用是输入FLV视频流,实时解析,实时更新视频时长(duration)。

库是好库,c#也是好语言,但没有 Java 简单易懂。

理解一个格式,最好的方式就是用 Java 写个解析转换库。 —— ME

我将之转换为 Java ,添加写入关键帧索引的功能,一切竟然如此简单,宛若拨云见月。

Appxmod / Flv-stream-saver-java: Pure Java library to parse and save flv stream, with keyframes support.

关键帧索引

关键帧索引指的是:一系列关键帧的时间点,映射到 ==> 文件偏移。

关键帧索引位于 onMetadata 元数据。Metadata 是一个 AMF 编码的 EcmaArray ,可以把它当作一个有序的 HashMap<String, Object>。在上面的 Java 库中,我用 JSON 存储解析结果。

关键帧索引(keyframes)就存于 Metadata[“keyframes”] 之中,格式如下:

keyframes (AsObject)
– times (Strict Array)
– filepositions (Strict Array)

AsObject 类似于 EcmaArray,唯一区别是写入时,不写数组长度。

Strict Array 可以看作 ArrayList。数字以 double 方式存储。两个 Strict Array 的长度相等。

times 时间点的单位是秒。filepositions 文件位置的单位是字节,位置是关键帧的起始地址,即 previous tagsize。

关键帧是特殊的帧,有别于 inter frame 等。关键帧索引有助于快速 seek,但不是唯一因素。播放器的支持也很重要。有的即使没有索引,也能用二分法快速 seek 。

FLV 文件中,除了开头九个字节,其他都是TAG。TAG类型有 SCRIPTDATA,AUDIO,VIDDEO,类型标于 TAG HEADER 中。TAG HEADER 11个字节,仅靠 previous tagsize 4个字节,后面就是 TAGDATA。TAGDATA 又有自己的 HEADER 头,其中第一个字节标明当前是否是关键帧。若是,则此字节高数位四位等于1 ( byte>>4==1 )。

SCRIPTDATA 并非脚本,而是数据。Metadata 就是此类型的一个 TAG,一般位于文件头部位置,所以存储关键帧索引时,通过预留位置的方式,最大存储6000多个索引(大小可调)。

【 previous tag size / tag header / tag data 】

tag header 11个字节,其中也包含当前 tag data 的大小。与 previous tag size 不同的是,tag header 中的本TAG大小存储于其中 3 个字节,仅包括 tag data。 所以之后的 previous tag size == 本 tag_data.length + 11。

除了关键帧索引,还有 avc nalu 啥的有助于网络流媒体快速播放。太过复杂没有研究,但是参考链接中有人用 c# 研究了。

参考链接

全部链接见上面我写的 Java 库GitHub地址。

除了参考链接,还有一些在线或离线的FLV工具,可以查看 metaedata、查看关键帧等,编写过程离不开这些。
请添加图片描述

http://www.lryc.cn/news/434677.html

相关文章:

  • 《深度学习》OpenCV 高阶 图像直方图、掩码图像 参数解析及案例实现
  • coredump-N: stack 消耗完之后,用户自定义信号处理有些问题 sigaltstack
  • 数据库有关c语言
  • 【网页播放器】播放自己喜欢的音乐
  • 【第27章】Spring Cloud之适配Sentinel
  • 怎么debug python
  • Java 递归
  • 获取业务库的schema信息导出成数据字典
  • 力扣: 快乐数
  • 一般位置下的3D齐次旋转矩阵
  • 每日一题——第八十六题
  • 十、组合模式
  • 一分钟了解网络安全风险评估!
  • 【springsecurity】使用PasswordEncoder加密用户密码
  • 从0到1实现线程池(C语言版)
  • Visual studio自动添加头部注释
  • 【C#生态园】提升性能效率:C#异步I/O库详尽比较和应用指南
  • 管理医疗AI炒作的三种方法
  • VMware Workstation Pro Download 个人免费使用
  • DevOps平台搭建过程详解--Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台
  • Nginx之日志切割,正反代理,HTTPS配置
  • Mysql数据量大,如何拆分Mysql数据库(垂直拆分)
  • 机器人可能会在月球上提供帮助
  • 真实案例分享:零售企业如何避免销售数据的无效分析?
  • ctfshow-文件包含
  • Qt事件处理机制
  • vue axios 如何读取项目下的json文件
  • 燃气涡轮发动机性能仿真程序GSP12.0.4.2使用经验(二):使用GSP建立PG9351FA燃气轮机性能仿真模型
  • 迟滞比较器/施密特触发器
  • LeetCode_sql_day22(1112.每位学生的最高成绩)