---
title: NINJA Slideshow
url: https://hernandez.systems/en/ninja-slideshow
lang: en
type: caso
alternate_es: https://hernandez.systems/es/ninja-slideshow
site: hernandez.systems
network: Osky Networks
---

# NINJA Slideshow

> A digital signage system with real-time content management that loops images and videos on browsers, Raspberry Pi, Android TV and LG and Samsung smart TVs.

## The problem

Multiple screens from different brands and platforms, spread across different areas, all need to show the same up-to-date content without anyone loading it onto each one by hand. And because the screens stay on unattended, any memory, network or deployment failure ends in a black screen.

## The solution

A digital slideshow system with an admin panel: upload images and videos, reorder them with drag and drop, and every screen plays them in an endless loop. Each change reaches every client instantly through Socket.IO.

It runs in any modern browser, on Raspberry Pi (Chromium in kiosk mode), on Android TV and Google TV (a Flutter app), on LG (a webOS app) and on Samsung (a Tizen app).

## How it works

- **Direct-to-storage uploads:** files go straight from the browser to DigitalOcean Spaces using presigned URLs; files of 100 MB or more are uploaded in parallel parts, up to 2 GB, with a progress bar and a cancel option. The server never holds the file in memory.
- **Real time:** after every upload, deletion or reorder, the server notifies all clients and they refresh their lists.
- **Automated deployment:** scripts that discover screens on the network, install the latest version on all of them (LG, Samsung and Android TV, each with its own tooling), power them on via Wake-on-LAN and shut them down at the end of the day, scheduled with cron. A deployment is only reported as successful if the install actually went through.

## Security

- Admin authentication with signed cookies (HMAC-SHA256) and no server-side sessions, so it works across multiple instances.
- Constant-time comparisons, rate limits on logins and writes, and per-route CORS.
- A strict Content-Security-Policy in production and filename validation against an allowlist.
- The server refuses to start if a secret is missing or too short.

## Documented reliability work

The repository documents how real failures on Android TV were diagnosed and fixed: a memory leak during video playback, half-finished cache downloads that cut videos short, and a screen that turned itself off every 10 minutes. Each fix shipped in a client release.

## Technical details

| Component | Technology |
|---|---|
| Backend | Express and Socket.IO, in TypeScript |
| Web panel | React, Vite, Tailwind and shadcn |
| Storage | DigitalOcean Spaces (S3-compatible) |
| Raspberry Pi and Android TV client | Flutter |
| LG and Samsung clients | Web apps for webOS and Tizen |

## Status

Public code on GitHub: [MoscoDJ/NINJA-Slideshow](https://github.com/MoscoDJ/NINJA-Slideshow).

## Related services

- [Streaming and real-time systems](https://hernandez.systems/en/streaming-and-real-time)
- [Drupal and integrations](https://hernandez.systems/en/drupal-and-integrations)
- [Automation and bots](https://hernandez.systems/en/automation-and-bots)
