Capture OTA TV and Transcode on the Fly with FFmpeg

Capturing over-the-air (OTA) television broadcasts and transcoding them in real-time is a highly efficient way to stream or archive live TV. This guide provides a direct, step-by-step walkthrough on how to use a TV tuner card on a Linux system to tune into a broadcast channel and utilize FFmpeg to transcode the incoming MPEG-TS stream on the fly into a highly compatible H.264/AAC format.

Prerequisites

Before beginning, ensure you have the following hardware and software configured:

  • TV Tuner Card: An ATSC (North America) or DVB-T/T2 (Europe/other regions) USB dongle or PCIe card installed and recognized by your system.
  • Linux Drivers: The card should be registered under /dev/dvb/adapter0/.
  • FFmpeg: Installed with support for the H.264 encoder (libx264) and AAC audio encoder.
  • Tuning Utilities: Install v4l-utils (which includes dvbv5-zap) or w_scan to generate channel configuration files.

Step 1: Scan and Generate a Channel List

You must first scan for available OTA frequencies to generate a configuration file. Use w_scan or dvbv5-scan depending on your region.

For DVB-T (Europe):

w_scan -ft -c US > channels.conf

(Replace US with your country code, e.g., DE for Germany or GB for the United Kingdom).

This command creates a channels.conf file containing the frequency, program ID (PID), and modulation details for every available channel in your area.


Step 2: Tune the Channel and Pipe to FFmpeg

Because TV tuner cards output raw MPEG-TS streams, you need to tune the card to a specific channel first. The most efficient way to capture and transcode simultaneously is to use dvbv5-zap to tune the card, then pipe the output stream directly into FFmpeg.

Run the following command to tune to a channel named "PBS" (replace this with a channel name from your channels.conf file) and transcode it:

dvbv5-zap -c channels.conf -r "PBS" -o - | ffmpeg -i - \
  -c:v libx264 -preset veryfast -crf 23 \
  -c:a aac -b:a 128k \
  -f mp4 output.mp4

Command Breakdown

  • dvbv5-zap -c channels.conf -r "PBS" -o -: Tunes the card to the channel named "PBS" using your channel list. The -o - flag redirects the raw MPEG-TS video stream to the standard output (stdout).
  • | (Pipe): Sends the stdout of the tuning utility directly to the stdin of FFmpeg.
  • -i -: Instructs FFmpeg to read the incoming stream from standard input.
  • -c:v libx264: Transcodes the incoming MPEG-2 video stream into H.264 video.
  • -preset veryfast: Balances CPU usage and encoding speed to ensure the transcoding keeps up with the live broadcast in real time.
  • -crf 23: Controls the video quality (Constant Rate Factor). Values between 18 and 28 offer a good balance of quality and file size.
  • -c:a aac -b:a 128k: Transcodes the audio to AAC format at a bitrate of 128kbps.
  • -f mp4 output.mp4: Formats and saves the final stream as an MP4 file.

Hardware Accelerated Transcoding (Optional)

If your CPU struggles to keep up with real-time encoding, you can offload the processing to an NVIDIA GPU (using NVENC) or an Intel CPU (using VAAPI).

Intel VAAPI Example:

dvbv5-zap -c channels.conf -r "PBS" -o - | ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i - \
  -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 24 \
  -c:a aac -b:a 128k \
  -f mp4 output.mp4

NVIDIA NVENC Example:

dvbv5-zap -c channels.conf -r "PBS" -o - | ffmpeg -i - \
  -c:v h264_nvenc -preset fast -cq 23 \
  -c:a aac -b:a 128k \
  -f mp4 output.mp4