I know that it’s only been 1.5 weeks since work began on Project One but I’m making a lot of progress, more than I thought I would. But here we are: Milestone v0.0.1. Let’s talk about this milestone.


The goals for the first milestone included (some things changed along the way):

  • Hardware - Raspberry Pi 4 + 2TB NVMe Hard Drive for Storage (External Enclosure)
  • Main Goal - Play one channel, focused on a single TV Series that plays between specific times of the day, i.e. 5AM-10PM, based on a schedule. Episodes start on the hour (11:00) or at the half hour (11:30) with “bumpers” in between. Each episode “airs” on time.
  • Software - Python, VLC, SQLite3, TheTVDB

I’m proud to say that as of today, I can launch a single Python script and have immediate playback with the expected results as stated in the main goal. Random episodes of Friends is put into a schedule, defined by the Channel Definition file, and for the moment, I have retro Halloween commercials playing in between each episode. I know that one of the rules I had for this project was “no commercials”, but this is temporary and is simply filler for the moment. I debated back and forth about what to put in between episodes like this and honestly, I don’t know what to put in there!

A Deeper Dive on the Workflow

Each time the script is ran, I have the File Watcher scan my external hard drive for new TV Series and Episodes. If a new TV Series is found, it will call out to TheTVDB and pull all the metadata (Series and Episodes) for it. Then, each file is scanned to see if it already exist in a local database. If it doesn’t, the File Watcher will find the episode in the episode metadata file and fill in the blanks. Each episode in the database has metadata such as Show Name, Season Number, Episode Number, Genre, Episode Overview, Year, Duration, and the local File Path. Needless to say, this metadata is key to building a schedule based on channel rules.

The Scheduler comes next once all files have been handled and accounted for. It reads in all Channel Definition files and creates a schedule based on those rules. Finally, the schedule is “set in stone” in memory so that the Program Manager can access it at any time. This comes in handy when we start to change the channel later.

At last, it’s time for the Program Manager to tune into the channel. It determines where in the schedule it should start at, how far into the episode or bumper to start playback, and then play the rest of the day’s schedule from there.


One of the biggest struggles that I came across so far was learning how to properly use Python-VLC. For example, getting your mind wrapping around the idea that simply calling VLC to play via Python doesn’t do what you think. You have to call time.sleep() in order for VLC to continue playing the file.

Secondly, knowing how time works, conversions, and how datetime and timedeltas work in Python was a stretch. I knew in my head things like “Ok, I need to find the time difference between now and the next play time”, but translating that into Python-speak was another story!

There were also the matters of how to use SQLite properly, reading and writing JSON files, and even Lists vs. Dictionaries. But I have learned so much in just the short amount of time working on it.

Random Stuff Goes Here

I started this blog post, going pretty deep into the workflow, explaining every little thing that my scripts do. However, I recall myself watching the RetroTV Youtube video and trying to figure out how to replicate it. There is a challenge here that can be pretty fun and rewarding if you are willing to accept it. It’s no fun when someone spells it out for you, plus, you don’t learn anything.

I won’t be doing a deep dive on the workflow. If you are interested in creating something like this, I highly recommend doing it on your own.

One thing that is a requirement to adding TV Series and Episodes into the database is that each episode must be in a specific format: S0xE0x. I’m pretty good at staying with these naming standards, but when I added another TV Series to my external hard drive, I wondered why they weren’t being added to the database. Turns out my file names didn’t meet what the script was looking for!

Next Steps - v0.0.2?

The next step is adding more media to my external hard drive, testing the File Watcher and Scheduler with multiple channels, and finding a way to “change the channel”. I can then begin to experiment with different channel queries, creating channels like “80s TV”, “90s TV”, “Sitcoms”, etc.

Once I can change channels successfully, movies will be next on the list. Movies will require a bit of work since it doesn’t follow the same format as a TV Series does; the current code was written to revolve around playing TV episodes. There’s also creating a table for the movies in the SQLite DB, pulling metadata from an external source, etc. I can easily say that my first movie channel will be something like what RetroTV’s Pay-Per-View channel does: pick a random movie and play it on loop throughout the day. Then, I can create other channels to pick multiple movies (like Action movies) and play them on a schedule.

I do have some shallow logging in place so I don’t have to scroll through the terminal, but I would like to standardize that in some way.

v0.0.2 is scheduled to include multiple channels, movie support, and standardized logging

Future Plans

Hardware and an enclosure is on my list of things to design, but that’s still down the road from now. The only piece of hardware that I don’t have is a portable monitor, not including things that will enhance the enclosure like status lights, buttons, etc.

I also have some plans for a possible “LAN Mode”; more on that in the future….

Please let me know if you have any questions!