Raw dogging TV channels

A QVC broadcast, mid pitch

Sometimes I enjoy pausing and figuring out a piece of technology or methodology that we often take for granted. A long while ago when everyone switched to "digital tv" broadcasting I actually never took a second look, but diving into how it gets done was pretty fascinating.

Once I realized that all TV channels are broadcasting on VHF/UHF frequencies, I knew I could probably decode those streams in real time. I've had a little SDR I wasn't using for anything (Airspy), and a ton of different antennas so I thought what the hell, let's try. It was also a good excuse to dive back into some signal processing libraries I haven't looked at in quite some time.

Things that blow my mind:

Now, should you do this to normally watch TV? Absolutely not. It's so inefficient and there are hardware decoders that take care of all these problems, in a much better way, for not much money at all. Was it fun? Hell yes.

I regret nothing. Also nobody should really be using this project, outside the fact that it's just a couple Docker containers so you aren't investing into much by running it yourself.

How it works

Antenna, then the Airspy, then software. The radio tunes one 6 MHz RF channel at a time and a GNU Radio ATSC decoder turns those samples into the MPEG transport stream the station is already sending, about 19.4 Mbps. The virtual channels are programs inside that one stream, so a few of them play at once off the same tune. A station on a different RF channel has to wait while the radio retunes.

                                                             ┌─► webtv :80  (browser page, H.264 for browsers)
antenna ─► Airspy R2 ─► atsc-rx (on-demand tuner) ◄─ /rf/<n> ─┤
            (USB)       GNU Radio gr-dtv            MPEG-TS  └─► Tvheadend :9981 HTTP (M3U, XMLTV, streams)
                        127.0.0.1:5600                                     :9982 HTSP (Kodi)

atsc-rx is the tuner. It only decodes while someone is actually watching. Tvheadend publishes the playlist, the guide, and the streams, so VLC, Kodi, and Jellyfin see the same channels. A web page lists them with a reception badge and can play in the browser.

Web TV, channels and the last scan The page. Reception is 100 minus the packet error rate.

A scan walks the band and only keeps what locks. ATSC 3.0 shows up as a signal with no 8VSB pilot and stops there. This is 1.0.

Code is on GitHub.