媒体格式分析之flv -- 基于FFMPEG

本来是应该先写一个媒体文件格式的简单讲解的,还没来得及写,以后再写。今天就先根据ffmpeg的flv.c的flv_demux这个结构体来讲解一下当前比较流行的媒体格式flv.

FLV 是FLASH VIDEO的简称,FLV流媒体格式是随着Flash MX的推出发展而来的视频格式。由于它形成的文件极小、加载速度极快,使得网络观看视频文件成为可能.当前主流的媒体网站像国内的优酷、国外youtube其标清格式的文件均采用flv的格式。

FLV文件结构解析

FLV是一个二进制文件,其文件格式如下图 ,由文件头(FLV header)和很多tag组成。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。

 

flv_struct

FLV Header

FLV的Header信息一般比较简单,包括文件类型之类的全局信息。如下图中解析:

flv_header 

文件类型3bytes 总是FLV(0x46 0x4C 0x56),否则就不是在ffmpeg中在没有指定文件格式的情况下,也是通过这个字段来探测文件是否属于FLV格式的。

版本1byte 一般是0x01,表示FLV version 1

流信息1byte 倒数第一bit是1表示有视频,倒数第三bit是1表示有音频,其他都应该是0(有些软件如flvtool2可能造成倒数第四bit是1,不过也没发现有什么不对)

header长度4bytes 整个文件头的长度,一般是9(3+1+1+4),当然头部字段也有可能包含其它信息这个时间其长度就不是9了。

FLV Body

FLV body就是由很多tag组成的,一个tag包括下列信息:

      previoustagsize 4bytes 前一个tag的长度,第一个tag就是0

tag类型1byte 共分为三类:

* 8 -- 音频tag

* 9 -- 视频tag

* 18 -- 脚本tag

数据区长度3bytes 时间戳3bytes 单位毫秒同时还有1bytes的扩展时间戳,放在最高位,大部分时间时间戳为媒体的dts信息,如果是脚本tag就是0

streamsID 3bytes 总是0(不知道干啥用)

数据区:根据不同的tag类型就有不同的数据区

脚本tag :

脚本tag一般是用文本方式表示,如下图flv的metadata信息:

flv_16

从中可以看出是通过文本的方式来标记的,其解析后其header信息为:

meta_data_header

 

从中可以看出其type为18。time stamp为0.data size为33638.

metadata tag data信息解析后为:

metadata

其中有一些媒体信息:

例如视频的:高和宽它的codec id。帧率。音频的信息例如:音频的sample rate,codec id,sample size及是否立体声。还有整个文件的大小等等。

音频的tag信息:

音频的tag信息如下图:

audio tag

其中time stamp 为0是因为其为第一个音频tag.

视频tag

video

这是文件中的第6个tag所以其time stamp不为0。因为其为视频tag所以其type为9。

ffmpeg中的flv文件格式解析的实现:

其中flv_read_header主要是从文件中读取一些头信息,同时作一些初始化化的工作

static int flv_read_header(AVFormatContext *s,AVFormatParameters *ap) 
{

         ……

    url_fskip(s->pb, 4); //将flv的头去掉。 
    flags = get_byte(s->pb);//读出flv的video和audio flag信息。

         ……  
        if(flags & FLV_HEADER_FLAG_HASVIDEO){ 
        if(!create_stream(s, 0))  //创建视频流 
            return AVERROR(ENOMEM); 
    } 
    if(flags & FLV_HEADER_FLAG_HASAUDIO){ 
        if(!create_stream(s, 1)) //创建音频流 
            return AVERROR(ENOMEM); 
    }

    offset = get_be32(s->pb); //获取文件头长度

        …… 
}

其它tag的读取:

