介绍下mp3写入avi文件的方法
来源:互联网 发布:淘宝订单信息 编辑:程序博客网 时间:2024/05/27 21:48
先介绍几个api函数:
AVIFileOpen
AVIFileCreateStream
AVIStreamSetFormat
AVIStreamWrite
字面意思大家都应该理解,就不多说了。AVIFileCreateStream ,AVIStreamSetFormat这两个东西很重要,对于流方式操作大家都明白,可是设置流的格式不一定懂,这个是api根据avi文件格式提出的一个特殊概念,因为avi如同一个建立好的抽屉,每个抽屉里面放什么东西,需要个说明,这个AVIStreamSetFormat就是在写入数据前先写个标签进去,以方便播放器调用正确的解码。
OpenMp3File的功能是打开mp3文件,并读取一个帧的帧头信息,本程序只考虑了bitrate恒定的mp3的读写,不考虑变体。
对于mp3帧头的读写,大家可以在网上找mp3格式自己解读,如果有需要详细说明的朋友,请留言。
BOOL AddMp3ToAvi(const char *pStrAvi,const char *pStrMp3,int StartTime)
{
PAVIFILE aviFile;
FILE* mp3File;
DscHeader fHeader;
/*打开AVIFILE和MP3 FILE,进行时间判断*/
int Ret = AVIFileOpen(&aviFile,pStrAvi,OF_READWRITE|OF_SHARE_EXCLUSIVE,NULL);
if(Ret != 0)
{
AfxMessageBox("Failed to Open the AVI File!");
return FALSE;
}
mp3File = OpenMp3File(pStrMp3,&fHeader);
if(mp3File == NULL)
{
AfxMessageBox("Failed to Open the MP3 File!");
AVIFileRelease(aviFile);
return FALSE;
}
/*获得 AVI 视频流的信息*/
PAVISTREAM videoStream;
AVIFileGetStream(aviFile,&videoStream,streamtypeVIDEO,0);
VERIFY(videoStream);
/*获得相配的MP3 祯数:26ms / frame*/
double VideoFrmTime = (double) AVIStreamLengthTime(videoStream) / AVIStreamLength(videoStream);
/*新建音频流为写入作准备*/
PAVISTREAM audioStream;
AVISTREAMINFO audioInf;
ZeroMemory(&audioInf,sizeof(AVISTREAMINFO));
audioInf.fccType = streamtypeAUDIO;
audioInf.dwRate = (fHeader.dwBitRate *1000) / 8;
//Ret = *fHeader.dwChannel;
audioInf.dwScale =1;
audioInf.dwSampleSize = 1;
audioInf.dwQuality = (DWORD)-1;
Ret = AVIFileCreateStream(aviFile,&audioStream,&audioInf);
#ifdef _DEBUG
if(Ret != 0)
{
TRACE("AVIFileCreateStream Failure!!/n");
}
#endif
MPEGLAYER3WAVEFORMAT mp3fmt;
ZeroMemory(&mp3fmt,sizeof(MPEGLAYER3WAVEFORMAT));
mp3fmt.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3 ;
mp3fmt.wfx.nChannels = fHeader.dwChannel;
mp3fmt.wfx.nSamplesPerSec = fHeader.dwSampleRate;
mp3fmt.wfx.wBitsPerSample = 0;
mp3fmt.wfx.nAvgBytesPerSec = audioInf.dwRate ;
mp3fmt.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;/**/
mp3fmt.wfx.nBlockAlign = 1;// ((fHeader.dwBitRate *1000 )/ fHeader.dwSampleRate);// (0 ==Ret)? 1:Ret;;
mp3fmt.wID = 1;
mp3fmt.fdwFlags = 2;
mp3fmt.nBlockSize = fHeader.dwFSize;
mp3fmt.nFramesPerBlock = 1;
mp3fmt.nCodecDelay = 0 ;
Ret = AVIStreamSetFormat(audioStream,0,&mp3fmt,sizeof(MPEGLAYER3WAVEFORMAT));
#ifdef _DEBUG
if(Ret != 0)
{
TRACE("Set Avi Mp3 Format Failure!!/n");
}
#endif
int frSize;
int audioFrmNum =0;
double escTime = 0;
double blocktimesize = (double)1000.0 * ((fHeader.dwVersion == VERSION1)?1152:576) / fHeader.dwSampleRate ;
char *buf = new char[2048];
#ifdef _DEBUG
static double vtotal;
static double atotal;
#endif
//int num = AVIStreamLength(videoStream);
//int CacheFrames = 0;//(AVIStreamLength(videoStream) > 1000)?(int)(1000/VideoFrmTime):2 ;/*一秒钟的缓冲*/
for(int i =AVIStreamStart(videoStream);i <AVIStreamEnd(videoStream);i++ )
{
#ifdef _DEBUG
vtotal += VideoFrmTime;
#endif
escTime += VideoFrmTime;
while(1)
{
if(escTime -blocktimesize <0)
break;
frSize = fHeader.dwFSize;
if(GetMp3Frame(mp3File,(UCHAR *)buf,&fHeader) == ENDFILE)
{
AVIStreamWrite(audioStream,audioFrmNum,1,buf,frSize,AVIIF_KEYFRAME,NULL,NULL);
goto L;
}
Ret = AVIStreamWrite(audioStream,audioFrmNum,1,buf,frSize,NULL,NULL,NULL);
escTime -= blocktimesize;
#ifdef _DEBUG
atotal += blocktimesize;
#endif
audioFrmNum++;
#ifdef _DEBUG
if(Ret != 0)
{
TRACE("Write To Avi Failure:%d!!/n",Ret);
break;
}
#endif
}
}
L:
fclose(mp3File);
AVIStreamRelease(audioStream);
AVIStreamRelease(videoStream);
AVIFileRelease(aviFile);
delete []buf;
return (Ret == 0);
- 介绍下mp3写入avi文件的方法
- opencv写入AVI文件[8]
- 使用Mplayer播放avi文件的方法
- 记录:继续探索moblin 2上的GSTREAMER:播放MP3及AVI文件
- 记录:继续探索moblin 2上的GSTREAMER:播放MP3及AVI文件
- 获取指定文件下的mp3文件
- MP3文件介绍
- MP3文件介绍
- #遍历E盘下的mp3文件
- Linux下mp3文件的乱码问题
- 修改的判断mp3文件方法
- VC中播放mp3文件的方法
- 把D:\\12.avi 复制到当前项目目录下的copy.avi中(文件流)
- xubuntu播放mp3 avi flash等多媒体文件
- linux下avi文件解析
- Ubuntu下打开.avi文件
- Windows XP下AVI文件无法直接删除的问题
- AVI文件在opencore框架下的解析
- “上海式贫困”与“北京式富裕”
- 有关调音台的专业英文词汇
- VC对话创业者
- 关于 OnCloseQuery: 顺序、不能关机等
- C#下的Webbrowser的KeyDown事件
- 介绍下mp3写入avi文件的方法
- arch 恢复 root密码
- web.xml配置详解
- 纯天然的野菜居然会致癌?
- 几种计算机语言的评价
- (转载)Linux thread 最基本用法
- MyEclipse 快捷键
- C#线程同步的几种方法
- Javascript去除字符串空格