cliffmccarthy.net

2014-12-10

Added ; last modified January 26, 2026

Stuff I found useful in transferring VHS video using a Hauppauge USB-Live 2 digitizer with Linux (Lubuntu 14.04, to be precise):

  • http://ivtvdriver.org/index.php/V4l2-ctl
    • This tool can be used to set the device to capture NTSC. The command I used was:
      • v4l2-ctl -d /dev/video1 -s ntsc
  • http://www.linuxtv.org/wiki/index.php/MEncoder
    • The advice here to use GStreamer for “unstable sources” worked out. I had been using an mencoder command to capture video because that was the only thing I had successfully made work, before I discovered the right v4l2-ctl command. The problem with mencoder is that when the video signal drops out (as VHS tapes are likely to do), it starts to lose audio/video sync.
    • Also, I was only able to make GStreamer work if I didn’t run the mencoder command at all. So, mencoder was leaving the device in some state that I couldn’t figure out how to get it out of, short of rebooting.
  • http://www.linuxtv.org/wiki/index.php/GStreamer

The trick with GStreamer is figuring out the complicated “pipeline” to handle the signals correctly. Ultimately, I was able to capture audio and video and keep them reasonably synchronized by running:

    gst-launch-0.10 -v \
        --gst-debug-level=3 --gst-debug-no-color \
        avimux name=mux \
        v4l2src device=/dev/video1 do-timestamp=true ! \
            video/x-raw-yuv,width=720,height=480,framerate=\(fraction\)30000/1001 ! \
            videorate ! \
            'video/x-raw-yuv,framerate=(fraction)30000/1001' ! \
            queue ! \
            mux. \
        alsasrc device=hw:1,0 ! \
            'audio/x-raw-int,format=(string)S16LE,rate=(int)48000,channels=(int)2' ! \
            audiorate ! \
            audioresample ! \
            'audio/x-raw-int,rate=(int)48000' ! \
            audioconvert ! \
            'audio/x-raw-int,channels=(int)2' ! \
            queue ! \
            mux. \
        mux. ! \
        filesink location=gstreamer.avi

This is loosely based on the “Record from a bad analog signal” link above.

I converted the resulting file to MP4 with:

    avconv -i gstreamer.avi -c:v libx264 -b:v 4500k -c:a aac -b:a 360k -strict experimental -filter:v yadif=0:-1:0,setsar=8:9 -ss 12 -t 704 gstreamer.mp4

The “12” and “704” mark the starting time and duration to extract from the full raw file. Note the ‘setsar=8:9’, because the NTSC default is 720x480, with non-square pixels. I prefer working with square pixels, but I decided because MP4 has reasonable handling of different pixel aspect ratios, this would be good enough. (And maybe that additional 12.5% of oversampling makes some sort of huge difference in the picture quality. Nah, probably not.)

Update 2015-03-17: To losslessly trim the mp4 file:

    avconv -i gstreamer.mp4 -ss 15 -t 315 -vcodec copy -acodec copy avconv.mp4

Update 2015-07-14: AAC is the recommended audio format for uploading to YouTube, but the above command may not produce the best audio quality. See https://trac.ffmpeg.org/wiki/Encode/AAC.