Saving Your Analog Data from Oblivion

Saving Your Analog Data from Oblivion

Article from Issue 219/2019

If you have old VHS tapes or audio cassettes lying around, the hardware to play these analog formats is becoming more difficult to find. Here's how to convert those old analog treasures to digital format for future enjoyment.

Transferring VHS tapes, audio cassettes, and other analog home media formats to a digital format, such as Ogg or Matroska, can be a complex and expensive process with archival-grade conversions. In this article, I show you a simple and inexpensive method for digitizing your VHS tapes that is perfect for personal use.

Shopping List

To convert a VHS tape to a digital format, you need two pieces of equipment: a playback device for the original medium and a capture device to read the playback device's output. In addition, you need transcoding software to process the data that the capture device retrieves from the playback device. For a list of what I used in this project, see the "Software and Hardware Requirements" box.

Software and Hardware Requirements


  • Firstline VCR-602
  • USBTV007 EasyCAP
  • SCART to RCA adaptor


  • GStreamer 1.6.4
  • FFmpeg 3.2.4
  • SoX 14.4.2

For the playback device, you can find a used VCR for less than EUR100 online ($100-$200+ for NTSC/PAL/multisystem). Keep in mind that your chosen playback device must match the color encoding system of the VHS tapes you intend to transfer. Trying to play a PAL VHS on an NTSC device won't work (see the box "PAL vs. NTSC").


PAL and NTSC are two color encoding systems – originally intended for analog television – that also apply to VHS tapes, players, and recorders:

  • Phase Alternating Line (PAL) is used in most of Europe, Australia, the Middle East, Asia, and a big part of South America [1]. PAL media run at 25 frames per second (fps) and have a frame size of 720x576. In this article, the example commands are for PAL media.
  • National Television System Committee (NTSC) is used in North America, Japan, parts of South America, and a few other countries [2]. NTSC media run at 29.97fps and have a frame size of 720x480. If you try to reproduce the steps in this article with NTSC devices, you will need to replace these values in the examples.

For a capture device, I use a USBTV007 EasyCAP (Figure 1), which is inexpensive (less than EUR15/may be difficult to find in the US), performs captures of acceptable quality, and has Linux support. Keep in mind that "EasyCAP" is not a commercial brand name; it is a popular term used by Chinese manufacturers to designate cheap, simple USB capture cards. Finding a specific EasyCAP model can be challenging, since manufacturers usually don't provide the full specification list in their product description or similar use cases. See the box "The Other EasyCAP."

The Other EasyCAP

Many EasyCAP devices other than the USBTV007 work under Linux. For more information about these other devices, see the LinuxTV wiki [3], but keep in mind that it is a bit outdated. (In fact, the wiki is so outdated that the EasyCAP model used here is reported to be unable to capture sound at the time of writing.)

Some of these EasyCAPs might require different command-line switches than the ones provided in this article's examples to work. If you have trouble getting your EasyCAP to work, try using a different pixel format option than YUY2 with GStreamer, such as UYVY or YV12 (Table 1). If you use any of these, you might want to supply a different pix_fmt switch to FFmpeg, although this is not really necessary .

Table 1

Pixel Formats








None known

Figure 1: This EasyCAP device works as a cost-effective capture device.

You will also need an SCART to RCA adaptor (Figure 2), which may be purchased for less than EUR10 ($8). The SCART connector is plugged into the VCR output, and the RCA plugs into the EasyCAP connectors. Most RCA connectors are correctly color coded (Table 2).

Table 2

RCA Color Codes




Left audio


Right audio



Figure 2: This SCART to RCA adaptor has an extra pin for audio input, which I won't be using.

In addition, I used a laptop with an i5-2467M CPU for my tests, but you can use a computer with less horsepower. A dual-core CPU of 2.5OGHz for each core is the minimum requirement. However, tests showed that the procedures described in this article will result in a barely acceptable loss of frames in the encoding when using this weak of a CPU. Using a drive with a high write speed is also advisable, since the VHS will be transferred and saved to the filesystem in real time.

In terms of software, I used GStreamer with the Ugly plugin for the capture (see the "Why GStreamer?" box) and FFmpeg to transcode. FFmpeg requires x264 and libdfk-aac support. Finally, the SoX sound processing utility is used to clean up the transferred media's audio.

Why GStreamer?

Many tutorials suggest capturing your VCR or cassette player's output directly with FFmpeg or MPlayer. Instead, I chose GStreamer to capture the VCR output and pipe it into FFmpeg, because GStreamer has better error tolerance when dealing with faulty media feeds. This means GStreamer will work better with cheap capture devices that provide bad frame rates (e.g., 25.02fps instead of 25fps for PAL video). This is specially true when muxing the output to formats that support time stamps, such as Matroska [4].

Hardware Detection

First, power up your computer and connect all the hardware as previously described. Then, make sure your operating system properly identifies the capture device.

