Just Arrived in the USA! Check my resume here.

· 5 min read


An automated linear TV channel broadcast FTA in Port Vila, Vanuatu.

1NOMO is a locally run and broadcast channel in Port Vila with the intention to compete with the only other locally broadcast television channel. Since we would have an automated system that could handle playlist generation and video transitions without human intervention, we hoped to capitalize on cheap advertising rates and more advanced social integrations via Facebook inspired by popular streaming services.

We launched quietly in the end of 2019 in hopes to test out the system and begin making some approaches to local businesses for advertising (our prices were an order of a magnitude cheaper) but we all know what slowed the economy and shut our borders down a few months later.

I truly believe the project could have grown into a major business on its own with the deals we setup for local producers for news programs, cooking shows, etc. and our automated system meant we could afford to offer cheap advertising too. But, things didn’t work out that way so let’s focus on the technical elements of the project from here on out.

The project is comprised of a few primary elements.

  • Media Management
  • Advertiser Campaign Management
  • Playlist templates and schedule solver
  • Live video overlays
playlist template


The core components of the system were:

  1. Media storage
  2. Playout server
  3. Management server
  4. Stream server

Media Storage

Our office already had 2 redundant FreeNAS servers which had some empty expansion slots remaining. Into those expansion slots I added 2x4x6TB drives giving us 16TB of usable storage on the ZFS filesystem. With a bit of configuration we then had a backup on the second FreeNAS system.

Playout Server

Playout refers the machine that actually plays the media content for broadcast. A mid-range desktop works well for this to prevent any hiccups in media playback. On the playout server we run OBS which actually plays the media content and other segments.

I found OBS to fit our needs just fine, although at first we looked at multiple other options such as CasperCG, Nebula Broadcast, and VLC among others.

OBS had a great websockets server so we could remotely control it, support for drag-and-drop layouts which even non-technical users could setup, and supported streaming right out of the box.

Management Server

The management server runs everything else from web interface to background tasks to Telegram bot for remote monitoring and management.

Stream Server

The stream server was comprised of an Nginx instance with the RTMP module installed and a small Flask app that provided authentication for the incoming streams. From this server we could provide an HLS stream to our public website and re-stream to Facebook via stunnel.

Web Interface

The web interface is built with Flask and allows us to build the week’s playlists, import new content and setup advertisements all in a morning.

Media Managment

media managementadvertiser campaign

Playlist Solver

Playlists are built following templates which are composed of clocks.


Clocks are the building blocks of a template. Clocks are composed of a duration, an optional set of tags and a type of of content such as a series, a movie, or an OBS scene.

During playlist generation, clocks are used to choose the actual media files to schedule into the playlist. A series would select an episode, a movie would select based on the tags of the clock and a scene would tell OBS to change its current active scene to the name given. Those scenes would often contain an external stream such as ABC news.

scheduled clock


Templates allow us to build repeatable playlists for different days. Clocks are placed on a 24 hour timeline to build the template. Clocks can be either premiere, repeat or random types. Premiere is often used for series which means the playlist generation should select the next episode in the series incrementing one episode since the last premiere. Repeat allows us to play the last premiere episode again at a later time. Lastly, random selects either a random episode of a series or selects randomly from the pool available content that fits the given tags on the clock.

playlist template


Playlists are built from templates that are assigned to that particular date. 1Nomo is linear because playlists should be built one after the other so our playlist generation can accurate find the next episode to play for a premiere or schedule the correct advertisements for the date and time of day.

However, playlists can be overriden and selected media within a playlist can be changed and the clock can be resolved to fill in the remaining duration.

scheduled template

Each clock in a playlist usually follows a pattern

  1. a bumper
  2. the main clock content
  3. a “be right back” bumper
  4. any advertisements for the clock’s date/time
  5. a promo
  6. any filler media to pad any excessive time remaining in the clock
  7. a PSA
  8. one or more dynamic segments that can exactly fit the remaining duration

Dynamic Segments

Dynamic segments are elements of a playlist that tell OBS to change to a given scene. These scenes have some sort of background video, music track and a browser overlay with transparent background that shows the background video. Some dynamic segments we have are an “Up next” which shows the names of upcoming series or movies, weather segment and a COVID-19 update segment.

These were built as a collection of small Vue.js apps which pulled data from the our API to create the segments. A benefit of this approach was they had no particular duration and were always updated on the fly.

These segments relied on our API and we would run periodic tasks to process weather data or COVID data from the WHO and local authorities so our segments had data they could fetch quickly.

Up Next Overlay

Weather Overlay

COVID 19 Overlay

Primary Overlay

The primary overlay contained our logo and periodic news ticker.

The logo would also periodically give the current weather or promote our Facebook page.

  • python
  • obs
Back to Projects