在解析RM文件时我们首先需要了解RM文件的格式。在下面的内容中将介绍RM文件的格式。
RM文件格式(RealMedia File Format 简称RMFF),文件单元使用四字符编码。编码是32位的。
RMF的基本单元是chunk。是数据的逻辑单元。
每个chunk包含:
1.四字符编码的单元标识符;
2.每个chunk的32位的数据;
3.未识别的块。
RMFF的标签
RMFF的标签由一个头单元,一个数据单元和一个引导单元组成。
在头部中包括一下单元:RM的文件头,属性头,媒体属性头,内容描述头。
RM文件头:
每个RM文件都是以RM文件头开始的。
RealMedia_File_Header
{
UINT32 object_id;
UINT32 size;
UINT16 object_version
;
if ((object_version == 0) || (object_version == 1))
{
UINT32 file_version;
UINT32 num_headers;
}
}
RMFHeader的结构体
由于RMFH的内容要根据RMFF的版本来改变,所以头的结构体有一个版本信息为了扩展方便。
object_id: RMF唯一的ID号。是32位的无符号整型。相当于文件的标识符。
size: RM头的大小。32位的无符号整型。
object_version: RMFH对象的版本。16位的无符号整型。所有文件依照这个规定有一个object_version是0或1.
file_version: 0或1.
num_headers: 在头部中头的数量。32位无符号整型。
属性头:
描述RMF的一般媒体属性。
RM系统成员通过这个对象来配置如何处理RMF中或者流中的数据。在RMF中只有一个属性头。
结构体如下:
Properties { UINT32 object_id; UINT32 size; UINT16 object_version; if (object_version == 0) { UINT32 max_bit_rate; UINT32 avg_bit_rate; UINT32 max_packet_size; UINT32 avg_packet_size; UINT32 num_packets; UINT32 duration; UINT32 preroll; UINT32 index_offset; UINT32 data_offset; UINT16 num_streams; UINT16 flags; } }object_id: 属性头的唯一ID,相当于标识符。(PROP)
size: 属性头的大小。字节数
object_version: 0或1.RMFH对象的版本。
当object_version==0时由如下成员。
max_bit_rate: 网络传输这个文件所需要的最大的比特率。
avg_bit_rate: 网络传输这个文件所需要的平均比特率。
max_packet_size: 媒体数据包最大的大小。
avg_packet_size: 媒体数据包的平均大小。
num_packets: 媒体信息中数据包数。
duration: 文件的位置。以毫秒为单位。
preroll: 在回放前缓冲区的毫秒数。
index_offset: 从文件开头到索引头对象的字节数。
data_offset: 从文件开头到数据单元的开头的字节数。
num_streams: 在主要的头单元中媒体属性头的数量。
flags: 位屏蔽的一些这些文件的信息。
媒体属性头(Media Properties Header)
描述RM文件的每个流中特殊的媒体属性。住用和属性头差不多。
结构体描述如下:
Media_Properties { UINT32 object_id; UINT32 size; UINT16 object_version; if (object_version == 0) { UINT16 stream_number; UINT32 max_bit_rate; UINT32 avg_bit_rate; UINT32 max_packet_size; UINT32 avg_packet_size; UINT32 start_time; UINT32 preroll; UINT32 duration; UINT8 stream_name_size; UINT8[stream_name_size] stream_name; UINT8 mime_type_size; UINT8[mime_type_size] mime_type; UINT32 type_specific_len; UINT8[type_specific_len] type_specific_data; } }object_id: 该结构体的实例化ID(MDPR),标识符。
Size: 该结构体的大小。
object_version: 媒体属性头的版本。
stream_number: 标识一个物理流。是一个唯一的值。每个数据包都属于一个物理流,这个物理流和数据包的stream_number相同。
start_time: 在物理流中每个数据包的添加时间戳的开始时间。
stream_name:流的名字
stream_name_size:stream_name的字节数。
mime_type: 一个非唯一索引的MIME风格的类型字符串是关联流的数据。
mime_type_size:mime_type的字节数。
type_specific_data: 通常被用于数据类型描绘器的实例化。为处理物理流。
type_specific_len: type_specific_data的字节数。
Logical Stream Organization
物理流组成逻辑流。逻辑流包含一下信息:
1.标识符:哪些物理流一起组成逻辑流
2.标识逻辑流属性的名字、值、属性。
逻辑流的结构体:
LogicalStream { ULONG32 size; UINT16 object_version; if (object_version == 0) { UINT16 num_physical_streams; UINT16 physical_stream_numbers[num_physical_streams]; ULONG32 data_offsets[num_physical_streams]; UINT16 num_rules; UINT16 rule_to_physical_stream_number_map[num_rules]; UINT16 num_properties; NameValueProperty properties[num_properties]; } };size:结构体的大小(字节)
object_version: 逻辑流结构体的版本。
如果object_version==0;
则有如下元素:
num_physical_streams: 构成逻辑流的物理流数。
physical_stream_numbers[]: 存储num_physical_streams的数组。这个成眼是可变的。
data_offsets[]: 标志每个物理流的数据单元开始位置。
num_rules: 逻辑流的ASM rulse 的数量。//ASM:制动存储管理
rule_to_physical_stream_map[] : 物理流对应的每个规则的存储列表。
num_properties: NameValueProperty结构体的数量。
properties[]: NameValueProperty结构体的存储列表。
NameValueProperty { ULONG32 size; UINT16 object_version; if (object_version == 0) { UINT8 name_length; UINT8 name[namd_length]; INT32 type; UINT16 value_length; UINT8 value_data[value_length]; } }size: NameValueProperty结构体的大小(字节数)。
object_version: 结构体的版本。
如果object_version==0;则有如下元素。
name_length: 名字的大小。
name[]: 名字信息。
type: 数据的类型。
value_length: 数据信息的长度。
value_data[]: 数据。
Content Description Header
Content_Description
{
UINT32 object_id;
UINT32 size;
UINT16 object_version
;
if (object_version == 0)
{
UINT16 title_len;
UINT8[title_len] title;
UINT16 author_len;
UINT8[author_len] author;
UINT16 copyright_len;
UINT8[copyright_len] copyright;
UINT16 comment_len;
UINT8[comment_len] comment;
}
}
展示文件的信息。是文本信息。包括文件的title.author.copyright和comments information.