最近跟着师傅在搞一个项目,有一块任务是这样的:要从服务器上将视频数据下载下来并播放。
原本没什么难的,可是偏偏这个视频格式不是普通的视频格式,是一位老师自定义的一个视频格式,现成的播放器是不能播放的,因为视频帧都是老师自己定义的,文件的后缀为.YTV,我的任务是要做一个程序(不管用什么语言来写,能用就行)来对视频进行解码转换成windows mediaplayer可以播放的格式(因为我的播放软件调用的就是wmplayer),问题比较烦,而且我对视频这方面什么都不了解,看了几天还是没头绪,求大侠指教啊
上传点老师给我的文件给大家看下,希望能有所帮助1. YTV文件格式
    文件由文件头(YTV_FILE_HEADER)+文件内容(一个个音频帧或者视频帧(每帧长度不定, 存储格式相同))组成,其中任意一帧由3个部分组成,分别为ID&Len(32位整数), Stamp (32位整数),frame data(Len个字节),还有就是ID&Len的一些具体情况介绍,因为比较麻烦,不好说。2. 文件头  YTV_FILE_HEADER的定义typedef struct {
int file_flag; //   =“YTV_”
int file_ver ; //   = “1.00”
int file_time;     //录像的时刻 , 通过 time(&t)获得的时间值. 
int file_total_ms;  //总时长 ms
        char file_des[256];  //文件描述,备注
        char file_user[30];  //用户名称
int video_fps;     //视频帧率,作为参考
int audio_included; //包含音频
int video_total_frames; //总的视频帧数目
int audio_total_frames;//总的音频帧数目
BITMAPINFOHEADER bih; //视频格式(用于显示)
WAVEFORMATEX     wf;//音频格式(用于播放)
} YTV_FILE_HEADER;3. 文件读取样例代码int makeint(char *str)  
{
int v;
char *p = (char*)&v;
p[0]=str[0];p[1]=str[1]; p[2]=str[2];p[3]=str[3];
return v;
}bool ReadYTV( char * filename)
{
  FILE * m_fp_videofile = NULL ; 
YTV_FILE_HEADER h; 
int  video_frames_read =0, audio_frames_read =0;
int  len, vstamp,astamp;
char isKeyFrm ; 
…..
//打开
    m_fp_videofile = fopen(filename,"rb");
if(!m_fp_videofile) {
AfxMessageBox("视频文件打开失败!");
return false;
}
//读文件头
fread(&h, sizeof(YTV_FILE_HEADER),1,m_fp_videofile);
if(h.file_flag!=makeint("YTV_")) {
AfxMessageBox("视频文件格式错误!");
fclose(m_fp_videofile); m_fp_videofile= NULL;
return false;
}while(1) 
{
//读取帧长度
res = fread(&len,sizeof(int),1,m_fp_videofile);
//碰到文件尾部
if(res<=0) {
        //文件结束的处理…………
break; 
} //视频帧
if(len&0x80000000) // video
{
isKeyFrm =(len>>24)&0x01; //是关键帧
len=len&0x00FFFFFF; 
fread(&vstamp,sizeof(int),1,m_fp_videofile);   //读时间辍
fread(vbuf,1,len,m_fp_videofile) ;  //读视频内容.
video_frames_read ++; //用于显示进度
…….
  }
else 
//音频帧
{
len=len&0x00FFFFFF; 
fread(&astamp,sizeof(int),1,m_fp_videofile);   //读时间辍
fread(abuf,1,len,m_fp_videofile) ;  //读音频内容.
audio_frames_read ++;  //用于显示进度
……..
}
}
  fclose(m_fp_videofile);
return true;
}

解决方案 »

  1.   

    总得知道frame data和其他格式的音视频数据有什么关系吧
      

  2.   

    你把YTV的文件头替换成播放器可播的文件头,可以到网上搜搜,比如:avi的文件头,然后用avi的文件播放器试试
      

  3.   

    唉,在这方面我就是个白痴,从没接触过,可以说是什么都不知道,看了半天网上资料,都是介绍各种视频格式历史还有什么YUV之类的原理,还是不懂啊,我快疯掉了
      

  4.   

    关键在于windows mediaplayer播放格式与你的YTV的格式区别,找出来后就简单了!
      

  5.   

    首先你要知道播放器能不能波那个文件它是先判断文件头和它定义的头是不是一样的,所以你要播放你们定义的文件,你就要先把文件头该了,因为视频文件也是一个文件,你现在网上搜到那个播放器可波的文件头,比如avi的文件头,然后你肯定知道你们老师定的文件头长度,假如为n,所以你播文件的时候先播你查到的文件头,然后再从你要播的文件n的位置开始播,这不是改程序,只是改变你开始读的位置
      

  6.   

    你用 vlc 试一下,能不能播,因为对于某些编码,播放器可以自己找帧数据的,试试就知道了,
      

  7.   

    这种帧序列的视频播放,还是自己直接绘制的好,不然无论怎么转换,都是平白的浪费资源
    要求一定要用wmplayer播放么?
      

  8.   

    windows media player要能播放自定义格式的文件,你需要为windows media player写filter,
    具体如何做,你看看directshow的sample. 
    我们的视频文件也是自定义格式的,就是自己开发个filter,注册下,windows media player就能自动播放了。