(OLD VERSION) Installation and Setup of FakeTV

Moe Fwacky
16 min readMay 15, 2017

Note: These instructions are out of date. FakeTV uses a different script and has had some enhancement since this was written.

FakeTV when ‘off-air’

I’ve been asked a few times to get full installation instructions for FakeTV. So here it is, how to set up your very own simulated broadcast station. I realized while putting this together that FakeTV is made up of a lot of different parts working together and talking to each other. To keep things organized, I’ll be breaking down the instructions first by hardware, then by software when necessary.

Plex Server Installation

This is first because it’s the most important. Your Plex server is the backbone of FakeTV and absolutely required for everything else to work. If you already have a Plex server setup you are happy with, you can skip this section. If you don’t already have a Plex server set up, you’ll be setting one up now. In my own, I use a Raspberry Pi 3 connected to the network over ethernet and attached to two powered USB hard drives. I do it this way because I want my FakeTV to be independent of other systems. However you can choose to install your Plex server in any environment you choose.

Raspberry Pi 3

My Raspberry Pi 3 Plex server in its natural environment

This is how mine is set up. It works very well as long as all the media is supported by Direct Play. If everything is in h.264, then this will work fine for you, but if your media needs to be transcoded, consider a more powerful option. For this setup, you’ll need a Raspberry Pi 3, power adapter, micro SD card (at least 8GB), external powered USB hard drive and an ethernet connection. Make sure you have enough network ports to plug everything in (don’t depend on WiFi for this), so you may also need a network switch. To install the software, first flash Raspbian to your SD card. Once flashing is complete — assuming your PC is running Windows here — open the SD card location in Windows Explorer and add an empty file to the root directory named ssh. Ensure the file has no extension (such as .txt, .doc, etc.) and eject the card from your computer. This will enable connection over SSH. Install it in the Raspberry Pi and power it up. From there, I recommend following these instructions by Daniel Adbilla.

Windows / OS X / Linux

This is the most common method of installation for the average person. Regardless of your operating system, Plex provides instructions on installation and setup of your server. If you don’t mind your FakeTV installation requiring your PC being turned on all the time, then this is an adequate solution.

NAS Device

This is probably the best and most expensive option. A NAS is the best way to keep your media safe, and run the server without having to lean on your PC. The installation instructions linked above also cover how to install the server on a NAS, if you have one.

Build the Plex Server Media Libraries

Once your Plex server is set up, your next step is to add media and scan it into your library. As the Plex server installation page indicates, make sure your media is using proper folder structure and naming conventions.

From the Plex help page on naming conventions:

Movies are gathered together in a “Movies” type folder, TV Shows in a “TV Shows” type folder, etc.
Movies are named as follows:
[Movie_Name (Release_Year)]
e.g., Avatar (2009).mp4

TV Show episodes are named with the season and episode:
[Show Name SxxEyy]
e.g., Dexter s01e01.mp4

TV Show episodes are stored in their own folder as follows:
/TV Shows/Show Name/Season/episodes
e.g., /TV Shows/Dexter/Season 01/Dexter s01e01.mp4

For TV shows, the folder structure can be very important. Make sure you have show folders that contain season folders that contain the episodes

A great resource I’ve found for renaming TV episodes is FileBot. FileBot scans your media, then downloads the show information from TheTVDB and renames the files according to a format that Plex understands. It can take a little tweaking in some cases, but overall it’s excellent and a great time-saver.

Once all of your media is in place and properly named, it’s time to create libraries. This Plex help page has information on creating libraries if you’ve never done it before. For FakeTV, you’ll want to add TV Shows, then Movies, then if you’re like me, Commercials (use the ‘Other Videos’ library type). If you have a large library, you’ll want to give this plenty of time to scan before installing the controller.

Plex Client Installation

My Raspberry Pi 3 running RasPlex

These instructions will assume you don’t have a Plex client set up and that you’ll be using a Raspberry Pi for yours. If you have a client you’d like to use, then by all means skip this step. I chose to use a Raspberry Pi for mine because I wanted a dedicated device that could occupy one of the HDMI ports on the TV and (almost) always be playing something. In addition to the Raspberry Pi, you’ll need a power cable, microSD card (4GB minimum), ethernet cable (again, don’t trust this to WiFi) and HDMI cable to connect to the TV.

Download and install the software

Since the hardware is a Raspberry Pi, the software is RasPlex, a Plex client built for the Pi. Installation is easy, just download one of the installers and follow the directions in the software. Make sure your microSD card is inserted into whatever card reader you’re using on your PC and the software will flash it with a fresh RasPlex install.

Configure the appearance

Selecting the Plex — Black Edition skin

