zoukankan      html  css  js  c++  java
  • C#获取 Flv视频文件播放时间长度等信息

    FLV是一个二进制文件,由文件头(FLV header)和很多tag组成。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。
    FLV Header 一般比较简单,包括文件类型之类的全局信息

    文件类型 3bytes 总是FLV(0x46 0x4C 0x56),否则...
    版本 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 单位毫秒,如果是脚本tag就是0
    扩展时间戳 1byte 作为时间戳的高位
    streamsID 3bytes 总是0(不知道干啥用)
    数据区    

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

    audio信息 1byte 前四位bits表示音频格式:
    • 0 -- 未压缩
    • 1 -- ADPCM
    • 2 -- MP3
    • 5 -- Nellymoser 8kHz momo
    • 6 -- Nellymoser
    下面两位bits表示samplerate:
    • 0 -- 5.5kHz
    • 1 -- 11kHz
    • 2 -- 22kHz
    • 3 -- 44kHz
    下面一位bit表示每个采样的长度:
    • 0 -- snd8Bit
    • 1 -- snd16Bit
    下面一位bit表示类型:
    • 0 -- sndMomo
    • 1 -- sndStereo
    audio数据区 不定  

    video tag 数据区

    video信息 1byte 前四位bits表示类型:
    • 1 -- keyframe
    • 2 -- inner frame
    • 3 -- disposable inner frame (H.263 only)
    后四位bits表示编码器id:
    • 2 -- Seronson H.263
    • 3 -- Screen video
    • 4 -- On2 VP6
    • 5 -- On2 VP6 without channel
    • 6 -- Screen video version 2
    video数据区 不定  

    script tag 数据区 略n字...
    代码 Code 目前只用到读取视频时长的部分

      1 using System;
      2  
      3 using System.Collections.Generic;
      4  
      5 using System.Linq;
      6  
      7 using System.Text;
      8  
      9 using System.IO;
     10  
     11 namespace _30edu.Common
     12  
     13 {
     14  
     15     public class FlvInfo
     16  
     17     {
     18  
     19         public FlvInfo()
     20  
     21         {
     22  
     23             Header = new FLVHeader();
     24  
     25             TagList = new List<FLVTag>();
     26  
     27         }
     28  
     29         public FLVHeader Header { get;private set; }
     30  
     31         public List<FLVTag> TagList { get; private set; }
     32  
     33         public TimeSpan Time
     34  
     35         {
     36  
     37             get
     38  
     39             {
     40  
     41                 int time=0;
     42  
     43                 //foreach (FLVTag tag in this.TagList.Where(p=>p.Type))
     44  
     45                 //{ 
     46                 //    byte[] tmp = new byte[4];
     47  
     48                 //    tmp[3] = tag.TimeEx;
     49  
     50                 //    tmp[0] = tag.Time[2];
     51  
     52                 //    tmp[1] = tag.Time[1];
     53  
     54                 //    tmp[2] = tag.Time[0];
     55  
     56                 //    time += BitConverter.ToInt32(tmp,0);
     57  
     58                 //}
     59  
     60                 FLVTag tag = this.TagList.Where(p => p.Type == 9).Last();
     61  
     62                 byte[] tmp = new byte[4];
     63  
     64                 tmp[3] = tag.TimeEx;
     65  
     66                 tmp[0] = tag.Time[2];
     67  
     68                 tmp[1] = tag.Time[1];
     69  
     70                 tmp[2] = tag.Time[0];
     71  
     72                 return new TimeSpan(0, 0, 0, 0, BitConverter.ToInt32(tmp, 0));
     73  
     74             }
     75  
     76         }
     77  
     78     }
     79  
     80     /**//// <summary>
     81  
     82     /// 文件头
     83  
     84     /// </summary>
     85  
     86     public class FLVHeader
     87  
     88     {
     89  
     90         public FLVHeader()
     91  
     92         {
     93  
     94             this.Type = new byte[3];
     95  
     96             this.Length = new byte[4];
     97  
     98         }
     99  
    100         /**//// <summary>
    101  
    102         /// 3byte 总是FLV(0x46 0x4C 0x56)
    103  
    104         /// </summary>
    105  
    106         public byte[] Type { get; set; }
    107  
    108         /**//// <summary>
    109  
    110         /// 版本 一般是0x01,表示FLV version 1
    111  
    112         /// </summary>
    113  
    114         public byte Version{ get; set; }
    115  
    116         /**//// <summary>
    117  
    118         /// 流信息 倒数第一bit是1表示有视频,倒数第三bit是1表示有音频
    119  
    120         /// </summary>
    121  
    122         public byte Stream { get; set; }
    123  
    124         /**//// <summary>
    125  
    126         /// 长度 4byte
    127  
    128         /// </summary>
    129  
    130         public byte[] Length { get; set; }
    131  
    132     }
    133  
    134     public class FLVTag
    135  
    136     {
    137  
    138         public FLVTag()
    139  
    140         {
    141  
    142             this.PreviousTagSize = new byte[4];
    143  
    144             this.DataLength = new byte[3];
    145  
    146             this.Time = new byte[3];
    147  
    148             this.streamsID = new byte[3];
    149  
    150         }
    151  
    152         /**//// <summary>
    153  
    154         /// 前一个Tag长度 4byte
    155  
    156         /// </summary>
    157  
    158         public byte[] PreviousTagSize { get; set; }
    159  
    160         /**//// <summary>
    161  
    162         ///  8 -- 音频tag 9 -- 视频tag 18 -- 脚本tag
    163  
    164         /// </summary>
    165  
    166         public byte Type { get; set; }
    167  
    168         /**//// <summary>
    169  
    170         /// 数据区长度 3byte
    171  
    172         /// </summary>
    173  
    174         public byte[] DataLength { get; set; }
    175  
    176         /**//// <summary>
    177  
    178         /// 时间戳 3byte 毫秒
    179  
    180         /// </summary>
    181  
    182         public byte[] Time { get; set; }
    183  
    184         /**//// <summary>
    185  
    186         /// 扩展时间戳 3byte 毫秒 作为时间戳的高位
    187  
    188         /// </summary>
    189  
    190         public byte TimeEx { get; set; }
    191  
    192         /**//// <summary>
    193  
    194         /// 一般为0 3byte
    195  
    196         /// </summary>
    197  
    198         public byte[] streamsID { get; set; }
    199  
    200         /**//// <summary>
    201  
    202         /// 
    203         /// </summary>
    204  
    205         public byte[] Data { get; set; }
    206  
    207     }
    208  
    209     public static class FlvInfoHelper
    210  
    211     {
    212  
    213         public static FlvInfo Read(string Path)
    214  
    215         {
    216  
    217             using (FileStream fs = File.OpenRead(Path))
    218  
    219             {
    220  
    221                 FlvInfo aFlvInfo = new FlvInfo();
    222  
    223                 fs.Read(aFlvInfo.Header.Type, 0, aFlvInfo.Header.Type.Length);
    224  
    225                 aFlvInfo.Header.Version=(byte)fs.ReadByte();
    226  
    227                 aFlvInfo.Header.Stream = (byte)fs.ReadByte();
    228  
    229                 fs.Read(aFlvInfo.Header.Length, 0, aFlvInfo.Header.Length.Length);
    230  
    231                 byte[] previoustagsize=new byte[4];
    232  
    233                 while (fs.Read(previoustagsize, 0, previoustagsize.Length) != 0)
    234  
    235                 {
    236  
    237                     FLVTag Tag = new FLVTag();
    238  
    239                     Tag.PreviousTagSize = previoustagsize;
    240  
    241                     Tag.Type = (byte)fs.ReadByte();
    242  
    243                     fs.Read(Tag.DataLength, 0, Tag.DataLength.Length);
    244  
    245                     fs.Read(Tag.Time, 0, Tag.Time.Length);
    246  
    247                     Tag.TimeEx = (byte)fs.ReadByte();
    248  
    249                     fs.Read(Tag.streamsID, 0, Tag.streamsID.Length);
    250  
    251                     byte[] tmp = new byte[4];
    252  
    253                     tmp[3] = 0;
    254  
    255                     tmp[2] = Tag.DataLength[0];
    256  
    257                     tmp[1] = Tag.DataLength[1];
    258  
    259                     tmp[0] = Tag.DataLength[2];
    260  
    261                     int n=System.BitConverter.ToInt32(tmp, 0);
    262  
    263                     fs.Seek(n, SeekOrigin.Current);
    264  
    265                     aFlvInfo.TagList.Add(Tag);
    266  
    267                 }
    268  
    269                 return aFlvInfo;
    270  
    271             }
    272  
    273             return null;
    274  
    275         }
    276  
    277     }
    278  
    279 }
    280  
  • 相关阅读:
    计算机组成原理小结
    selenium基本操作
    selenium实现网易邮箱的登录注册
    如何安装selenium框架
    2020年目标
    个人对软件测试的认识
    java b2b2c电商系统javashop7.2发布
    基于脚本引擎的运费架构分享
    模拟支付宝微信回调
    Javashop电商系统7.2发布
  • 原文地址:https://www.cnblogs.com/xyzhuzhou/p/2820474.html
Copyright © 2011-2022 走看看