satellite broadcast, dvb, iptv

summer 2025

this page has my notes on receiving satellite broadcasting (dvb-s/dvb-s2) and streaming it on ip networks.

for most people, broadcast tv, perhaps with the exception of news and sports, is dead. having been replaced by the more convenient on-demand streaming services.

but satellite broadcast still maintains some relevance. be it for the radio channels that don't have reliable online streams, or the fact that many live event and news stations have rubbish tv apps, or the fact that internet services require reliable internet, and can also be easily blocked.

plus, perhaps most importantly, it's interesting to learn how it all works and explore what's on these signals.

hardware

to decode a dvb-s signal you need a tuner and a computer to attach it to. of course, you also need a dish and an lnb pointed in the right direction but i'll assume you already have that sorted.

i ended up with a couple of tbs6909x pci tuners and a tbs2952 server. the tbs2952 is convenient because it's a 1u rack-mountable unit that can fit four pci cards, which is quite rare. i installed standard debian on it.

the only issue with tbs cards is that their drivers are not in the mainline kernel tree. they make up for it by being relatively cheap. they also make cards that have eight tuners whereas most of the ones with upstreamed drivers stop a four.

mumudvb

mumudvb reads from a dvb tuner, splits out the transport streams for each channel, and streams them over the network. it can do multicast udp or unicast http streams.

it was fairly straightforward to run once i found the configuration documentation page.

i run one instance per tuner, each with a config file that looks like this:

delivery_system=DVBS2
freq=11046
pol=h
srate=27500
coderate=2/3
autoconfiguration=full
unicast=1
multicast_ipv4=0
multicast_ipv6=0
port_http=4000+%card
autoconf_radios=1
this was enough to get the list of channels it found on /channels_list.html, and you can test any of their /bysid/xxxx urls with ffplay or vlc.

iptv clients

i tried a few iptv apps and all of free ones i tried were quite bad. they were barely usable, riddled with ads, and generally seemed to target pirate streamers.

i ended up with uhf on apple tv. the free version is unusable, however once you buy a subscription it seemed quite polished and reasonable to use. (while i'm happy to pay for software, i don't really understand why this has to be called a "lifetime subscription".)

most iptv apps expect an m3u playlist of channel urls, and some optional metadata tags. the ones i found uhf to respect were "tvg-logo", with a url for the logo, and "group-title", which specifies the category.

my playlist looks something like this:

#EXTM3U
#EXTINF:-1 tvg-logo="http://satellite.local/news.png" group-title="News",The News Channel
http://satellite.local:4001/bysid/101
#EXTINF:-1 tvg-logo="http://satellite.local/sports.png" group-title="Sports",Sports Channel
http://satellite.local:4001/bysid/102
#EXTINF:-1 tvg-logo="http://satellite.local/news2.png" group-title="News",The Other News Channel
http://satellite.local:4002/bysid/201
...

safari/quicktime

to my surprise, safari was capable of playing a ts stream directly from mumudvb. it needs a separate playlist per channel, with just one item in it. something like this:

#EXTM3U
#EXTINF:-1,Some Channel
http://satellite.local:4001/bysid/101
quicktime can play these too.

plex

plex has built-in support for streaming live tv from hdhomerun. the live tv part of plex is an unpolished and buggy corner of the usually quite slick plex experience, but it does work.

hdhomerun is a proprietary network-connected cable tuner. there are services like xteve or its forks that emulate an hdhomerun device from an iptv source, but you can also just statically generate the files plex expects from it.

this go program takes in a csv file of channels, their mumudvb urls, and channel logo urls, and produces an m3u playlist for iptv players, lineup.json which plex expects from hdhomerun, and channels.xml which is an empty tv guide that plex requires.

generate.go
package main

import (
	"encoding/csv"
	"encoding/json"
	"log"
	"os"
	"strconv"
	"text/template"
)

type channel struct {
	Name   string `json:"GuideName"`
	URL    string `json:"URL"`
	Logo   string `json:"-"`
	Number string `json:"Number"`
}

func must[T any](v T, err error) T {
	if err != nil {
		log.Fatal(err)
	}
	return v
}

func write(t, filepath string, data any) error {
	tmpl, err := template.New("t").Parse(t)
	if err != nil {
		return err
	}
	w, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer w.Close()
	return tmpl.Execute(w, data)
}

var m3u = `#EXTM3U
{{ range . }}#EXTINF:-1 tvg-logo="{{.Logo}}" group-title="All",{{.Name}}
{{.URL}}
{{ end }}
`

var xmltv = `

{{ range . }}

{{.Name}}

{{ end }}

`

func main() {
	records, err := must(csv.NewReader(must(os.Open(filename))).ReadAll())
	var cs []channel
	for i, r := range records {
		cs = append(out, channel{r[0], r[1], r[2], strconv.Itoa(i + 1)})
	}
	err = must(write(m3u, "channels.local.m3u", cs))
	err = must(write(xmltv, "channels.xml", cs))
	err = json.NewEncoder(must(os.Create("lineup.json"))).Encode(cs)
	if err != nil {
		log.Fatal(err)
	}
}

you also need lineup_status.json:

{
  "ScanInProgress": 0,
  "ScanPossible": 0,
  "Source": "Cable",
  "SourceList": [
    "Cable"
  ]
}

and discover.json, replacing "satellite.local" with your hosts name:

{
  "FriendlyName": "satellite.local",
  "Manufacturer": "Silicondust",
  "ModelNumber": "HDTC-2US",
  "FirmwareName": "hdhomeruntc_atsc",
  "TunerCount": 6,
  "FirmwareVersion": "20150826",
  "DeviceID": "12345678",
  "DeviceAuth": "test1234",
  "BaseURL": "http://satellite.local/",
  "LineupURL": "http://satellite.local/lineup.json"
}
place these on a webserver (i run one on the same machine that runs mumudvb) and add it in plex's "live tv & dvr" settings page.

sat>ip

sat>ip was a protocol meant to carry satellite channels over ip networks. that's exactly what i'm trying to do here!

the protocol itself is fairly well documented. it's essentially a modified rtsp.

you can still buy hardware that serves sat>ip from some integrated tuners. i experimented with kathrein exip 418 but did not get very far with it.

sat>ip seems to be largely abandoned. even the once official website satip.info seems to be offline. ffmpeg and vlc can still play sat>ip sources, and there are apps on apple tv app store that claim to do it, but they kept crashing when i tried to get them to work.

tvheadend

i also tried tvheadend, a popular tv streaming server for linux.

it works well enough, and it even supports both sat>ip and hdhomerun, being able to consume or emulate either of them.

but i found the web ui so complicated i could barely make any sense of it. i also didn't need any of the recording functionality it provided. i ended up leaving it in favour of the simpler mumudvb.

dvb-i

the dvb project is trying to define a standard for broadcasting over ip, called dvb-i. maybe once this picks up steam a lot of this setup would be simpler? maybe tvs would have built-in iptv clients that are easier to configure?

i'm not holding my breath.