本来是应该先写一个媒体文件格式的简单讲解的,还没来得及写,以后再写。今天就先根据ffmpeg的flv.c的flv_demux这个结构体来讲解一下当前比较流行的媒体格式flv. FLV 是FLASH VIDEO的简称,FLV流媒体格式是随着Flash MX的推出发展而来的视频格式。由于它形成的文件极小、加载速度极快,使得网络观看视频文件成为可能.当前主流的媒体网站像国内的优酷、国外youtube其标清格式的文件均采用flv的格式。 FLV文件结构解析FLV是一个二进制文件,其文件格式如下图 ,由文件头(FLV header)和很多tag组成。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。 FLV HeaderFLV的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 BodyFLV 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信息: 从中可以看出是通过文本的方式来标记的,其解析后其header信息为: 从中可以看出其type为18。time stamp为0.data size为33638. metadata tag data信息解析后为: 其中有一些媒体信息: 例如视频的:高和宽它的codec id。帧率。音频的信息例如:音频的sample rate,codec id,sample size及是否立体声。还有整个文件的大小等等。 音频的tag信息:音频的tag信息如下图: 其中time stamp 为0是因为其为第一个音频tag. 视频tag这是文件中的第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的头去掉。 …… offset = get_be32(s->pb); //获取文件头长度 …… 其它tag的读取: static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) …… …… …… …… } (qingquan) |