/ultimate-media-server-core

A bunch of scripts that I've collected, written, and forked for the ultimate administration & automation of your Media Server - Think of this as your "Media server in a box"

Primary LanguageShell

The Ultimate Media Server Setup!

This repo is a constant work-in-progress... If you have any additions, please submit your Pull Requests!

The aim of this project, is to build your perfect media server setup with end-to-end automation in an evening, not weeks - I'll be updating this repo as my own setup evolves, but for now here's a "dump" to help you get the perfect PMS setup! If you're new to this, you should clone down the repo, and start by reading about all the various services that are listed, and then standing up all the services within Docker - one by one - This is the easiest way to get running...

@UPDATES:

July 2020:
- Include Radarr script to move primary directory of a radarr movie (useful if you change your drive/nas structure/layout)'

Aug 2019:
- Added in Health Checking support of key containers, and automatic subtitle downloading support..

Mar 2019:
- I've added in the ability to run multiple Plex transcoders (in multiple Docker containers that you
can split the transcoding process over multiple hosts) if your Plex server has a lot of users.

Dec 2018:
- There's a lot here, I'll add some screen-shots and do a proper blog write-up on this one day so you
can see it all working, for now you'll have to take my word If you want to "cut the cord" - You're
not going to get much better than this!

The setup of Plex Transcoding over multiple servers is a little complex, so it's worth reading: here, here, and here for details, and then going through the docker-compose file for Plex. Note, you can still use the old Plex docker-compose file (read below) if you do not want to have multiple transcoding servers.


My almost perfect media server setup consists of:

Media Servers

  • PLEX! - If you don't know what Plex is, you should start here - Plex is the ultimate Media Server, with apps for iOS, Android, numerous smart TV's and all the rest - It's truly a one-stop media shop.
  • Funkwhale - Your own personal self hosted music server (Think of this as self hosting Spotify or Apple Music!)
  • TvHeadend - Plex is actually configured to talk to this - It's a server to pull in your favorite IPTV or Over-the-air TV Channels (if you have a hardware TV Tuner/Card), Now you can finally cut the cord!

Download Automation

  • Sonarr - Automatically grabs your favourite TV shows, sends them to your download client & organises the files.
  • Radarr - A fork of Sonarr, but for Movies.
  • Lidarr - A fork of Sonarr, but for all your favorite music - Great for pulling in AAC/FLAC tracks that you can't get on Spotify if you're an Audiophile.
  • Bazarr - Bazarr is a companion application to Sonarr and Radarr that manages and downloads subtitles.
  • Jackett - API integration of all of the most popular Torrent Trackers for Sonarr/Radarr.
  • qBittorrent - Reliable, lightweight linux torrent client

Tools & Scripts

  • Tautulli - A monitoring and tracking tool for Plex (Think of this as Google Analytics for Plex)
  • PlexConnect - Hijacks the trailers app on your AppleTV 2/3 (and replaces it with Plex)
  • Ombi - Great way for your friends/family to request (and automate) adding new content to your Plex Server
  • Openspeedtest - Handy to have to test the upload/download speed for your friends/family streaming from you.
  • Beets - This is an essential tool for managing your MP3 library / cleaning up ID3 tags, pulling in Cover Art & Lyrics etc...
  • tvhProxy - This is how you can seamlessly connect TvHeadend into Plex
  • WebGrab+Plus - This is how you pull in all the EPG (TV Guides) from various sites to Plex without having to use a paid metadata TV Guide service...
  • piHole - Better ad blocking for my home network / finally no Youtube ads!
  • Docker Autoheal - A lightweight container, designed to monitor the health of other containers & restart them if they have crashed.

So without further mention, let's dive in and get the thing up and running! (Docker-compose files are based upon the components mentioned above)


1. Clone Repo:

The project uses Git Submodules, make sure you clone the repo using: git clone --recurse-submodules https://github.com/ultimate-pms/ultimate-media-server-core.git /opt/pms-scripts

2. Setup services:

2.1 Install Docker & Docker Compose:

See here for Docker: https://www.docker.com/get-started For Docker-compose: https://docs.docker.com/compose/install/

2.2 Install Plex & other applications mentioned

NOTE: Before running this, you should configure each docker-compose file accordingly! By default everything will mount to a volume called /nas which should be a network s hare to your NAS/External Drive(s)...

Docker compose files are located in the dockerfiles/server directory, and have comments explaining various variables etc.

