USB Audio/Video Capture on Linux.
Recently I've been looking into digitising a bunch of old family videos. They're recorded on old media formats like VHS, MiniDV, MiniDisk, CD and DVD. I'm not too concerned with quality, it's more about making them easily accessible and not be burdened by degrading physical media and playback devices.
The most obvious solution is to buy a USB video and audio capture device. They're very common and cheap, usually selling for around US$3.50. Sure they only take composite video or S-Video rather than RGB or component, but that's good enough.
Avoiding proprietary software
One of the many things I dislike about Windows is that it installs random proprietary junk whenever I plug in a USB device. And if it doesn't, I'll need to install that junk manually. Going by user reviews, as usual the drivers seem to be buggy, incompatible and full of security issues. So instead, I'm going to use a Linux test machine. By using a test machine, I can minimise any potential damage from a random cheap USB device. Linux has video4linux2 (v4l2), which is a collection of open source drivers and other software for video capture devices.
Working VLC configuration
To avoid any ambiguity, I'll start by sharing a VLC configuration without my personal preferences. This should give us an idea of the sorts of information we need to get this working.
- File
- Open Media
- Capture Device
- Capture mode
- Video camera
- Device selection
- Video device name
/dev/video2
- Audio device name
hw:1,0
- Video device name
- Options
- Video standard
Undefined
(default)
- Video standard
- Show more options
- Edit options
:alsa-samplerate=96000
- Edit options
- Capture mode
- Capture Device
- Open Media
Converting this to a command line gives:
vlc v4l2:///dev/video2 --input-slave=alsa://hw1,0 --alsa-samplerate=96000
Useful links
- Linux's v4l2 API: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/v4l2.html
- VLC's v4l2 API: https://wiki.videolan.org/Documentation:Modules/v4l2/
Finding the USB device
We should always first make sure the USB device is working. Otherwise we'll be wasting our time.
To do so, first list all USB devices with:
lsusb
We should see our device in the list. It may be listed with a different name or, in my case, even no name.
If we can't find it, list devices before and after plugging it in and compare.
We can also dump all USB device details for more information and find it that way.
lsusb -v
Once we have identified the device, we can list only its information using its device ID:
lsusb -v -d 534d:0021
This is a useful way to see what video and audio formats are supported along with frequencies, bitrates and resolution.
For reference, my USB device is a "MACROSILICON AV TO USB2.0 20150130".
Finding the video device
We can see a list of video devices provided by the USB device using:
v4l2-ctl --list-devices
This might show other video devices too like for the built-in laptop webcam.
If v4l2-ctl
is not available and can't be installed, we can list all available video devices:
ls -la /dev/video*
To find which devices are coming from our USB device, we can list them before and after plugging it in. For convenience, we can use the symlinks matching our USB device under /dev/v4l/by-id/
or /dev/v4l/by-path/
.
In either case, chances are our USB device will have multiple video devices. To find the correct one, we'll have to trial and error. In my case, the correct one was /dev/video2
.
Each time we plug in the USB device, the video device paths might change. So we'll need to repeat this process to re-identity them or use the syslinks mentioned before.
Supported video formats
Other than by checking the USB information, we can find a more basic list of supported formats with ffplay
:
ffplay -f v4l2 -list_formats all /dev/video2
My device has raw video at 480x320 and compressed video using MJPEG up to 720x480.
To access these formats in VLC we can add more options:
:v4l2-chroma=mjpg :v4l2-width=720 :v4l2-height=480
It's worth noting that whenever I use these options, they seem to stick somewhere such that if I removed them, they'd still be active. So for example, I couldn't switch back from mjpg to raw video. Though sometimes, but not always, after a reboot or reconnect it would switch back. I didn't look into what's causing it. It could be VLC, v4l2 or even the USB device, though it's probably v4l2.
Finding the audio device
We can see if the audio device is detected by ALSA with:
arecord -l
or
cat /proc/asound/cards
Typically, if our device is second on the list, its identifier for ALSA-related commands and configurations will be hw:1,0
. If not, again, trial and error.
The actual sound device path can be found under /dev/snd
. For convenience we can use the symlinks matching our USB device under /dev/snd/by-id/
or /dev/snd/by-path/
. However, VLC doesn't support supplying sound devices to v4l2 due to security issues. So, we won't be using these paths. We'll use the ALSA identifier instead.
Playing and recording video and audio capture
There are multiple applications for playing and recording the video and audio captured by v4l2 devices. The most common are:
- VLC
- ffmpeg and ffplay
- mplayer
VLC is best for getting started as it has a GUI. Though, that GUI is extremely limited and confusing so the GUI-less cvlc
is useful too.
ffmpeg is useful for troubleshooting VLC-specific issues and extracting more information.
mplayer's not that useful if we're using the other two.
Once everything is figured out, it's best to use ffmpeg for recording since it avoids the bloat of VLC; which probably uses ffmpeg underneath anyway.
At this pointm we can provide VLC with the information we've gathered so far through its GUI. I recommend launching VLC from a terminal so that its logs are easily accessible.
- File
- Open Media
- Capture Device
- Capture mode
- Video camera
- Device selection
- Video device name
/dev/video2
- Audio device name
hw:1,0
- Video device name
- Capture mode
- Capture Device
- Open Media
When we try running this, chances are there'll be some problems. We'll get into those next.
Black video
A black or blank video usually means there is no video data coming into the device. Check the cables and connectors.
Make sure the connectors are colour matched and that they are all the way in. Some connectors, especially as they age, can get a bit stiff.
If we're using a SCART output, make sure the SCART connector going into the output device has output pins. Some SCART connectors, typically adapters, only have input pins that are expected to only be plugged into a display.
Misaligned and glitchy output
A misaligned, warped, glitchy, static output without the correct colours likely means our output is using a different video standard from what the input expects. For example, 60Hz NTSC instead of 50Hz PAL.
Change either the video standard in VLC or video settings on the device so that they both match.
Picture quality
v4l2 has the usual options to adjust the image, such as brightness and contrast. VLC also has those options under "Tools > Effects and Filters". VLC's options are a lot more convenient as it provides a live preview. Unfortunately, VLC's GUI uses tiny sliders to adjust values, with no numbers or number inputs visible.
I suggest using a test image to tweak the values, similar to calibrating a TV or any other display. Use arrow keys to have proper control over the sliders
In my case, the device's brightness was way too high. Dialing it down by around 10 steps and balancing out the other values greatly improved things.
Driver limitations
For the USB device I had, I couldn't figure out how to get VLC or ffmpeg to support NTSC (480i@60hz), so I always configured the output device to use PAL (576i@50Hz) instead, which works as default. Changing VLC's "video standard" option in general didn't seem to have any effect. Trying to identify available standards also errored:
ffplay -f v4l2 -list_standards all /dev/video2
# /dev/video2: Immediate exit requested
I assume this is a driver limitation as screenshots of the proprietry software does show options to change video standards. This wasn't a major issue for me as being in the United Kingdom, most media and devices were targeting PAL anyway.
VLC also has a v4l2 tab under "Effects and Filters" but, other than a reset button, it was empty.
Incorrect audio sample rate
Chances are when using VLC with basic options, we'll run into an error with the audio device:
access_alsa demux error: cannot restrict rate to 192000 Hz or less: Invalid argument
main input error: Your input can't be opened
main input error: VLC is unable to open the URL 'alsa://hw:1,0'. Check the log for details.
This is because the default sample rate is 41000
. We can find our device's actual sample rate with:
lsusb -v | grep 'tSamFreq'
This should show something like:
tSamFreq[ 0] 96000
If there are multiple results, try filtering by the USB device as shown previously.
In VLC, we can provide the correct frequency by adding an additional option under "Edit options".
Since VLC uses :input-slave
to set the audio device, we'll need to add:
:alsa-samplerate=96000
Conclusion
After all of these fixes, the end result should now be as best as it can be. We can't expect a perfect solution from such a cheap device. But thanks to Linux and open source, it's a reliable one.
Thanks for reading.