I use plex media server for several years now. In newer versions, Plex started supporting TV tuners of different kind. This makes it to a whole solution that supports movies, music, pictures and TV from various sources. As there is a discussion of removing the ability to skip ads during replay of a TV show taking place, I look for a solution where I am not bound to a TV Provider to give me recordings.

Components and call sequence

The following sequence diagram shows the calls made to bring the tv to your Plex system. This should give you a little overview of the whole system. And yes, it is not a clean UML diagram but should be ok if it helps you to understand the system and how the components communicate.

sequenceDiagram participant Plex participant telly participant TV7Playlist participant Udpxy participant TV7 Plex->>+telly: Give me your channels telly->>+TV7Playlist: Get playlist TV7Playlist->>+TV7: download channel m3u TV7-->>-TV7Playlist: Sending file TV7Playlist-->>-telly: Sending fixed playlist telly-->>-Plex: Present channellist Plex->>+telly: Tune to channel 1 telly->>+Udpxy: Stream URL channel1 Udpxy->>+TV7: Join multicast TV7-->>-Udpxy: Streaming Udpxy-->>-telly: Streaming telly-->>-Plex: Streaming

Virtual machines setup

Plex media server requirements

I run plex on a dedicated virtual machine. The machine has enough RAM and CPU power to transcode multiple 1080p streams. You may have some less powerful system, but this should not be a problem at all. This VM is hosted on a server running Proxmox comunity edition .

There is a little catch although. To enable the DVR support of Plex, you need to have a valid Plex pass. This is not problem for me as I payed a lifetime membership back when I started using it. You just need to take this into account on your system. Without a Plex pass, this feature will currently not work.

Debian server is the operating system I use for Plex. There is a Package available directly at the plex download page that can be installed. I will not cover a basic Plex setup here as there are multiple good tutorials out there. Just use your search engine of your choice.

Docker requirements

All additional components used for this setup are available as docker images. You may also grab the Dockerfile, source and build it on your own. You’ll find the link to the sources at each service.

If you don’t like to type long docker commands, you could also use something like portainer.io to manage the docker host. I use portainer to manage my docker host. But I provide a command line as well ;-) I hope I crafted them right. If not, just let me know and I’ll update it here.

Container setup

Udpxy - multicast proxy

This service converts a multicast stream to a unicast stream that telly and Plex can use and play. If Plex and/or telly would be able to handle multicats, this would not be needed.

To set up Udpxy, you have to run the container with network set to host as the multicast joins would not work otherwise.

You may get a dockerfile to build this image under https://git.haefelfinger.net/dockerapps/Udpxy .

In portainer:

  • In portainer set the name to udpxy
  • Use the image phaefelfinger/udpxy:latest (if you like to take mine and you trust me)
  • Under Advanced container settings select Network and there host
  • Under Advanced container settings select Restart policy and there set Unless stopped
  • Hit Deploy the container to finish

Use the following command if you prefer the terminal:

docker run -t --name="udpxy" --network="host" --restart=unless-stopped phaefelfinger/udpxy:latest

tv7 playlist rewrite

My small .net core app just rewrites the original TV7 multicast playlist so that telly uses udpxy to subscribe to the stream. This is quite easy to set up.

You may get my code including a dockerfile to build the app and image under https://git.haefelfinger.net/dockerapps/tv7playlist .

In portainer:

  • In portainer set the name to tv7playlist
  • Use the image phaefelfinger/tv7playlist:latest (if you like to take mine and you trust me)
  • Click on Add additional port to add a new mapping
    • Set host to 8000
    • Set the container to 80
  • Under Advanced container settings select Env
    • Click on add environment variable
    • Set name to UdpxyUrl
    • Set value to http://your.host.ip.of.udpxy:4022/udp
  • Under Advanced container settings select Restart policy and there set Unless stopped
  • Hit Deploy the container to finish
  • Sync your senderlist
    • Navigate to http://your.tv7playlist.host:8000
    • Click on “Synchronize playlist”
    • Verify the URL and hit “Run synchronization”
    • You will be redirected to the startpage listing all channels
  • Edit the list and disable the channels you don’t need
  • Update the channelnumbers and names to match your EPG provider

Use the following command if you prefer the terminal:

