介绍下mp3写入avi文件的方法

先介绍几个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);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值