# Copy compose files into /opt
cp -rp /opt/pms-scripts/dockerfiles/server/* /opt/

# Stand up each container... (go grab a coffee, this will take a while)
find /opt/ -maxdepth 1 -name "docker*" -type d \( ! -wholename /opt/ \) -exec bash -c "cd '{}' && docker-compose up -d" \;

NOTE:

  • The Plex docker files can be split into 4 containers with the UnicornTranscoder for Plex project, which allows you to transcode on multiple servers (if you have a lot of traffic). Please read the docker-compose file for details. By default, Plex will be stood up in a single container.

    • If you want to use this setup, just run: docker-compose up -d --compose-file docker-compose_multi-transcoder.yml from the server/docker-plex directory.

    • If you're going to run multiple transcoders (on other hosts), you just need to run the plex-transcoder-1 part of the Plex docker-compose.yml file, not all the other containers...

  • Don't forget to manually configure Plex in the web/ui once it's running & setup a reverse proxy using something like Caddy (with automatic HTTPS/lets Encrypt).

  • Don't forget to update the<IP-OF-HOST-OR-DNS-FQDN-OF-HOST> (in your docker-compose.yml files) to the actual local IP of your server and/or a DNS name if you're putting a reverse proxy (Caddy/Nginx) in front of it.

3. Configure!

You'll now need to go and configure each service - there's various howto's on the Internet already, when I've got time I'll do a write up.

Useful URLs:

Download Management:

  • Jackett - http://<server-ip>:9117/UI/Dashboard - Start here, configure your torrent indexers to start
  • qBittorrent - http://<server-ip>:8080/ - This is your torrent client, you will ned to configure save-file location, password etc
  • Sonarr - http://<server-ip>:8988/ - Configure, then add in all your favorite TV series you want to start auto-downloading
  • Radarr http://<server-ip>:7878/ - Configure Movies you want to start auto-downloading
  • Lidarr http://<server-ip>:8686/ - Configure for any Music you want to start auto-downloading
  • Bazarr http://<server-ip>:6767/ - Setup your automatic subtitle downloading

Media Server:

  • Plex - http://<server-ip>:22500/ - Access Your Plex Media Server! (via Nginx proxy injecting TVHeadend CSS Fixes) - You should be port-forwarding to this one and sharing with your friends.
  • Funkwhale - http://<server-ip>:8881/ - This is the front-end for Funkwhale if you are using: funkwhale-nginx-proxy
  • tvHeadend - http://<server-ip>:9981/ - You'll need to configure tvHeadend with your favorite IPTV feeds if you want to use the Plex DVR Feature

Analytics & Supporting Tools:

  • Tautulli - http://<server-ip>:8181/home - Analytics about who's watching what media on your network
  • OpenSpeedtest - http://<server-ip>:8081/ - Worth setting up port-forwarding to this, it will allow you to test the download speed (of you internet connection) when accessing your server remotely.
  • Ombi - http://<server-ip>:3579/ - Worth setting up port-forwarding to this one also - It will allow your friends and family to "request" new Series, Movies etc to be added to your server (This way they don't need access to Radarr/Sonarr/Lidarr)

4. Additional Automation & Maintenance Scripts

NB: Some of these Scripts you may want to run once off, others you may wish to schedule in a cron.

Script Language Targets Description
radarr_move_primary_directory.sh Bash Radarr (API) A script to move the primary directory of a radarr movie (useful if you change your drive/nas structure/layout)
radarr_rename-movie-files.sh Bash Radarr (API) Quick and dirty script to hit the Radarr API and rename any movies (via the Radar API) so that they are correctly indexed in Plex
radarr_search-missing-movies.sh Bash Radarr (API) Script that hits the Radarr API to search for any missing movies (Ideally this should be scheduled with your CRON and run each night)
radarr_search-missing-movies-by-year Bash Radarr (API) Same as previous script, but only searches missing movies that match a specific year (i.e. Only search missing movies from 2016)
radarr_cleanup-crappy-movies.sh Bash Radarr (API) I stupidly added in a list to Radarr that imported thousands of low ranking movies that I didn't want .... This is a quick and dirty script to find those movies on the NAS and blow them away if not yet downloaded
radarr_remove-downloaded-movies.sh Bash Radarr (API) Script from 12Nick12 to remove are already downloaded with quality greater than 1080p and older than 2 years.
radarr_remove-undownloaded-movies.sh Bash Radarr (API) I love my lists - but I don't like searching for movies older than year 1992 - Script finds any un-downloaded movies (auto populated from a list) and removes them
radarr_bulk-import-movies-hack.md Javascript Radarr (Browser) If you're like me and trying to import thousands of pre-downloaded movies (around 4,000+ movies) into Radarr, you're not going to want to click through the web-ui manually and add them all...
fake-video-detector Mixed CLI Automatically detect fake videos in your library based upon a 'database' of blacklisted videos
remove-completed-downloads Bash qBitTorrent qBitTorrent script to automatically remove any completed downloads from matching category (tv
convert-to-mp4 Bash N/A Post processing script that you can hook into Radarr (or run on your filesystem via run-nas.sh) that converts all your video files into mp4 containers - NO TRANSCODING IS DONE, The original transcoding, subtitles, audio channels etc are all copied as is - This is a must have as Plex prefers to "direct stream" any content in MP4 format
remove-embedded-movie-titles Bash N/A Post processing script that goes and strips any Metadata titles out of your video file names - This is great if your TV/Movie organizer (Radarr/Sonarr etc) is setup to rename your files as Plex will use the file name to sort Movie/TV not title that is in the file's metadata.
lidarr_search-missing-tracks Bash Lidarr (API) Script to go and hit the Lidarr API (suggest scheduling via a cron each night) to "force search" for any missing tracks against your indexers...
lidarr_last-fm-adder Bash Lidarr (API) Script to query the last.fm API and return new artists to add into your Lidarr search Library...
lidarr_refresh-filesystem Bash Lidarr (API) Iterates through each and every one of your Lidarr artists and triggers a refresh of files on on your filesystem (Useful if you add/update your music library outside of Lidarr so that Lidarr is kept in-sync with new music added)
funkwhale_bump-files Bash Funkwhale Importer A script that runs the "Funkwhale Import" API command to import your music files into funkwhale, then it parses the log files and tries to fix any "known errors" (such as invalid ID3 tags) so that they will be successfully imported to Funkwhale on the next import run.

Here's a copy of my current cron jobs -- update paths accordingly:

############## GENERAL DOWNLOAD/CLEANUP AUTOMATION ##############

# Remove any old, un-downloaded movies before triggering search-all...
45 2 * * * /opt/pms-scripts/scripts/radarr/radarr_remove-undownloaded-movies.sh

# Trigger nightly 'Search all' in sonarr/radarr/lidarr for any missing series/episodes...
30 1 * * * /opt/pms-scripts/scripts/lidarr/lidarr_search-missing-tracks.sh
0 3 * * * /opt/pms-scripts/scripts/radarr/radarr_search-missing-movies.sh

# Cleanup any completed torrents that have been post processed and are just left seeding...
20 * * * * /opt/pms-scripts/scripts/qbittorrent/qb_remove-completed-downloads.sh

## Script to go and remove those pesky embedded movie file names from mp4 files that mess up Plex's auto file names...
30 3 * * * /opt/pms-scripts/scripts/post-processing/remove-embedded-movie-title-bulk.sh

############## TV TUNER & IPTV ##############

# PUSH EPG DATA FROM WEBGRABP DOCKER CONTAINER TO TVHEADEND - RUNS EVERY 2 HOURS
25 */2 * * * cat /opt/docker-webgrabplus/config/guide.xml > /opt/docker-tvheadend/config/data/wg.xml