docker volume create tv7playlist_data
docker run -t --name="tv7playlist" -p 8000:80 -e "UdpxyUrl=http://your.host.ip.of.udpxy:4022/udp" -v tv7playlist_data:/data  --restart=unless-stopped phaefelfinger/tv7playlist:latest

telly - TV tuner

Telly is the ip tv server that exposes itself as HD-Homerun tv tuner to Plex. Plex can use the channel list from telly and match it with its own EPG sources to show you a nice overview of your channels. There are multiple images available. As I had some issues with the latest stable, I use the dev image. Currently including ffmpeg as I’m still testing if I should activate ffmpeg or not. The latest version does not only use environment variables but a configuration file.

You can find Telly on https://github.com/tellytv/telly/tree/dev .

So first, I created the telly configuration file on the host system under /srv/telly/telly.config.toml. I used the template from the github repository above. I had to set some opens as mentioned below.

I set the friendlyname and left thre rest of discovery as it was. To test ffmpeg I can change the line under the IPTV section.

Do not forget to set the base and listen address or it will not work.

[Discovery]
  Device-Auth = "telly123"
  Device-Friendly-Name = "TV7"

[IPTV]
  FFMpeg = true

[Web]
  Base-Address = "192.168.15.2:6077"
  Listen-Address = "192.168.15.2:6077"

# I removed all sources except the last custom one:
[[Source]]
  Name = "TV7"
  Provider = "Custom"
  M3U = "http://your.tv7playlist.host:8000/api/playlist"
  Sort = "group-title"

Finishing the configuration file you may start the container.

In portainer:

  • In portainer set the name to tellydevffmpeg
  • Use the image tellytv/telly:dev-ffmpeg
  • Under Advanced container settings select Volumes
    • Click on Add additional volume
    • Select Bind on the right
    • Enter /etc/telly/telly.config.toml for the container
    • Enter /srv/telly/telly.config.toml for the host
  • Under Advanced container settings select Env
    • Click on add environment variable
    • Set name to TZ
    • Set value to Europe/Zurich or what your timezone is
  • Under Advanced container settings select Network and there host
  • Under Advanced container settings select Restart policy and there set Unless stopped
  • Hit Deploy the container to finish

Use the following command if you prefer the terminal:

docker run -t --name="tellydevffmpeg" --network="host" -e "TZ=Europe/Zurich" -v "/srv/telly/telly.config.toml:/etc/telly/telly.config.toml" --restart=unless-stopped tellytv/telly:dev-ffmpeg

Plex

Now that all containers work, you should be able to add the tuner to Plex. To do this go to Settings and then left to Live TV & DVR. You now use the add button to open the windows to add telly as a TV tuner. If Plex does not find telly automatically, you may enter the IP and Port of telly like telly.host.name:6077 and force Plex to connect.

If you get a list of available TV Channels, your setup seems to be ok. Plex also likes to know which EPG it should use. I would just accept the automatically matched defaults until your test are completed and you like to finalize your setup.

Here you may change the EPG mapping later and enable or disable some channels.

Congratulations! You just have set up TV7 on your Plex system.

Recording

Recording is really simple. When you klick on record on a given show or movie, plex asks where to save it. You may use your current libraries or create new empty libraries where Plex should store the recordings. You need to create one of each type as Plex will store shows in a library for shows and movies in a movie library. So I created two Recording libraries Recording Movies and Recording Series. The storage is a ZFS-Dataset of 1TB from my nas and is mounted via NFS. I’m looking forward to see how much space 1TB to store recorded stuff is.

The cool thing is when you start watching a movie / show, you also have the live pause option without recording the show. Y may even go back to where you started watching the movie.

Credits

I took many information and the idea using udpxy and telly from Sebastian Plattner’s Blog . Thanks for your work and the right hints for my setup.

Update 2019-01-28

The tv7 playlist app got a little upgrade. It supports now a small webinterface to manage an sync the list if required. New features are:

  • View all Channels
  • Enable / disable them
  • Set channel number
  • Set channel name

This should help you to better match the channels in plex and only get the ones you really want to.

Todos / open issues

The setup described above is currently running at my home. However, there are some things left to do. There are good chances that I write additional blog posts with my learnings.

  • Tune settings to reduce delay and buffering issues on channel switch
  • Test if multiple streams work at the same time (e.g. record a channel and view another one)
  • Probably create a docker-compose.yml to setup all containers as one stack (low priority)