书接上回,我们讨论了FLV文件的结构,有了这些基础之后,我们就能够对FLV文件进行一些操作了,比如本文要讨论的——校验FLV文件的完整性。
完整的FLV文件应该按照FLV文件的结构提供完整的数据信息,如:FLV Header
,FLV Body
中的Previous Tag Size
,Tag
。那我们下面由简入繁的步骤来对FLV文件校验一番。
最简单的校验方法,仅校验FLV Header信息,如(.NET代码):
public static bool IsValidFlvHeader(byte[] bytes)
{
if (bytes.Length != 9) return false;
byte[] header0 = new byte[] { 0x46, 0x4C, 0x56 };
byte flvVer = bytes[3];
byte flvType = bytes[4];
byte[] header_offset = new byte[] { 0x00, 0x00, 0x00, 0x09 };
if (!header0.SequenceEqual(bytes.Take(3).ToArray())) return false;
if (flvVer != 0x01) return false;
if (flvType != 0x01
&& flvType != 0x04
&& flvType != 0x05)
return false;
return header_offset.SequenceEqual(bytes.Skip(5).Take(4).ToArray());
}
这种方法仅校验FLV文件的Header信息是否是标准的FLV Header,在进行文件区分——特别是文件名缺失的情况下,这种方法能够快速的对FLV文件进行提取。
当然,如果我们不仅仅是要对文件进行简单的识别,要更进一步,那么我们就需要更多的校验,比如校验FLV文件的完整性,下面是FLV文件的整体结构:
------------------------
| FLV Header |
------------------------
| Previous Tag Size#0 |
------------------------
| Tag #1 |
------------------------
| Previous Tag Size#1 |
------------------------
| Tag #2 |
------------------------
| Previous Tag Size#2 |
------------------------
| ... |
------------------------
| Tag #n |
------------------------
| Previous Tag Size#n |
------------------------
从结构中可以明确,要校验,只需要校验每个FLV Header,Tag Size即可基本完成校验,关于具体的细节请参见FLV文件格式详解。
有结构的特性,我们可以从文件末尾往前推演进行校验,代码就不放出来了,留给参阅的朋友自己写吧,这里给个思路:
- 读取末尾的4字节,转化成整数,得出这之前的Tag Size
- 根据获取的Tag Size,向前跳过Tag块,再读取更前面的一个Tag的Tag Size(这里重复1)
- 重复1,2两步,直到Tag Size为0,或者当前读取位置(Position)已经小于读取的Tag Size + 9。
- 如果,读取到Tag Size为0时,且前面的数据长度为9(如果Position移动后,可能是13)则认为是完整FLV
- 如果,读取的Tag Size + 9 已经超出了剩下的可用长度,则认为不是完整FLV。
这样就能够简单的分析一个FLV是否完整,这在对文件完整性粗略校验中有比较好的表现。
当然,如果你知道FLV文件的结构的话,你也可以通过下面这些方法来校验文件的完整性:
- 顺序来读取FLV文件进行校验,因为Tag的大小可以在Tag Header中获取,不能100%确认
- 知道在onMetaData中能够得到FLV文件的大小的话,那么,通过这种方法来判断完整性也是可行的。
结合上面的多种校验方式,就能比较准确的校验FLV文件的完整性了。
基本的校验方法就这些,在这里起个抛砖引玉的作用,如果你有更好的方法,欢迎讨论。