5 min read

Solostation Release v1.0

Solostation Release v1.0
Photo by Sašo Tušar / Unsplash

If you have been keeping up, I have been working on what is now called Solostation for the last 1.5 years as a small passion project. I wanted to create a pseudo cable station that has multiple channels, playing all of my random movies and TV shows, with some random commercials in between. And it's now to the point where I can call the code "good enough" and start focusing on the hardware.

This post will focus on 1.0 features, some pain points, and some behind the scenes stuff for those who care.


1.0 Features


Copying from the last blog post...

  • 24 hour schedule
    • Each channel has a custom schedule built on each run that lasts for over 24 hours, from midnight on the current day until the next day.
    • The feature of extending the schedule automatically and keeping playback going did not make this cut. I tried but I should have planned this from the start. This is something that I feel only a re-write could solve.
  • Commercials
    • Commercials are on channel2 only. If a TV episode is playing, you will see a random mix of commercials from the 1970s through the 2000s. Even though it is the biggest pain of the project, it's also one of the coolest features.
  • Loud! - An MTV clone
    • Music videos all day with classic MTV channel "idents" in between for some fun.
    • The Artist and Song Title is displayed at the bottom of the screen, using the same font as MTV does. I used to show this at the beginning and end of each music video, but I thought it would be a little more modern and useful to just keep it shown the whole time.
  • Movie Channels
    • Motion is a channel that selects and plays random movies, while Bang plays random action movies. Each movie has a 15-30 minute gap between them so you can have a break, watch movie trailers and some select web content while you wait for the next showtime. All movies on these channels start at 15 minute increments (12:00, 12:15, etc).
    • There are now 3 Pay Per View channels to give some variety. Each channel picks a single movie and just loops it all day.
  • Media Manager
    • As long as media is in the proper location, format (MP4 or MKV), and naming standards (see Github), the Media Manager will use TheTVDB's API to pull all information for a TV show or movie. It will also update the local database for web content, movie trailers, and music videos.
    • The idea here is to only pull from the Internet when necessary and keep metadata locally. Solostation is meant to be used offline.


Hurdles, Problems, and Time


This project should NOT have taken me so long to get to this point. I believe that I've re-written all the code at least 20 times by now because I can just never be satisfied with it; it feels like I can always do better somehow.


The last 2 weeks I decided to run my code through ChatGPT and Grok to see what improvements that it would make, and sure enough, my Python skills are not that great. You can actually check it out over in the Git repo under the "v3-classes" branch. But it was a great learning opportunity to fill in my "swiss cheese" knowledge of Python and show me that there are so many ways to accomplish things.


Probably the biggest hurdle through this entire project has to be injecting commercials and getting the timing just right. In a perfect world, you would have commercials for every length of time that just perfectly fit between episode chapters, giving you a solid 30 or 60 minute block of TV. But in reality, you have to code in a more dynamic way, using what you have available to you. Getting commercials to fit while making sure not to go over the alloted time is not easy. I just can't find a way around it. In order to make time blocks work on channel2, Solostation currently plays a filler video just to balance things out and make the schedule work. Again, a re-write of this project may resolve this issue.


Secondly, I've learned that you have to play by the rules of the video player, in this case, MPV. I started this project with VLC in mind, but I found that it was a little hard to work with in Python compared to MPV. Luckily, python-mpv exists. This wrapper made everything a lot easier! The one thing that I have learned about MPV is patience and process. If you tell your code to seek to the proper time based on the schedule, you had better give it a breath to properly load the file first, and THEN seek. I've had to put quite a few checks in place to get the process lined up so that there wouldn't be any interruptions in changing channels.


The Raspberry Pi 4b was a good choice for the project, but I think that a x86 mini PC would have been better due to Python package compatibility and better video playback. If you add anything like flash storage, you will likely have to throw more money at it just to make sure that everything is powered properly. I'm having to use a powered USB hub just to use my 2TB SSD; it's going to make a huge mess with the hardware due to all the cables.


Behind the Scenes


I'm not going to go through the entire process and explain how it all works (read the code, it's not that bad), but let's talk about a few things.


I had to make my peace with SQL during this project and realize that it was the best choice for the amount of media and metadata Solostation needed. The original re-write back in October of 2024 actually used JSON files as a means for a database; this worked, but when things like a schedule were constantly being written over or you were performing more advanced searches, SQL just made more sense. It luckily didn't take me long to get used to it.


All playback is centered around what's playing right now. Nothing is preloaded, there are no playlists involved, no magic trickery here. If an item's start time is right now, MPV will stop everything and play it right away. A playlist-like method would be better to make sure that transitions are smooth, but I could not get this to work with things like channel2 and commercials. Trust me, I've tried many times. However, the trade off is that by doing it this way, changing channels is super fast and the right thing is guaranteed to play at the right time.


Also included is a very experimental web API using websockets. I wanted to have a dashboard that showed everything that was currently playing and how much time the item had left, but it won't be included in the 1.0 release. I figured that if I was actually watching the content, a dashboard wouldn't matter that much. It was just a neat, debugging tool that I used when testing schedule creation.

What's Next?


Now that the code is in a working state, it's time to switch gears and focus on the hardware:

  • 15" 1080P LCD screen w/built-in speakers
  • Raspberry Pi 4b- Powered USB hub
  • 2TB SSD

I want to build an enclosure that is easy to carry, doesn't take up too much room on my office desk, and has a few hardware buttons to perform a few tasks:

  • Safe reboot
  • Safe shutdown
  • Volume up/down
  • Channel up/down

Not sure about what style of buttons, placement, etc, but I'll work on drawing it out soon and sharing here once I have a final design.'


Finally, I would like to step away from the code for a while, but eventually come back for a re-write that better implements Python standards and has the ability to add more features.


If you have any questions about this project, let me know via Matrix [here](@sixstorm:beeper.com).