static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) 
{

     …… 
for(;;url_fskip(s->pb, 4)){ /* pkt size is repeated at end. skip it */ 
    pos = url_ftell(s->pb); 
    type = get_byte(s->pb); //获取tag的类型,前面已经提到flv的tag大概有以下三种 :FLV_TAG_TYPE_AUDIO = 0x08,FLV_TAG_TYPE_VIDEO = 0x09,FLV_TAG_TYPE_META  = 0x12, 
    size = get_be24(s->pb);//获取tag的长度 
    dts = get_be24(s->pb); 
    dts |= get_byte(s->pb) << 24; //计算tag的timestamp也就是dts信息

    …… 
    if (type == FLV_TAG_TYPE_AUDIO) { //判断是否为audio tag

       …… 
         } else if (type == FLV_TAG_TYPE_VIDEO) {//判断是否为video tag

       …… 
               if ((flags & 0xf0) == 0x50) /* video info / command frame */ 
            goto skip; 
    } else { 
        if (type == FLV_TAG_TYPE_META && size > 13+1+4)//判断是否为meta tag,如果是meta信息则会将信息存放在一个map表中。 
         ……

}

版权所有:博水。转载请注明出处:http://www.cnblogs.com/qingquan/

转载于:https://www.cnblogs.com/xumaojun/p/8543061.html

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

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

相关文章

C++从0到1的入门级教学(三)——表达式和运算符

文章目录3 运算符3.1 表达式3.1.1 基本概念3.1.2 运算符和运算对象3.1.3 运算对象的转换3.1.4 左值和右值3.2 运算符3.2.1 算术运算符3.2.2 赋值运算符3.2.3 比较运算符3.2.4 逻辑运算符3.2.5 成员访问运算符3.2.6 条件运算符3 运算符 C提供了一套供操作内置数据类型的运算符&…

谈谈用SQLite和FMDB而不用Core Data

谈谈用SQLite和FMDB而不用Core Data 发布于&#xff1a;2014-04-22 11:22阅读数&#xff1a;4235 凭良心讲&#xff0c;我不能告诉你不去使用Core Data。它不错&#xff0c;而且也在变好&#xff0c;并且它被很多其他Cocoa开发者所理解&#xff0c;当有新人加入你的组或者需要别…

Idea工具开发 SpringBoot整合JSP(毕设亲测可用)

因为&#xff0c;临近毕业了&#xff0c;自己虽然也学了很多框架。但是&#xff0c;都是在别人搭建好的基础上进行项目开发。但是springboot的官方文档上明确指出不提倡使用jsp进行前端开发&#xff0c;但是在校期间只学了jsp作为前端页面。所以&#xff0c;废话不多说&#xf…

深度学习番外——Yolov5服务器环境搭建

文章目录1 服务器搭建yolov5环境1.1 创建环境1.2 跟随官方指引2 下载预训练权重3 推理4 测试1 服务器搭建yolov5环境 1.1 创建环境 首先先的在本地环境下搭建一个我们的环境&#xff0c;名字设为yolo5-6 conda create -n yolov5-6 python3.7#创建环境 conda activate yolov5…

机器学习实战(一)——员工离职预测

文章目录员工离职预测——逻辑回归的应用1 读取文件2 独热编码3 划分数据集4 归一化5 逻辑回归预测6 模型预测及评估员工离职预测——逻辑回归的应用 开始这个案例之前&#xff0c;请先点击这里的数据集进行下载&#xff1a;HR_comma_sep.zip - 蓝奏云 (lanzout.com) 1 读取文…

Mac版Anaconda安装Tweepy包

Anaconda官网给出的tweepy包安装方法&#xff1a;https://anaconda.org/conda-forge/tweepy 查阅Anaconda官方文档&#xff0c;可以通过以下控制台命令安装Tweepy包。 conda install -c conda-forge tweepy 在控制台执行后&#xff0c;系统可能会提示未找到conda指令&#xff…

iOS 证书与签名 解惑详解

iOS 证书与签名 解惑详解 分类&#xff1a; iPhone2012-06-06 19:57 9426人阅读 评论(1) 收藏 举报iosxcodecryptographyappleiphone测试目录(?)[] 教程截图&#xff1a; 下面是一篇有澳洲墨尔本的一名全职iOS开发者提供的文章。他在论坛上是一个很摩登的年轻人 – Adam Eberb…

Julia学习笔记(一)——入门

文章目录1 入门1.1 启动与退出1.1.1 启动1.1.2 退出1.2 编译文件1.3 变量1.3.1 基本介绍1.3.2 重定义1.3.3 变量名合法性1 入门 1.1 启动与退出 1.1.1 启动 在没有任何IDE的帮助下&#xff0c;使用cmd启动黑窗口来尝试julia是一种最简单的方法。我们称进入julia后的黑窗口为…

Linux学习宝典

文章目录1 虚拟机1.1 简介1.2 Linux版本1.2.1 内核1.2.2 发行版1.3 文件和目录1.3.1 单用户操作系统和多用户操作系统1.3.2 window文件系统1.3.3 Linux下的文件系统2 概述2.1 为什么要学习命令2.2 一些基本操作和说明3 指令和选项4 基础指令4.1 ls指令4.1.1 讲解4.1.2 选项4.1.…

《华为工作法读后感》

开篇 首先不得不说《华为工作法》是一本很好的书籍。感谢我们领导的照顾和用心&#xff0c;才使得我们又有了一些对社会 对工作 对生活等等的认知 。 之前的我是不怎么读书的&#xff0c;因为个人原因读的慢&#xff0c;每句话都要了解其中寓意之后才继续读下去,还有就是工作…

Redis发布与订阅——PUBLISH SUBSCRIBE

2019独角兽企业重金招聘Python工程师标准>>> &#xfeff;Redis发布与订阅——PUBLISH & SUBSCRIBE 一般来说&#xff0c;发布与订阅&#xff08;又称pub/sub&#xff09;的特点是订阅者&#xff08;listener&#xff09;负责订阅频道&#xff08;channel&…

Android 网络通信架构学习

最近跟着云课堂上的极客学院做安卓APP&#xff0c;学习了课程里面介绍的一种网络通信架构。清晰明了&#xff0c;比我自己东一块西一块拼凑出来的要好很多。在这里记录一下。 云课堂的连接&#xff1a;http://study.163.com/course/courseMain.htm?courseId917001 目录&#x…

网络爬虫(二)——Xpath和Selenium的使用

文章目录2 网络爬虫进阶2.1 Xpath2.1.1 Xpath解析原理2.1.2 信息提取2.1.2.1 获取所有结点2.1.2.2 获取子节点2.1.2.3 获取父节点2.1.2.4 获取文本2.1.3 属性匹配2.1.3.1 单个属性匹配2.1.3.2 多个属性匹配3.1 Selenium3.1.1 概述3.1.2 安装3.1.3 元素定位3.1.4 元素信息3.1.5 …

lintcode:买卖股票的最佳时机 III

买卖股票的最佳时机 III 假设你有一个数组&#xff0c;它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。 样例 给出一个样例数组 [4,4,6,1,1,4,2,5], 返回 6 解题 尝试参考买卖股票的最佳时机 II 提交运行发现错误&#…

团队项目计划BACKLOG

团队名称&#xff1a; 铁大老司机 团队成员&#xff1a; 组长&#xff1a;杨超群 组员&#xff1a;杨涛 杜文星 张家军 计划会议过程&#xff1a; 我们小组在周三下午进行了团队会议&#xff0c;会议召开在图书馆大厅&#xff0c;主要内容是进行项目的总体计划安排&#xff0…

C++从0到1的入门级教学(八)——通讯录管理系统

文章目录8 通讯录管理系统8.1 系统需求8.2 菜单功能8.3 退出功能8.4 添加联系人8.4.1 设计联系人结构体8.4.2 设计通讯录结构体8.4.3 main函数中创建通讯录8.4.4 封装添加联系人函数8.5 显示联系人8.5.1 封装显示联系人函数8.5.2 调用显示联系人函数8.6 删除联系人8.6.1 封装检…

【Data Cluster】真机环境下MySQL数据库集群搭建

真机环境下MySQL-Cluster搭建文档 MySQL Cluster简介 MySQL cluster 和 Oracle RAC 完全不同&#xff0c;它采用 无共享架构Shared nothing&#xff08;shared nothing architecture&#xff09;。整个集群由管理节点(ndb_mgmd)&#xff0c;处理节点(mysqld)和存储节点(ndbd)组…

数据结构杂谈(八)——树(上)

文章目录8 树(上)8.1 引入8.2 树的基础知识8.3 树的存储结构8.3.1 双亲表示法8.3.2 孩子表示法8.4 二叉树8.4.1 基础知识8.4.2 高频考点8.4.3 二叉树的性质8.4.4 二叉链表8.4.5 树和二叉树的转换8.4.6 森林和二叉树的转换8.5 遍历8 树(上) 8.1 引入 我们在前面的章节中一直在…

Maven(一)——快速上手Maven

文章目录Maven概述Maven简介Maven的安装Maven的基本使用IDEA配置Maven依赖管理依赖范围Maven概述 Maven是专门用于管理和构建Java项目的工具&#xff0c;它的主要功能有&#xff1a; &#xff08;一&#xff09;提供了一套标准化的项目结构 不同的IDE项目结构是不一样的&…

EntityFramework_MVC4中EF5 新手入门教程之三 ---3.排序、 筛选和分页

在前面的教程你实施了一套基本的 CRUD 操作&#xff0c;为Student实体的 web 页。在本教程中&#xff0c;您将添加排序、 筛选和分页到 StudentsIndex的功能。您还将创建一个页面&#xff0c;并简单分组。 下面的插图显示页面当你完成时的样子。列标题是链接&#xff0c;用户可…