The Bare Essential Webcam Capture
Posted
#1
(In Topic #284)
Regular

Code (gambas)
- ' Gambas class file
- '=============================================================================
- myPlayer.URL = "v4l2:///dev/video1"
- myPlayer.Play()
- '=============================================================================
- '=============================================================================
- ThePictureBox.Image = theImage
- '=============================================================================
- '=============================================================================
- '=============================================================================
- '=============================================================================
Step 1. Create a GUI project
Step 2. Add a PictureBox named "ThePictureBox"
Step 3. Add a Button named "TheButton"
Step 4. Copy the Code into the main form class
TADA. You may need to use video0 on your computer.
However, there is a catch. When the Webcam window is closed first, the console output ends with "gb.media: warning: could not catch end of stream".
I haven't been able to figure out a good way to avoid this. Anybody know?
Thanks,
Ced
.... and carry a big stick!
Posted
Guru

Here is a slightly different way to do this in 4 lines of code and no error.
<IMG src="http://www.cogier.com/gambas/WebCamera.png">
</IMG>
Posted
Regular

That's handy, it looks like a higher level wrapper around a MediaPlayer.
However, I don't see a way to capture the current image to an Image object. This is a requirement for me.
Notice, that the first three code lines and the Form_Open are really the only required elements, so declaring the MediaPlayer in code vs the MediaVeiwer on the form becomes the only distinction. The other stuff I added, I considered "minimal want" as opposed to "minimal need".
.... and carry a big stick!
Posted
Regular

Hats off to Cedron for the code, and to cogier for the example project.
And I agree with you Cedron. While the high level allows this to code to be short and simple, its also limiting for those who want to use webcam video to a fuller potential.
After much Googling, I found a great Gambas project that uses gb.v4l to capture webcam video, instead of gb.media.form. Cedron, this code is a step lower in level, and may be what you're looking for in trying to capture the current image to an Image object.
Thanks and credit for this Gambas project goes to justlostintime, who uploaded it to GitHub 4 years ago.
https://github.com/justlostintime/gambas/tree/master/app/examples/Multimedia/MyWebCam
The code loads and works great in Gambas 3.13.0. However, it does crash when I stop the capture, on the line
Code (gambas)
- hWebCam = Null
Lastly, I should point out that the video source
Code (gambas)
- /dev/video0
Code (gambas)
- /dev/video1
My webcam can switch between the two at random, for no good reason. This switching would render my security software useless for hours at a time. I researched this, and found the solution is to use a symbolic link to your webcam, which never changes and can be created.
However, apparently most modern webcams will have like a "built-in" symbolic link, which has worked flawlessly for me. Its found under
Code (gambas)
- /dev/v4l/by-id
Code (gambas)
- /dev/v4l/by-id/usb-Chicony_Electronics_Co._Ltd._USB2.0_HD_UVC_WebCam_0x0001-video-index0
Code (gambas)
- /dev/videoX
I hope justlostintime's project is useful to Cedron and to everyone who finds this kind of thing interesting.
EDIT:
After posting this message, I played around with this project further. And to my dismay, I discovered that changing the webcam settings (i.e. brightness, contrast, whiteness, hue) appears to alter the webcam settings permanently! I apologize for that. I'm providing code to properly initialize the sliders, and to reset your webcam settings to their default values.
1) Add a Public Sub Form_Open() and paste this code. This initializes each slider's min, max, and default values to match your webcam's specifications.
Code (gambas)
2) Add a new button to that project. Call it Reset or whatever you like. Paste this code to its click event. This code resets your webcam's values for brightness, contrast, etc. to its default values.
Code (gambas)
- ' Shell "v4l2-ctl -d /dev/video0 --list-ctrls" To TheResult
- 'or
- OnSet = True
- TheStart = 0
- TheLength = 0
- TheName = Null
- TheStart = 1
- TheStart = 0
- TheLength = 0
- TheStart = 0
- TheLength = 0
- Bright.Value = TheDefault
- Contrast.Value = TheDefault
- Whiteness.Value = TheDefault
- Hue.Value = TheDefault
- Colour.Value = TheDefault
- OnSet = False
3) Optional, but its helpful to add these lines to the bottom of each respective slider _Change event. These lines of code show a tooltip for the respective slider that displays your webcam's minimum value, current value per the slider position, and maximum value.
Code (gambas)
- Bright.Tooltip = Bright.MinValue & " - " & Bright.Value & " - " & Bright.MaxValue
- Contrast.Tooltip = Contrast.MinValue & " - " & Contrast.Value & " - " & Contrast.MaxValue
- Whiteness.Tooltip = Whiteness.MinValue & " - " & Whiteness.Value & " - " & Whiteness.MaxValue 'gamma
- Colour.Tooltip = Colour.MinValue & " - " & Colour.Value & " - " & Colour.MaxValue
- Hue.Tooltip = Hue.MinValue & " - " & Hue.Value & " - " & Hue.MaxValue
I hope you find these modifications useful. I apologize that I posted yesterday before realizing some major shortcomings in justlostintime's otherwise awesome project. And before coding and posting proper modifications to the code (albeit probably crude, to more advanced coders).
Please feel free to post any further modifications and/or fixes to justlostintime's code.This stuff is quite cool!
Posted
Regular

I totally relate to your desire to have more control over the Webcam. I actually wrote a simple webcam capture to snapshot in pure C++ using the v4l library and the jpeg library, and of course, straight X window programming.
In a word: Yuck.
However, unfortunately, the gb.v4l component is officially depracated, which is why I didn't use it:
/comp/gb.v4l - Gambas Documentation
I have not figure out yet if it is possible to have similar control through the MediaPlayer. It was discovering that starting the URL with "v4l2://" allowed the MediaPlayer to capture the Webcam, and the super simple code that ensued, is what led me to start this thread.
I am really impressed by the MediaPlayer. I am also using it in my music player that I will post shortly, as well as being able to single step through .mov files, using the new .Forward() method.
So, anyway, I have attached a slightly more comprehensive webcam capture program. It is an expansion of the original posting.
Enjoy,
Ced
.... and carry a big stick!
Posted
Guru

You need to add some code to catch cases where there is no camera connected as it crashes at the moment.
Posted
Regular

As for V4L, does anyone know what its being depreciated in favor of? SDL perhaps? I only found out SDL exists a few days ago. From what little I learned about it, its supposed to be the bees knees.
Posted
Regular

Thanks for the kind words. I don't truly know the answers to your other questions about v4l so I posted the question to the mailing list.
As for SDL, I'm not a big fan, but I don't want to discourage you. It may be exactly what you are looking for. For me, it is out of consideration since it is incompatible with using Qt form controls. Originally I thought it might be something I could use as it seems to be the only place with gamepad support in official Gambas. Since I have ruled it out for myself, I have not explored it fully. I don't know if the webcam is accessible through SDL.
Instead, I wrote my own shared library for gamepad support. First using the deprecated joystick model, then using the current evdev mode. It is in my pile of "almost ready to be released" projects. As part of researching evdev, I dove into some of the source code for SDL (the SDL itself, not the Gambas interface to it) and was not really impressed by the quality of the code.
The evdev uses similar directory structure design as the video. That is, there is a /dev/event## directory and a symbolic by-id directory. I used the latter in my sample because of your mentioning it in your reply. I should of stated that earlier.
If you, or anyone, has an interest in the gamepad code, I will bump up its priority and get it posted.
Ced
.... and carry a big stick!
1 guest and 0 members have just viewed this.


