(Web) Camera API

Just starting out? Need help? Post your questions and find answers here.
User avatar
Frontier
User
User
Posts: 74
Joined: Thu Dec 22, 2005 2:43 pm
Location: Chios, Greece
Contact:

(Web) Camera API

Post by Frontier »

Hello,

I am writing a small application (for free) that will be used for training and learning classes for a non-commercial organization that I support in my area. What I would like to do is to grab video and pictures from a web camera and stream them over the internet. The idea is that the teacher could see the student - and the opposite - while they are in the middle of a course, without having them at the same physical area.

So far I have a simple framework for exchanging information between the client and the server (the teacher's PC), but I cannot find any PB-like code that would allow me to use my web camera in order to fetch video from it.

I've searched the forum and some old threads came up, but either they had code that did not work (probably it was written for older versions of PureBasic or it required libraries that are no longer available). Can someone direct me to some information on how can I access the web camera API in Windows? I assume that there is some universal web camera API, so that my application will not have specific dependencies to a particular web camera brand.

Thank you very much in advance for your help.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Do a search for avicap32.dll and you should find what you are looking for. ;)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Frontier
User
User
Posts: 74
Joined: Thu Dec 22, 2005 2:43 pm
Location: Chios, Greece
Contact:

Post by Frontier »

Thank you very much for the help Sparkie, it works fine :D

May I ask another similar question? Is it possible to capture sound together with video using the avicap library?

Many thanks in advance.
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

No you can't, avicap isn't designed for this.

You should use the winmm.dll (do a little forum search for examples) or MCI commands, or externals libs like fmod, bass.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@Frontier: Can I assume you are using an audio source other than your webcam's mic?
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Frontier
User
User
Posts: 74
Joined: Thu Dec 22, 2005 2:43 pm
Location: Chios, Greece
Contact:

Post by Frontier »

Sparkie wrote:@Frontier: Can I assume you are using an audio source other than your webcam's mic?
Possibly but it would be nice if I could have the option to choose the audio source (like MSN does).
Flype wrote:No you can't, avicap isn't designed for this.

You should use the winmm.dll (do a little forum search for examples) or MCI commands, or externals libs like fmod, bass.
I was afraid that this might be a limitation. MCI is supposed to utilize the video/audio input/output services in Windows, right? For the sake of compatibility (the target OS is Windows XP tablet edition) I think I have to stick to MCI commands, but I do not know if it will support what I'm trying to do.

Again, thank you very much for your time and input regarding my issue.
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

finally, i'm not so sure that avicap can't record audio.

first, if you intend to use seriously avicap32 you should refer to the official documentation here :
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

and, while reading a little i found this :
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

so it might be possible, to be confirmed...
Last edited by Flype on Wed May 21, 2008 6:57 pm, edited 1 time in total.
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

ok, just sorry (msdn's your friend).

actually there's a callback for catching sound :

capWaveStreamCallback(*hWnd, *lpWHdr.WAVEHDR)

just like the video callback :

capVideoStreamCallback(*hWnd, *lpVHdr.VIDEOHDR)
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I have no problem capturing audio with my webcam using avicap. I'll take a closer look when I get home and have the code in front of me.
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Frontier
User
User
Posts: 74
Joined: Thu Dec 22, 2005 2:43 pm
Location: Chios, Greece
Contact:

Post by Frontier »

Thank you very much for the help.

If you have some source code to share, please do so as it would help me understand better the underlying avicap API.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Here's a thread from 2004 that you can take a look at. http://www.purebasic.fr/english/viewtopic.php?t=11401

I do have fresh code for PB 4.x but I need to clean it up before I post it. It's pretty much the same as the '04 code with less clutter, as most of the #WM_CAP* constants are now pre-defined in PB 4.x. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

Heya Sparkie, that sounds nice. Post it when ready... please? :-)
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

I've got one other priority to work on and then I'll come back here and post the code. My new code isn't all that much different from my original code from 2004. :wink:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Ok, here's what I've got for you. It is not a full featured capture program by any means. It's just to show you the basics of capturing from a webcam. Use your imagination and skills to build off of this code snippet. 8)

This quickie GUI is best suited for 320 x 240 capture window. Also, this has only been tested on XP so let me know how Vista handles it. ;)

