Create AVI with Sound

Share your advanced PureBasic knowledge/code with the community.
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Create AVI with Sound

Post by Nico »

Code updated For 5.20+

Code: Select all

;/ Nico le 02/06/05
;/ Création d'un avi avec de l'audio

#streamtypeAUDIO = $73647561
#streamtypeVIDEO = $73646976
#ICMF_CHOOSE_KEYFRAME=1
#ICMF_CHOOSE_DATARATE=2
#AVIERR_OK=0
#AVIIF_KEYFRAME=$10
#Lib = 0

Structure bitmap24
  bmiHeader.BITMAPINFOHEADER
EndStructure

Structure msvc
  a.b
  b.b
  c.b
  d.b
EndStructure

Structure AVISTREAMINFO
  fccType.l
  fccHandler.msvc
  dwFlags.l
  dwCaps.l
  wPriority.w
  wLanguage.w
  dwScale.l
  dwRate.l
  dwStart.l
  dwLength.l
  dwInitialFrames.l
  dwSuggestedBufferSize.l
  dwQuality.l
  dwSampleSize.l
  rcFrame.RECT 
  dwEditCount.l
  dwFormatChangeCount.l
  szName.b[64]
EndStructure

Structure AVICOMPRESSOPTIONS
  fccType.l
  fccHandler.l
  dwKeyFrameEvery.l
  dwQuality.l
  dwBytesPerSecond.l
  dwFlags.l
  *lpFormat
  cbFormat.l
  *lpParms
  cbParms.l
  dwInterleaveEvery.l
EndStructure

;     Structure WAVEFORMATEX
;       wFormatTag.w
;       nChannels.w
;       nSamplesPerSec.l
;       nAvgBytesPerSec.l
;       nBlockAlign.w
;       wBitsPerSample.w
;       cbSize.w
;     EndStructure

NewList bitmap.s()
NewList memoire.l()


;/ Procédure traduite en Pure Basic
;/ d'un code écrit en c++ par son auteur Chiew Heng Wah.

