2011-08-23 4 views
1

저는 기존의 비디오 스트림이있는 avi 파일에 오디오 스트림을 추가하는 간단한 프로그램을 추가했습니다. 문제는 결과 파일에 비디오 스트림이 있지만 스트림에 데이터가없는 것입니다. 오디오 파일은 DirectX 샘플에서 SDKwavefile에 의해 읽혀집니다.Windows 용 비디오 - AVI에 오디오 스트림 추가

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를 사용하지 않아야 알고 있지만 그 결정은 내 머리 위에 길을 간다. 그리고 내가 나중에 올 수있는 일의 결과를 점검, 아니에요 알고있다.)

감사합니다.

답변

3

기존의 .avi에 .wav를 추가하기 위해이 클래스를 사용하려고 시도했지만 (클래스 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; 
}