Code: Select all

#IDS_CAP_END = 301

#MicroSecond = 1000000

Enumeration
  #Window_0
EndEnumeration

Enumeration
  #Stream_0
  #Frame_0
  
EndEnumeration

Structure MYCAPSTATUS
  uiImageWidth.l
  uiImageHeight.l
  fLiveWindow.l
  fOverlayWindow.l
  fScale.l
  ptScroll.POINT
  fUsingDefaultPalette.l
  fAudioHardware.l
  fCapFileExists.l
  dwCurrentVideoFrame.l
  dwCurrentVideoFramesDropped.l
  dwCurrentWaveSamples.l
  dwCurrentTimeElapsedMS.l
  hPalCurrent.l
  fCapturingNow.l
  dwReturn.l
  wNumVideoAllocated.l
  wNumAudioAllocated.l
EndStructure


Structure MYCAPDRIVERCAPS 
  wDeviceIndex.l
  fHasOverlay.l
  fHasDlgVideoSource.l
  fHasDlgVideoFormat.l
  fHasDlgVideoDisplay.l
  fCaptureInitialized.l
  fDriverSuppliesPalettes.l
  hVideoIn.l
  hVideoOut.l
  hVideoExtIn.l
  hVideoExtOut.l
EndStructure 

Structure MYCAPTUREPARMS
dwRequestMicroSecPerFrame.l
fMakeUserHitOKToCapture.l
wPercentDropForError.l
fYield.l
dwIndexSize.l
wChunkGranularity.l
fUsingDOSMemory.l
wNumVideoRequested.l
fCaptureAudio.l
wNumAudioRequested.l
vKeyAbort.l
fAbortLeftMouse.l
fAbortRightMouse.l
fLimitEnabled.l
wTimeLimit.l
fMCIControl.l
fStepMCIDevice.l
dwMCIStartTime.l
dwMCIStopTime.l
fStepCaptureAt2x.l
wStepCaptureAverageFrames.l
dwAudioBufferSize.l
fDisableWriteCache.l
AVStreamMaster.l
EndStructure

mycapDriver.MYCAPDRIVERCAPS
mycapSetup.MYCAPTUREPARMS

;...I'll capture ~15 frames per sec
mycapSetup\dwRequestMicroSecPerFrame = #MicroSecond / 15
mycapSetup\fYield = #True
;...Max frames captured
mycapSetup\dwIndexSize = 1800
mycapSetup\fCaptureAudio = #True
;...Press Esc to stop capture
mycapSetup\vKeyAbort = #VK_ESCAPE
;...I'll auto end capture after 10 seconds
mycapSetup\fLimitEnabled = #True
mycapSetup\wTimeLimit = 10

Procedure CapStatusCallback(hwnd.l, nId.l, lpsz.l)
  result = #True
  If nId = #IDS_CAP_END
    StatusBarText(0, 0, "Capture ended")
    DisableGadget(0, 0)
    DisableGadget(1, 0)
    DisableGadget(2, 0)
    DisableGadget(3, 1)
    DisableGadget(4, 0)
    DisableGadget(5, 0)
  Else
    StatusBarText(0, 1, PeekS(lpsz))
  EndIf
  ProcedureReturn result
EndProcedure

Procedure CapYieldCallback(hwnd.l)
  result = #True
  ProcedureReturn result
EndProcedure

;...Path to saved stream capture
capStream$ = "c:\cap_stream.avi"

;...Path to saved frame capture
capFrame$ = "c:\cap_frame.bmp"

If OpenWindow(0, 0, 0, 685, 325, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) 
  If CreateStatusBar(0, WindowID(0))
    AddStatusBarField(135)
    AddStatusBarField(550)
    StatusBarText(0, 0, "")
    StatusBarText(0, 1, "")
  EndIf
  
  If CreateGadgetList(WindowID(0))
    ButtonGadget(0,10,10,90,20,"Select Format")
    ButtonGadget(1,110,10,90,20,"Select Source")
    ButtonGadget(2,210,10,90,20,"Capture Stream")
    ButtonGadget(3,310,10,90,20,"Stop Capture")
    DisableGadget(3, 1)
    ButtonGadget(4,410,10,90,20,"Capture Frame")
    ButtonGadget(5,510,10,90,20,"Save Frame...")
    ImageGadget(6, 350, 40, 320, 240, 0)
  EndIf
