【问题标题】:Video for Windows - Adding Audio Stream to AVI适用于 Windows 的视频 - 将音频流添加到 AVI
【发布时间】:2011-11-02 02:48:39
【问题描述】:

我有一个非常简单的程序,将音频流添加到具有预先存在的视频流的 avi 文件中。 问题是生成的文件包含视频流,但流中似乎没有任何数据。 音频文件由 SDKwavefile 从 DirectX 示例中读取。

AVIFileInit();

PAVIFILE avi;
AVIFileOpen(&avi, argv[1], OF_WRITE, NULL);

CWaveFile wav;
wav.Open(argv[2], NULL, WAVEFILE_READ);
WAVEFORMATEX *wavFormat = wav.GetFormat();

PAVISTREAM audioStream;
AVIFileCreateStream(avi, &audioStream, &audioInfo);

AVISTREAMINFO audioInfo;
memset(&audioInfo, 0, sizeof(AVISTREAMINFO));
audioInfo.fccType = streamtypeAUDIO;
audioInfo.dwScale = wavFormat->nBlockAlign;
audioInfo.dwRate = wavFormat->nSamplesPerSec * wavFormat->nBlockAlign;
audioInfo.dwSampleSize = wavFormat->nBlockAlign;
audioInfo.dwQuality = (DWORD)-1;
AVIStreamSetFormat(audioStream, 0, wavFormat, sizeof(WAVEFORMATEX));

BYTE *data = (BYTE *)malloc(wav.GetSize());
DWORD sizeRead;
wav.Read(data, wav.GetSize(), &sizeRead);
AVIStreamWrite(audioStream, 0, (wav.GetSize() * 8) / wavFormat->wBitsPerSample, data, wav.GetSize(), 0, NULL, NULL);

AVIStreamRelease(audioStream);

free(data);

wav.Close();

AVIFileRelease(avi);
AVIFileExit();

(另外,我知道我不应该再使用 VFW,但这个决定超出了我的想象。而且我知道我不会检查任何结果,这可能会在以后出现。)

谢谢。

【问题讨论】:

    标签: c++ avi vfw


    【解决方案1】:

    我尝试使用它来将 .wav 添加到现有的 .avi 中(尽管我有一个 CWaveSoundRead 类)。 如果你检查返回码,你会到达 AVIStreamWrite(),它返回 0x80044065,结果是 AVIERR_UNSUPPORTED。

    事后看来,我会说您在填写 AVISTREAMINFO 对象之前调用了 AVIFileCreateStream()。实际上,现在我看到了,很难想象您的代码会按原样编译,因为 audioInfo 是在 AVIFileCreateStream 之后定义的!

    这是我做的,虽然它仍然错误的音频流长度:

    struct FmtChunk { 
      char id[4];            //="fmt "
      unsigned long size;              //=16 or 0x28
      short wFormatTag;       //=WAVE_FORMAT_PCM=1
      unsigned short wChannels;        //=1 or 2 for mono or stereo
      unsigned long  dwSamplesPerSec;  //=11025 or 22050 or 44100
      unsigned long  dwAvgBytesPerSec; //=wBlockAlign * dwSamplesPerSec
      unsigned short wBlockAlign;      //=wChannels * (wBitsPerSample==8?1:2)
      unsigned short wBitsPerSample;   //=8 or 16, for bits per sample
    };
    
    struct DataChunk { 
      char id[4];   //="data"
      unsigned long size;    //=datsize, size of the following array
      unsigned char data[1]; //=the raw data goes here
    };
    
    struct WavChunk { 
      char id[4];   //="RIFF"
      unsigned long size;    //=datsize+8+16+4
      char type[4]; //="WAVE"
    };
    
    bool Q_AVI_AddWav(cstring fnameVideo,cstring fnameAudio)
    // Adds a .wav file to an existing .avi (with video stream)
    {
      IAVIStream* m_pStreamAudio=0;
      HRESULT hr;
    
      AVIFileInit();
    
      PAVIFILE avi;
      hr=AVIFileOpen(&avi, fnameVideo,OF_WRITE,NULL);
      CHECK(hr,"AVIFileOpen");
    
      WavChunk wav;
      FmtChunk fmt;
      DataChunk dat;
    
      //read wav file
      FILE *fr;
      int   pos;
    
      fr=qfopen(fnameAudio,"rb");
    
      // Read header
      fread(&wav,1,sizeof(wav),fr);
    
      // Read 'fmt' chunk; may be 16 or 40 in length
      pos=ftell(fr);
      fread(&fmt,1,sizeof(fmt),fr);
      if(fmt.size==40)fseek(fr,40-16,SEEK_CUR); // Skip rest of fmt
      // else it's ok
    
      // Read data specs
      fread(&dat,sizeof(dat),1,fr);
      char *buf = new char[dat.size];
      qdbg("Wav data %d bytes\n",dat.size);
      fread(buf,1,dat.size,fr);
      qfclose(fr);
    
      // set wave format info
      WAVEFORMATEX  wfx;
      wfx.wFormatTag=fmt.wFormatTag;
      wfx.cbSize=0;
      wfx.nAvgBytesPerSec=fmt.dwAvgBytesPerSec;
      wfx.nBlockAlign=fmt.wBlockAlign;
      wfx.nChannels=fmt.wChannels;
      wfx.nSamplesPerSec=fmt.dwSamplesPerSec;
      wfx.wBitsPerSample=fmt.wBitsPerSample;
    
      // create audio stream
      AVISTREAMINFO ahdr; ZeroMemory(&ahdr,sizeof(ahdr));
      ahdr.fccType=streamtypeAUDIO;
      ahdr.dwScale=wfx.nBlockAlign;
      ahdr.dwRate=wfx.nSamplesPerSec*wfx.nBlockAlign; 
      ahdr.dwSampleSize=wfx.nBlockAlign;
      ahdr.dwQuality=(DWORD)-1;
      hr=AVIFileCreateStream(avi, &m_pStreamAudio, &ahdr);
      CHECK(hr,"AVIFileCreateStream");
      if(hr!=AVIERR_OK) {if (buf) QDELETE_ARRAY(buf); /*delete[] buf;*/ return false;}
      hr = AVIStreamSetFormat(m_pStreamAudio,0,&wfx,sizeof(WAVEFORMATEX));
      CHECK(hr,"AVIStreamSetFormat");
      if(hr!=AVIERR_OK) {if (buf) QDELETE_ARRAY(buf); /*delete[] buf;*/ return false;}
    
      //write audio stream
      unsigned long numbytes = dat.size;
      unsigned long numsamps = fmt.wChannels*numbytes*8 / wfx.wBitsPerSample;
      hr = AVIStreamWrite(m_pStreamAudio,0,numsamps,buf,numbytes,0,0,0);
      CHECK(hr,"AVIStreamWrite");
      qdbg("Write numsamps %d, numbytes %d\n",numsamps,numbytes);
      QDELETE_ARRAY(buf); //if(buf)delete[] buf;
    
      // Release audio stream
      AVIStreamRelease(m_pStreamAudio);
    
      // Close AVI
      hr=AVIFileRelease(avi);
      CHECK(hr,"AVIFileRelease");
    
      // Close VFW
      AVIFileExit();
    
      return hr==AVIERR_OK;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 2018-04-02
      • 2013-03-05
      相关资源
      最近更新 更多