Once the software is installed, you can insert the microSD card into the Raspberry Pi, plug everything in and get started. Ensure that the microSD card is properly seated and the HDMI, ethernet and power cables are secure. With a keyboard plugged into the Pi, press the left arrow key and select Preferences from the menu. The first menu option is ‘Skin.’ Select this option and the first option (also ‘Skin’)in the submenu. From there, select ‘Plex — black Edition’ from the available choices. I’ve chosen this skin for its ease in removing the menu from the home screen, as I’ll detail further below.

Selecting a background image

Below the skin selector is the Settings menu, Click on that and deselect all of the options on both the ‘General’ and ‘Home Decks’ menus. Under ‘Backgrounds,’ select “Disable Home Slideshows and select ‘Custom Single Home Background Image’ to set your background. Finally, under ‘Expert,’ select only the option ‘Hide warning and error notifications.’

Setting location and time zone

Back under the ‘Appearance’ menu, select ‘International’ and set your time zone. Once set, click down to ‘Screensaver’ and set ‘Screensaver mode’ to ‘None.’ I’ve also gone through and deselected everything in the ‘General’ section, but it’s probably not necessary given that we’ll be eliminating the menu from the home screen anyway.

System and Network Settings

Signing into the Plex account

Under the ‘System’ section, represented by the gear icon, select the ‘Plex’ submenu and select ‘Sign in to Plex.’ From there you’ll receive instructions to navigate to plex.tv/pin and enter the information on screen. Once authorized, navigate to ‘Power saving’ and set the Shutdown function timer to off. Set other settings as desired, then navigate to the network preferences section. Under ‘Media Server’ click ‘Manually specify server’ and enter the IP address of the Plex server. Once you’re done here, you can exit back to the home screen.

Eliminate the menu

These instructions are specific to RasPlex and the Plex — Black Edition skin, which we switched to earlier.

I had tried changing all of the menu bar options to black, but it was still bothersome.

In the early days of FakeTV, there was one thing that spoiled the experience for me, the Plex menu bar. Every skin had one, and no amount of customization could mitigate that. So instead, we’ll eliminate it from the theme entirely.

Open up your preferred SSH client (such as PuTTy) and point it at the IP address of your Plex client. Log in with username root and password rasplex. With your preferred text editor (I use nano), open the HomeMenu.xml file in the /storage/.plexht/addons/skin.plex_black_editionHT/720p/ directory and comment out the following lines (comment tags included below):

<!--
<control type="image">
<include condition="!Skin.HasSetting(BiggerHomeMenu)+!Skin.HasSetting(BiggerHomeMenu3)">HomeMenuWidth</include>
<include condition="Skin.HasSetting(BiggerHomeMenu)">HomeMenuWidthBigger</include>
<include condition="Skin.HasSetting(BiggerHomeMenu3)">HomeMenuWidthBigger3</include>
<include>BGDarkenImage</include>
<height>720</height>
</control> -->
<!--
<control type="image">
<include condition="!Skin.HasSetting(BiggerHomeMenu)+!Skin.HasSetting(BiggerHomeMenu3)">HomeMenuWidth</include>
<include condition="Skin.HasSetting(BiggerHomeMenu)">HomeMenuWidthBigger</include>
<include condition="Skin.HasSetting(BiggerHomeMenu3)">HomeMenuWidthBigger3</include>
<include>BGMainOverlayImage</include>
<height>720</height>
</control> -->

Once you’ve added the comment tags, save the file (ctrl + o if you’re using nano) and exit (ctrl + x). Type reboot and hit enter. When RasPlex reboots, you should only see the background on the screen and no menu. If you need to access the settings menus, you can hit the left arrow key (←) on an attached keyboard and navigate from there. Note that only the highlighted menu item will be easily visible, due to removing the background the text normally sits on top of.

You can faintly see the menu to the left, pressing the left arrow key again will dismiss it

This concludes the client setup portion of these instructions. At this point, you should have a working Plex server and client, both logged into your Plex account. From here it’s time to set up the controller, which will become the brain and arms of FakeTV, knowing what switches to flip and when to flip them. Before starting on the next section, ensure that your Plex server has finished scanning and updating the library.

Installation and setup of the Plex Controller

My Plex Controller Raspberry Pi, seated with a 2.8" PiTfT screen.

The Plex Controller is a python script that I have only ever run in Linux on a Raspberry Pi, though it may also work in Windows. I use a Raspberry Pi 2 B+ to run mine, in addition to an attached 2.8" display for status information (more on that in the future). These instructions will be specific to the Pi, but if you’re intent on using a different device, it shouldn’t be too difficult.