The USBTV007 EasyCAP will show up as two different capture devices: one for audio and one for video. This model does not work with the PulseAudio sound server, so you might need to tell PulseAudio to ignore the device so that ALSA can manage it instead. To do this, use the graphical tool pavucontrol: Move to the Configuration tab and select the Off profile for USBTV007. If you prefer to work from the command line, then enter,

pactl set-card-profile $card_number off

where $card_number is the identifier of your EasyCAP device for PulseAudio. If you don't know what it is, you can find out by typing:

pactl list cards | grep -E '|device.string'

To list your currently detected audio inputs, enter the command:

arecord -l

This will display the working capture devices detected by ALSA.

Video inputs will show up as files named /dev/video* (e.g., /dev/video0, /dev/video1, etc.). If you have more than one video input – for example, you have a webcam in addition to an EasyCAP – and you are not sure which one is which, you can extract information from each device with the v4l2-ctl command. The following command will display some known properties of /dev/video0:

v4l2-ctl --device=/dev/video0 --list-inputs

The Capture Process

Once everything is connected and detected, it is time to capture the video. To do this, insert a VHS tape into the VCR and play it, and then turn on your capture software, which takes the VCR's output and dumps it into a file on the fly.

The raw video and audio stream can take up a lot of storage, probably more than 100GB, which is why most people prefer encoding that stream into something more manageable as it is captured. Because the computer is capturing the raw VCR output in real time, your encoder must be both fast and CPU-friendly, so as not to affect the data capture negatively. If you try to use an encoding configuration that is too hard on the CPU, it will not have enough time to process each piece of incoming data before the next one arrives, which will result in lost frames and data loss.

Listing 1 performs a lossless capture of the analog input. While not very practical, Listing 1 is provided as a reference. Notice that the buffers are set to zero in order to avoid problems during the real-time video capture. The pixel format, YUY2, is set to the format that the EasyCAP feeds to the computer. Audio is captured in a lossless format at a sampling rate of 48KHz in stereo. The output is dumped to a Matroska file. Listing 1 is tuned for PAL devices (if you are using NTSC, see the "PAL vs. NTSC" box.)

Listing 1

Compressionless Capture Command

gst-launch-1.0 -q v4l2src device="$videodevice" do-timestamp=true norm="PAL" pixel-aspect-ratio=1
    ! video/x-raw,format=YUY2,framerate=25/1,width=720,height=576
    ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0
    ! mux.
  alsasrc device="$alsadevice" do-timestamp=true
    ! audio/x-raw,format=S16LE,rate=48000,channels=2
    ! queue
  max-size-buffers=0 max-size-time=0 max-size-bytes=0
    ! mux. matroskamux name=mux
    ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0
    ! filesink location=vhs.mkv

In Listing 1, replace "$videodevice" with a video input device (e.g., /dev/video1). The "$alsadevice" (in the alsasrc device line) describes an audio input such as hw:1,0 or hw:2,0. The ALSA audio inputs are always named in a "hw:$card,$device" format.

Listing 2 performs lossy compression while carrying the analog stream's capture, resulting in a smaller file. It is configured to capture video for 1 hour and 40 minutes, but you can stop the recording by pressing q at any time.

Listing 2

Compressed Capture Command

ffmpeg -loglevel 32 -t 01:40:00
       -i <( gst-launch-1.0 -q v4l2src device="$videodevice1"
             do-timestamp=true norm="PAL" pixel-aspect-ratio=1
             ! video/x-raw,format=YUY2,framerate=25/1,width=720,height=576
             ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0
             ! mux.
            alsasrc device="$alsadevice" do-timestamp=true
             ! audio/x-raw,format=S16LE,rate=48000,channels=2
             ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0
             ! mux.
            matroskamux name=mux
             ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0
             ! fdsink fd=1
       -c:v libx264 -preset ultrafast -x264opts crf=18:keyint=50:min-keyint=5
       -pix_fmt yuyv422 -c:a flac
       -f matroska file:vhs.mkv

Listing 2 offers a good trade-off. GStreamer captures the VHS output and pipes it to FFmpeg for transcoding (see Table 3). It will encode the raw stream without a noticeable loss of quality and will diminish the output file size by a factor of ten. Because it is CPU-friendly, it allows the capture of the analog data without frame loss. The resulting file is, however, still too big for most users. It is also likely to suffer from audio and video noise, since old analog data is susceptible to acquiring defects because of the media's age. Therefore, the captured video will require postprocessing.

Table 3

FFmpeg Options



-t 01:40:00

Sets a duration for the recording.

-c:v libx264

Uses the x264 video codec.

-preset ultrafast

Makes the encoder work as fast as possible.


Sets the quality of the encoding. Lower is better, but also implies larger files.


Maximum interval between keyframes. Low values make it easier to seek specific positions in the video [6].


Minimum interval between keyframes.


Pixel format (the same as EasyCAP).

-c:a flac

Audio is encoded as FLAC, which provides reasonable compression without reduction of sound quality.

-f matroska

Mixes the audio and the video into a Matroska multimedia container.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More