## Create EPG Data/guide for Plex to import (from tvheadend - Runs every hour)
30 */2 * * * wget http://127.0.0.1:9981/xmltv/channels --user=admin --password=xxxxxxxxx -O /opt/docker-plex/config/iptvGuide.xml

## Fire off API request to Plex to refresh Guide Data from the EPG file we just created (By default plex only does it once a day)
31 */2 * * * curl -X POST "http://127.0.0.1:32400/livetv/dvrs/1/reloadGuide?X-Plex-Token=xxxxxxxxxx" # NB: you may need to update the number after /dvrs/ to reflect the DVR number you have in Plex

############## MUSIC SERVER ##############

## Import files into funkwhale - Try avoid running in evenings/peak time...
0 4 * * * /opt/pms-scripts/scripts/funkwhale/funkwhale_bump-files.sh
0 11 * * * /opt/pms-scripts/scripts/funkwhale/funkwhale_bump-files.sh
0 16 * * * /opt/pms-scripts/scripts/funkwhale/funkwhale_bump-files.sh

## Cleanup any rouge files that have slipped through beets...
40 2 * * * find /nas/Music -type f -not -regex '.*\.\(jpg\|png\|mp3\|lrc\)' -delete

And some more Docker based scripts:

Script Language Targets Description
plex2netflix Nodejs Plex (API) Dockerised version of the plex2netflix NPM which checks how much of your content is on Netflix
ical-to-xmltv Python N/A Script to go and pull in an iCal/Google Calendar feed and convert it into XMLTV format so you can get EPG Data from it (an example here is the schedule on twit.tv)