To start, you’ll need to flash your SD card with Raspbian. If you are planning on using a PiTfT screen as a status display like I have, then I recommend using this version of Raspbian which has the drivers for 2.4", 2.8" and 3.2" screens or this version if you have the 3.5" screen. I will post follow-up instructions on using a screen as a FakeTV status display soon, but consider this the first step in that process.

If in Windows, use Win32DiskImager to flash your memory card. Then, before ejecting the card, open the card location in Windows Explorer. The root directory is the /boot/ directory in Raspbian. Add an empty file named ssh, with no extension to the directory. This will enable SSH access without having to plug in a monitor first. If some of these instructions seem familiar, it’s because they’re the same as when setting up the server on a Pi.

Now you can eject the card from your PC and install it into your Raspberry Pi. Plug in the network and power cables and fire up PuTTy or your preferred SSH client. Once your Pi has started up, point PuTTy at its IP address and connect. When prompted for a username, enter pi and raspberry for the password. Our first order of business will be to change that default password. Once logged in, type sudo raspi-config and select the second option titled ‘Change User Password.’ Set it to something unique that you won’t lose, and hit enter. Once the password is set, you should expand the file system and set the time zone in the ‘Internationalisation Options.’ This is important, because if not set to your local time zone, scheduling will be offset based on your time zone’s position relative to UTC. Also during this time, you can take the opportunity to enter the ‘Advanced Options’ and change the hostname to something unique. I use “controller” for mine. Once this is complete, you can exit raspi-config and reboot.

Install Dependencies

Before installing the script, you’ll want to make sure everything’s up to date and install some dependencies. After the Pi has finished rebooting, reconnect and run sudo apt-get update and sudo apt-get upgrade. Then install python with sudo apt-get install python. Next, install the following python libraries (you may need to run sudo apt-get install python-pip before pip install will work):

  • The Python Plex API sudo pip install plexapi
  • Enchant sudo apt-get install enchant and sudo pip install pyenchant
  • web.py for Webhooks integration sudo pip install web.py

Important Note: You will need to add the IP or subnet for your Plex controller device to the authorized IP list in your Plex Server Settings. Look for ‘allowed without authorization.’ If it isn’t authorized, you may run into issues updating the Plex controller database.

Install the controller script

Download the most recent version of the system_setup.py file and place it in your /home/pi directory with curl "https://raw.githubusercontent.com/MoeFwacky/Python-Plex-Controller/master/system_setup.py" -o "system_setup.py", and execute it with python system_setup.py.

The system_setup.py script will create a subdirectory in your home directory, hasystem/ and copy the script files from the repository to your device. The system setup script will prompt you for information in order to get connected with the Plex server and client devices.

Populating the controller database

Once installation is complete, it will prompt you to build and update the database. The Plex controller uses its own database (myplex.db) separate from the Plex server database to avoid any accidental corruption. This has the added advantage of the controller not being affected if you watch content from your Plex server independent of this setup. Once the database has been created and scanned all of the TV and movie data, you’re pretty much ready to go. But, if you’re like me and you’ve created a custom library full of commercials, you will want to run python /home/pi/hasystem/upddatedb_pi.py commercials to add those to the database. A note about the database update script, when using the argument all only the movies and TV shows databases will be updated. Commercials and other custom libraries must be updated separately.

At this point, you should be able to play items from your library through commands issued in the SSH window. Try playme “name of media” or playcommerical if you have commercials set up.

Note: If you enter an incorrect value during setup, which prevents the Plex controller from working properly, you can run python system_setup.py reset from your home directory and it will delete the previously stored data and prompt you to re-enter it.

Understanding play modes

Before I get into creating schedules, I’m going to cover the various play modes available in the script. These are the various play modes you can set the script to. When play checking is turned on (more on that later), or the startnextprogram command is used, the script will play an item according to the mode it's set to. You can check the play mode with getplaymode and set it with setplaymode.

  • normal — Creates a queue and plays items it. It will find more content automatically when the queue is exhausted.
  • block.blockname — Plays through the specified block, when it reaches the end of the block, it will drop back into normal mode. Blocks can be customized (such as a series of shows in a specific order) or random (such as a block of random genre-specific movies). I use the randommovieblock feature to follow the end of scheduled content for the day. It plays 3 movies of the specified genre, which is great for random, middle-of-the-night content.
  • marathon.show — Plays the specified show until the mode is changed.
  • holiday.usercreatedholiday — Plays items from a user-created holiday list.
  • commercialmode — Plays random items from the commercials table unless user plays something else or changes play mode. This is the primary mode I use to play in between scheduled content.
  • custom.customsectionname — plays items from a custom.table user added using upddateddb.py custom.insertablenamehere.