EndIf

If OpenLibrary(1, "C:\WINDOWS\system32\avicap32.dll")
  *capAddress = GetFunction(1, "capCreateCaptureWindowA")
  hWndC = CallFunctionFast(*capAddress, "My Capture Window", #WS_BORDER |#WS_CHILD | #WS_VISIBLE, 15, 40, 320, 240, WindowID(0),10)
  CloseLibrary(0)
  SendMessage_(hWndC, #WM_CAP_DRIVER_CONNECT, 0, 0)
  SendMessage_(hWndC, #WM_CAP_SET_PREVIEW, #True, 0)
  SendMessage_(hWndC, #WM_CAP_SET_PREVIEWRATE, 30, 0)
  SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_YIELD, 0, @CapYieldCallback())
  SendMessage_(hWndC, #WM_CAP_SET_CALLBACK_STATUS, 0, @CapStatusCallback())
  ;...Open a dialog to select video format
  SendMessage_(hWndC, #WM_CAP_DLG_VIDEOFORMAT, 0, 0)
  UpdateWindow_(hWndC)
Else
  MessageRequester("Error", "Could not open avicap32.dll", #PB_MessageRequester_Ok | #MB_ICONERROR)
EndIf

quit = #False

Repeat 
  
  event = WaitWindowEvent() 
  
  Select event
    
    Case #PB_Event_Gadget
      
      Select EventGadget()
        ;...Select video format
        Case 0
          SendMessage_(hWndC, #WM_CAP_DLG_VIDEOFORMAT, 0, 0)
          UpdateWindow_(hWndC)
          
        ;...Select capture source  
        Case 1
         SendMessage_(hWndC, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
        
        ;...Start capture stream
        Case 2
          DisableGadget(0, 1)
          DisableGadget(1, 1)
          DisableGadget(2, 1)
          DisableGadget(3, 0)
          DisableGadget(4, 1)
          DisableGadget(5, 1)
          
          ;...Clean up our previous stream capture
          If FileSize(capStream$)
            DeleteFile(capStream$)
          EndIf
          
          StatusBarText(0, 0, "Capturing to " + capStream$)
          StatusBarText(0, 1, "Press Esc To stop capture")
          SendMessage_(hWndC, #WM_CAP_SET_SEQUENCE_SETUP, SizeOf(MYCAPTUREPARMS), @mycapSetup)
          SendMessage_(hWndC, #WM_CAP_FILE_SET_CAPTURE_FILEA, 0, capStream$)
          SendMessage_(hWndC, #WM_CAP_SEQUENCE, 0, 0)
          StatusBarText(0, 0, "Press Esc to stop capture")
         
        ;...End capture stream  
        Case 3
          SendMessage_(hWndC, #WM_CAP_STOP, 0, 0)
          DisableGadget(0, 0)
          DisableGadget(1, 0)
          DisableGadget(2, 0)
          DisableGadget(2, 1)
          DisableGadget(4, 0)
          DisableGadget(5, 0)
          StatusBarText(0, 0, "Capture ended")
          
        ;...Capture still frame
        Case 4
          SendMessage_(hWndC, #WM_CAP_FILE_SAVEDIBA, 0, capFrame$)
          LoadImage(0, capFrame$)
          ResizeImage(0, 320, 240)
          SetGadgetState(6, ImageID(0))
          
        ;...Save captured still frame  
        Case 5
          saveFrame$ = SaveFileRequester("Save Captured Frame", "c:\myframe.bmp", "Image *.bmp", 0) 
          If saveFrame$
            SaveImage(0, saveFrame$)
          EndIf
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      SendMessage_(hWndC, #WM_CAP_STOP, 0, 0)
      SendMessage_(hWndC, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
      DestroyWindow_(hWndC)
      quit = #True
      
  EndSelect
  
Until quit = #True

End
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Frontier
User
User
Posts: 74
Joined: Thu Dec 22, 2005 2:43 pm
Location: Chios, Greece
Contact:

Post by Frontier »

Thanks for the code Sparkie, I will try it and post results :D
Post Reply