Procedure AddWAV(strFileWAV.s, pfile.l)
  pfileWav.IAVIFILE
  siWav.AVISTREAMINFO
  psWav.IAVISTREAM 
  psAvi.l
  fmtWav.WAVEFORMATEX
  If CallFunction( #Lib, "AVIFileOpen",@pfileWav, @strFileWAV, #OF_READ, #Null)=0
    If CallFunction( #Lib, "AVIFileGetStream",pfileWav, @psWav, #streamtypeAUDIO, 0)=0
      If CallFunction( #Lib, "AVIStreamInfo",psWav, @siWav, SizeOf(AVISTREAMINFO))=0
        If CallFunction( #Lib, "AVIStreamReadFormat",psWav, 0, #Null, @lFmtSize) =0
          If lFmtSize
            If  CallFunction( #Lib, "AVIStreamReadFormat",psWav, 0, @fmtWav, @lFmtSize)=0
              lStreamLength = CallFunction( #Lib, "AVIStreamLength",psWav)
              If lStreamLength
                lpbData = AllocateMemory(lStreamLength)
                If CallFunction( #Lib, "AVIStreamRead",psWav, 0, lStreamLength, lpbData, lStreamLength, #Null, #Null)=0
                  If CallFunction( #Lib, "AVIFileCreateStream",pfile, @psAvi, @siWav)=0
                    If CallFunction( #Lib, "AVIStreamSetFormat",psAvi, 0, @fmtWav, lFmtSize)=0
                      If CallFunction( #Lib, "AVIStreamWrite",psAvi, 0, lStreamLength, lpbData, lStreamLength, #AVIIF_KEYFRAME, #Null, #Null)=0
                        val.b=1
                      EndIf
                    EndIf
                    CallFunction( #Lib, "AVIStreamRelease",psAvi)
                  EndIf
                EndIf
                FreeMemory(lpbData)
              EndIf
            EndIf
          EndIf
        EndIf
      EndIf   
      CallFunction( #Lib, "AVIStreamRelease",psWav)
    EndIf
    CallFunction( #Lib, "AVIFileRelease",pfileWav)
  EndIf
  ProcedureReturn val
EndProcedure 

Fichier.s = OpenFileRequester("Sélection multiple des Fichiers Bitmaps", "", "Fichiers BMP|*.bmp", 0, #PB_Requester_MultiSelection)
If Fichier
  Debug  Fichier
  AddElement(bitmap())
  bitmap()= Fichier
  Repeat
    Fichier = NextSelectedFileName()
    If Fichier
      AddElement(bitmap())
      bitmap()= Fichier
      Debug Fichier
    EndIf
  Until Fichier = ""
EndIf

ForEach bitmap()
  If ReadFile(0, bitmap())
    FileSeek(0,SizeOf(BITMAPFILEHEADER))
    bmi.bitmap24
    ReadData(0,@bmi, SizeOf(bitmap24))
    If  bmi\bmiHeader\biWidth
      If  bmi\bmiHeader\biHeight
        If  bmi\bmiHeader\biBitCount
          If  bmi\bmiHeader\bisizeimage=0
            bmi\bmiHeader\bisizeimage=Lof(0)-54
          EndIf
          FileSeek(0,1078)
          AddElement(memoire())
          memoire() =GlobalAlloc_(#GMEM_FIXED|#GMEM_ZEROINIT, bmi\bmiHeader\bisizeimage)
          ReadData(0,memoire(), bmi\bmiHeader\bisizeimage)
        EndIf
      EndIf
    EndIf
    CloseFile(0)
  EndIf
Next

If OpenLibrary  ( #Lib , "AVIFIL32.DLL")
  CallFunction ( #Lib,  "AVIFileInit" )
  avifile.s = SaveFileRequester ( "Nom du fichier Avi à enregistrer", "", "Video|*.avi", 0 )
  If GetExtensionPart(avifile)=""
    avifile=avifile+".avi"
  EndIf
  Debug avifile
  
  If CallFunction( #Lib, "AVIFileOpen", @pAVIFile.IAVIFILE, @avifile, (#OF_WRITE | #OF_CREATE), 0 )=0
    strhdr.AVISTREAMINFO
    strhdr\fccType                = #streamtypeVIDEO
    strhdr\fccHandler\a             = $6D
    strhdr\fccHandler\b             = $73
    strhdr\fccHandler\c             = $76
    strhdr\fccHandler\d             = $63 
    strhdr\dwScale                = 1 ;Nb de frames/secondes
    strhdr\dwRate                 = 4 ;( 1 à 30)
    strhdr\dwSuggestedBufferSize  = bmi\bmiHeader\biSize
    
    If SetRect_(@strhdr\rcFrame, 0, 0, bmi\bmiHeader\biWidth, bmi\bmiHeader\biHeight) <>0
      If CallFunction( #Lib, "AVIFileCreateStream", pAVIFile, @pAVIStream, @strhdr) =0
        opts.AVICOMPRESSOPTIONS
        Dim aopts(0)
        aopts(0)=@opts
        
        If CallFunction( #Lib, "AVISaveOptions", 0, #ICMF_CHOOSE_KEYFRAME | #ICMF_CHOOSE_DATARATE, 1, @pAVIStream, @aopts(0)) =1
          If CallFunction( #Lib, "AVIMakeCompressedStream", @pAVICompressed, pAVIStream, aopts(0), 0)=#AVIERR_OK
            If CallFunction( #Lib, "AVIStreamSetFormat", pAVICompressed, 0, @bmi, SizeOf(bitmap24)) =0
              ForEach memoire()
                If memoire()
                  If CallFunction( #Lib, "AVIStreamWrite", pAVICompressed, index, 1,  memoire() , bmi\bmiHeader\bisizeimage, #AVIIF_KEYFRAME, 0,0) =0
                    index=index+1
                  EndIf 
                EndIf
              Next
            EndIf
            CallFunction( #Lib, "AVIStreamRelease", pAVICompressed)
          EndIf
        EndIf
        CallFunction( #Lib, "AVIStreamRelease", pAVIStream )
      EndIf
      ;------------------------ Inclure le son -----------------------------------------   
      
      
      strFileWAV2.s = OpenFileRequester("Sélection d'un Fichier Audio", "", "Fichiers Wav|*.wav", 0)
      
      If AddWAV(strFileWAV2, pAVIFile)
        a$="Le fichier avi créé contient un fichier audio."
      Else
        a$="Le fichier audio n'a pu être créé."
      EndIf
      
      ;----------------------------------------
    EndIf
    CallFunction( #Lib, "AVIFileRelease", pAVIFile)
  EndIf
  CallFunction( #Lib, "AVIFileExit" )
  CloseLibrary( #Lib )
  
  ForEach memoire()
    GlobalFree_(memoire())
  Next
  MessageRequester("Info","Nombre de Frames enregistrées: "+Str(index)+Chr(13)+a$)
EndIf
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

I doesn't get any outputs !? :?
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

Are you a message info?
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

No, there wasn't any message.
I defined all the needed files and it seemed to work.
But i got no output file.
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

You have necessarily a message, look at the end of the code!
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

Oh ...This message :oops: ????
There was a "1" . But no outputfile.


Ok.

I made another try and it works.
I used now other files.
It seems to work not with every files :?


Thanks for this nice code :-)
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

I would like making attempts with your file to see what does not work!
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

Hi Nico,

thanks for your very useful code.
It seems you got a lot of skills on these API fuctions included in the avifil32.dll.

My approach is that I want to EXTRACT a Wav out of an AVI where a PCM Wav soundstream is included.

How should that be done?

My actual approach is in the code below, .... but it doesnt work, means no ErrorMessage via Messagerequester is shown, BUT theres even no wav "file" safed on my HD. So I cant even say if such a wav out of that code below would work.

Could you give me a hand?
Mercí,
Inc.

Code: Select all

#Lib=0
 #streamtypeAUDIO = $73647561
#AVI_ERR_OK = 0
#Lib = 0
SaveCallback = 0

Procedure Avi2Wav( avifile.s, wavfile.s )

 Structure LPAVICOMPRESSOPTIONS
  fccType.l
  fccHandler.l
  dwKeyFrameEvery.l
  dwQuality.l
  dwBytesPerSecond.l
  dwFlags.l
  *lpFormat.l
  cbFormat.l
  *lpParms.l
  cbParms.l
  dwInterleaveEvery.l
EndStructure

plpOptions.LPAVICOMPRESSOPTIONS

OpenLibrary  ( #Lib , "AVIFIL32.DLL")
CallFunction ( #Lib,  "AVIFileInit" )

  res = CallFunction( #Lib, "AVIFileOpen", @pFile, avifile.s, 0, nil )
   If res = #AVI_ERR_OK
      Else
        MessageRequester( "Error!", "Cant open Avifile!",  0 )
  EndIf
 
res = CallFunction( #Lib, "AVIFileGetStream", pFile, @pAVI, #streamtypeAUDIO, 0 )
  If res = #AVI_ERR_OK
      Else
        CallFunction( #Lib, "AVIFileExit" )
        MessageRequester( "Error!", "Cant reveive Audiostream!",  0 )
  EndIf
 
res = CallFunction( #Lib, "AviSaveV", wavfile.s, nil, @SaveCallback, 1, pAVI, plpOptions) 
  If res = #AVI_ERR_OK
      Else
        CallFunction( #Lib, "AVIStreamRelease", pAVI )
        CallFunction( #Lib, "AVIFileExit" )
        MessageRequester( "Error!", "Cant safe Wavfile!",  0 )   
  EndIf
  MessageRequester( "Ready", "",  0 )
CallFunction( #Lib, "AVIStreamRelease", pAVI )
CallFunction( #Lib, "AVIFileExit" )
CloseLibrary( #Lib )
 
  EndProcedure

avifile.s = OpenFileRequester ( "Select AVI or AVS File for WAV extraction", "", "Avi, Avs|*.avi; *.avs; *.*", 0 )

wavfile.s = SaveFileRequester ( "Safe Location for WAV", "", "Wave|*.wav", 0 )
  If GetExtensionPart(wavfile)=""
    wavfile.s=wavfile.s+".wav"
  EndIf


If avifile : Avi2Wav( avifile.s, wavfile.s ) : EndIf
Nico
Enthusiast
Enthusiast
Posts: 274
Joined: Sun Jan 11, 2004 11:34 am
Location: France

Post by Nico »

Try this:

Code: Select all

; Extract Wave of Avi File
; By Nico
; PB 3.93
; le 27/06/05

#streamtypeAUDIO = $73647561 
#streamtypeVIDEO = $73646976 
#ICMF_CHOOSE_KEYFRAME=1 
#ICMF_CHOOSE_DATARATE=2 
#AVIERR_OK=0 
#AVIIF_KEYFRAME=$10 
#Lib = 0 
#AVI_ERR_OK=0


Structure msvc 
  a.b 
  b.b 
  c.b 
  d.b 
EndStructure 

Structure AVISTREAMINFO 
  fccType.l 
  fccHandler.msvc 
  dwFlags.l 
  dwCaps.l 
  wPriority.w 
  wLanguage.w 
  dwScale.l 
  dwRate.l 
  dwStart.l 
  dwLength.l 
  dwInitialFrames.l 
  dwSuggestedBufferSize.l 
  dwQuality.l 
  dwSampleSize.l 
  rcFrame.RECT  
  dwEditCount.l 
  dwFormatChangeCount.l 
  szName.b[64] 
EndStructure 

Structure WAVEFORMATEX 
  wFormatTag.w 
  nChannels.w 
  nSamplesPerSec.l 
  nAvgBytesPerSec.l 
  nBlockAlign.w 
  wBitsPerSample.w 
  cbSize.w 
EndStructure
 
;/ Procédure traduite en Pure Basic 
;/ d'un code écrit en c++ par son auteur Chiew Heng Wah.
Procedure ExtractWav(strFileWAV.s, pfile.l) 
  pfileWav.IAVIFILE 
  siWav.AVISTREAMINFO 
  psWav.IAVISTREAM  
  psAvi.l 
  fmtWav.WAVEFORMATEX 
  If CallFunction( #Lib, "AVIFileOpen",@pfileWav, @strFileWAV, #OF_READ, #Null)=0 
    If CallFunction( #Lib, "AVIFileGetStream",pfileWav, @psWav, #streamtypeAUDIO, 0)=0 
      If CallFunction( #Lib, "AVIStreamInfo",psWav, @siWav, SizeOf(AVISTREAMINFO))=0 
        If CallFunction( #Lib, "AVIStreamReadFormat",psWav, 0, #Null, @lFmtSize) =0 
          If lFmtSize 
            If  CallFunction( #Lib, "AVIStreamReadFormat",psWav, 0, @fmtWav, @lFmtSize)=0 
              lStreamLength = CallFunction( #Lib, "AVIStreamLength",psWav) 
              If lStreamLength 
                lpbData = AllocateMemory(lStreamLength) 
                If CallFunction( #Lib, "AVIStreamRead",psWav, 0, lStreamLength, lpbData, lStreamLength, #Null, #Null)=0 
                  If CallFunction( #Lib, "AVIFileCreateStream",pfile, @psAvi, @siWav)=0 
                    If CallFunction( #Lib, "AVIStreamSetFormat",psAvi, 0, @fmtWav, lFmtSize)=0 
                      If CallFunction( #Lib, "AVIStreamWrite",psAvi, 0, lStreamLength, lpbData, lStreamLength, #AVIIF_KEYFRAME, #Null, #Null)=0 
                        val.b=1 
                      EndIf 
                    EndIf 
                    CallFunction( #Lib, "AVIStreamRelease",psAvi) 
                  EndIf 
                EndIf 
                FreeMemory(lpbData) 
              EndIf 
            EndIf 
          EndIf 
        EndIf 
      EndIf    
      CallFunction( #Lib, "AVIStreamRelease",psWav) 
    EndIf 
    CallFunction( #Lib, "AVIFileRelease",pfileWav) 
  EndIf 
  ProcedureReturn val 
EndProcedure 

avifile.s = OpenFileRequester ( "Select AVI or AVS File for WAV extraction", "", "Avi or Avs|*.avi; *.avs; *.*", 0 ) 
If  avifile
  wavfile.s = SaveFileRequester ( "Safe Location for WAV", "", "Wave|*.wav", 0 )
  If wavfile
    If GetExtensionPart(wavfile)="" 
      wavfile.s=wavfile.s+".wav" 
    EndIf  
    If  OpenLibrary  ( #Lib , "AVIFIL32.DLL") 
      CallFunction ( #Lib,  "AVIFileInit" ) 
      If  CallFunction( #Lib, "AVIFileOpen", @pwavfile, @wavfile,(#OF_WRITE | #OF_CREATE),0) = #AVI_ERR_OK 
        If ExtractWav(avifile, pwavfile) 
          CallFunction( #Lib, "AVIFileRelease",pwavfile)  
          MessageRequester( "Info", "Wave extracted!",  0 )
        EndIf 
      Else
        MessageRequester( "Error!", "Cant create pwavfile!",  0 )
      EndIf
          CallFunction( #Lib, "AVIFileExit" ) 
          CloseLibrary( #Lib )
    EndIf
  EndIf 
EndIf
 
:)
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

Mercí Nico!
:)
User avatar
Falko
Enthusiast
Enthusiast
Posts: 271
Joined: Sat Oct 04, 2003 12:57 pm
Location: Germany
Contact:

Post by Falko »

Hi Nico,

sorry my little witing english but i can reading better :)

I will make a actuality sreenshots streams to an AVI.
When the AVI-API this can do, have you an excample for me?

thx ,

Falko
Post Reply