Building a schedule using shell scripts

The syntax to add a scheduled item is addschedule “show or movie” hh:mm day or addschedule “script command” hh:mm day. For day, you have a handful of options. You can choose a day of the week, everyday, weekdays, weekends or today. So, if you wanted the Simpsons to play every weekday at 6:30 PM, you would use the command addschedule “the simpsons” 18:30 weekdays.

Now, as the command only allows for scheduling one item at a time, it can become cumbersome when you’re trying to schedule ten to twenty shows per day, like I do. So, I created a shell script to do the heavy lifting. You’ll need to add a line to the script for each item you’d like to schedule using the template provided. Here is a sample of my script:

Each line schedules a show or command to play on a specific day of the week at a specific time.

As you can see, I have entries at the top scheduled to turn commercial mode on at the beginning of each broadcast day. Once your schedule is built in the schedule.sh file, set its permissions with chmod +777 schedule.sh and execute it with sh schedule.sh. Once the script has finished processing the commands, your scheduled media should start to play at the times you have indicated.

If you looked closely, you would have noticed the above schedule has a gap between 12:30 and 15:00. This is because I have a Sunday afternoon movie that plays starting at 1pm. For date-specific scheduling, I have created a separate script. This script is intended to be run at the beginning of each day. It will check today’s date against the dates in each of the entries, and will add the entries that match today’s date to today’s schedule. Because I’ve allotted a two-hour block for movies, and some movies run for 90 minutes or less, I’ve also added a filler show in those cases to play after the movie ends. You can see a sample of my movies script below.

This script checks today’s date and compares it to the date in each if statement, if they match it runs the command to schedule the movie for today.

As you can see above, you’ll need to use the YYYYMMDD format for your dates in each of the entries. This script will need to be run after midnight each night in order to add that day’s movies to the schedule. More on that in the below section.

Using the play checker and setting up /etc/crontab

Outside of scheduled items, the script has two methods to trigger media to play according to the play mode. There is a play checker script that periodically checks the server to see if anything is currently playing on the client, and if not issues the command to start playback in accordance with the current play mode. The other method relies on webhooks, which are only available to Plex Pass subscribers. I have toyed with the webhooks a bit, and while more quickly responsive, they are triggered when playback stops and had a tendency to conflict with scheduled playback. So, I use the play check script called piplaystate.py. An entry to start this script at boot should be added to crontab when running system_setup.py. Type sudo nano /etc/crontab into the console and ensure the following lines are in your crontab file (you only need the line under #MOVIES if you’re using the movies.sh shell script (make sure the path is correct to the location of your movies.sh file).

@reboot pi python /home/pi/hasystem/piplaystate.py > /dev/null 2>&1 &
* * * * * pi python /home/pi/hasystem/tbn_schedule.py >/dev/null 2>&1 &
#MOVIES
0 1 * * * pi sh /home/pi/hasystem/scripts/movies.sh

In addition to these lines, I have a few others I include in my setup in order to keep the play checker running and turned on during on-air hours, but also not running on the hour and half-hour minutes to avoid conflict with scheduled media. Below is what my crontab file looks like:

The playcheckstatus entries checks if the play check script has crashed and restarts it if it has. There are also a few areas in the script which trigger the play check status to turn off. I haven’t been able to identify why or what causes them yet, so as a stop-gap, I’ve added the playcheckstart lines to turn on play checking every minute. I’ve added the playcheckstop lines around the hour and half hour to prevent the script from checking and executing at the same time as scheduled playback. Then, at the end I have the movies shell script which runs each night at 1 AM and adds anything indicated for that day to the schedule.

Play checking isn’t perfect, and could be improved upon. I’m thinking about finding a way that incorporates both webhooks and play checking for a more responsive system that doesn’t interrupt scheduled playback.

So, that’s pretty much it. If you followed these instructions, you should have a FakeTV of your own. However, if there’s a better way, I’m always open to hearing about it. If you set up your own, please let me know about it and any changes or challenges you may have encountered. Also, I’m not much of a programmer, but have managed to make minor changes to the controller script. But, I’m always open to suggestions from more experienced programmers on methods to make this work better. So again, please comment or suggest changes on github.

Finally, there’s one more bit to the FakeTV puzzle which I’m saving for a future article, and that’s the status screen. You’ve seen me mention that I have a 2.8" PiTfT screen which displays the status of what’s playing. I wanted to include that in this write-up, but decided that this was long enough already. So if you’re interested in using a screen for status information, stay tuned and I’ll work on getting that up soon. In the meantime, enjoy your simulated broadcast experience.

--

--

Moe Fwacky

Just a place where I talk about my various projects