您的位置:首页 > 编程语言 > C语言/C++

C++获取flv视频文件的播放时间

2009-12-16 11:49 561 查看
由于项目的需求,要利用C++获取flv视频文件的播放时间,网上找的资料中有php、perl、和C#实现的介绍,但试了下,效果不好,有些flv文件可以读取播放时间,而有些却不能。下面是参考过的资料:
1、
http://flixforums.com/archive/index.php/t-149.html
该资料是帮助最大的,其中有段话:
I compute the FLV duration from the encoded FLV itself. The FLV file format is documented at Macromedias site. Basically validate the FLV header and determine if there is a video stream or only audio. Then seek to the end of the file and read the UI32 there which is the size of the last tag, then keep seeking backwards skipping over tags until you find a video (or audio if no video) tag, skip forward a UI24 (tag size) then read a UI24 and UI8 - this is the last timestamp (a big endian UI24 followed by UI8 which is the upper byte) and this is the duration in milliseconds.
It would be nice if FlixEngine had an API to get this directly since it obviously knows.
(大概的意思是通过获取最后一个视频tag段中的timestamp就是视频播放的时间)

2、
adobe官方网对flv文件格式的说明:
video_file_format_spec_v10.pdf
这是最原始的资料,不必多说了。
3、
http://blog.csdn.net/eleele/archive/2009/09/06/4525457.aspx(该资料对理解flv文件结构帮助不小,但是对文中提到的获取播放时间的方法是不可取的,因为脚本段中的duration描述的不准确)
(以上均为个人见解,仅供参考)
================================
C++获取flv视频播放时间代码:

//表示为FLV格式的文件
 flvinfo flvinfo1;
 UINT32 taglen,filelen,len;
 type=FLV;

 ifile.seekg(0,ios::beg);

 //读取FLV头
 ifile.read((char *)data,9);
 memcpy(flvinfo1.signature,data,3);
 flvinfo1.signature[3]='/0';
 flvinfo1.version=data[3];
 flvinfo1.typeflag=data[4];
 flvinfo1.dataoffset = str2ulong(data + 5);

 //判断是否存在视频信息
 if(flvinfo1.typeflag & 0x01)
 {//表示存在视频数据
 
  //将文件指针移到0文件末尾最后4个字节处
  ifile.seekg(-4,ios::end);
  filelen = ifile.tellp();
  len=4;    
  while(len<filelen)
  {
   ifile.read((char *)data,4);
   taglen = str2ulong(data);
   len=len+taglen;    
     
   //将指针移到当前tag段的开头
   ifile.seekg(-1 * len,ios::end); 
   ifile.read((char *)data,11);
   if(*(data)==9)
   {
    fsize = str2UINT24(data+4)/1000 ;
    break;
   }
   //矫正指针位置
   ifile.seekg(-15,ios::cur);
   len+=4;
  }    
 }
 else
 {
  fsize=0;
 }
===================================
程序中所用到的结构体和函数说明如下:
//flv文件结构体说明
struct flvinfo
{
 UINT8 signature[4];
 UINT8 version;
 UINT8 typeflag;
 UINT32 dataoffset;
};
//flv文件tag结构
struct flvtag
{
 UINT32 tagtype;
 UINT32 datasize;
 UINT32 timestamp;
 UINT32 timestampextended;
 UINT32 streamID;
};

//高位存放在低位
static unsigned long str2ulong(unsigned char *str)
{
   return ( str[3] | (str[2]<<8) | (str[1]<<16) | (str[0]<<24) );
}
static unsigned short str2usint(unsigned char *str)
{
   return ( str[1] | (str[0]<<8) );
}
static unsigned long str2UINT24(unsigned char *str)
{
   return ( str[2] | (str[1]<<8) | (str[0]<<16) );
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  flv c++ video ui ios file