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

2024-09-06 22:28

本文主要是介绍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、查看关键帧等,编写过程离不开这些。
请添加图片描述

这篇关于FLV 格式详解资料整理,关键帧格式解析写入库等等的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143295

相关文章

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

详解python pycharm与cmd中制表符不一样

《详解pythonpycharm与cmd中制表符不一样》本文主要介绍了pythonpycharm与cmd中制表符不一样,这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽... 这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽度不同导致的。在PyChar