Tinytron is an ESP32 powered video player with a 1.69 inch display, designed specifically around the ESP32-S3-LCD-1.69 from Waveshare.
It can play MJPEG files from a microSD card, or stream video content from a computer over WiFi. It runs on battery, features a web interface with Wifi access point mode for configuration, and can be controlled with a single physical button.


There are plenty of great ESP32 TV projects around (credits name a few). Tinytron is my attempt at standing on their shoulders to make one that's very easy to build and use:
Note: with these goals in mind, I chose not to support audio playback in this project.
I sourced parts from Aliexpress and Amazon, and designed the case around them.
One of Tinytron's goals is to keep the BOM as short as possible. Only 3 parts, and 6 easy solder joints are needed. There is no audio amp nor speaker in this project.
| Part | Notes | Link (non affiliated) |
|---|---|---|
| Waveshare ESP32-S3-LCD-1.69 | This is the non touch version. The touch version has thicker glass and a different footprint. | Amazon.fr, Aliexpress |
| Micro SD card reader breakout board | The case was modeled after this exact board. Dimensions: 18x18x20mm |
Amazon.fr |
| 400 mAH 3.7v LiPo battery | Important: the default connector is PH2.0 which isn't compatible with the Waveshare dev board. I spliced a connector but you can custom order the correct one (JST1.25mm) from the battery seller. Technically optional it is possible to power the device via USB C connector. Dimensions: 6x25x30mm |
Aliexpress |
| Micro SD card | FAT32 formatted. Also technically optional since the project can also stream video over local network. |
The case design is inspired by late 90's TV/VCR combos like the Sony KV-14V6D. It was made with OnShape and has 4 parts: front, back, bezel and button. Glue is required to stick the bezel to the front part, the rest of the assembly snap fits (with pretty tight tolerances). Printing the parts separately allows for interesting color combinations.


The case was only tested with Prusa MK4S and PLA. It prints with 0.28mm layers in about 30 minutes and 16 grams of material. I tried my best to limit the need for supports but paint-on supports (pictured in green in the screenshots below) are recommended in select spots for best results.
| Part | Face on print bed | Paint-on support |
|---|---|---|
| Front | Front face | Inside of USB C slot |
| Back | Vent side | Around the curved edge on the print bed |
| Bezel | Flat side | None |
| Button | Top side | None |


Assembly only takes a few minutes. You'll need a drop of plastic glue or cyanoacrylate glue, a bit of electrical tape, a soldering iron and flush cutter pliers.
Solder the 6 pin header to the SD breakout board. Trim the pins underneath.
The ESP32 dev board comes with a cable that breaks out some IO. We need to cut some of the wires to save room, and use the rest to connect the SD card reader.
Separate the lines that we'll keep from the ones we'll cut according to the table below, triple check everything and cut the unused wires flush against the connector. You can change the suggested wiring if you update the platformio.ini file accordingly, but these are the default.
| Keep | Description | Cut |
|---|---|---|
| Black | GPIO18 | |
| Red | GPIO17 | |
| GPIO16 | Green | |
| GPIO3 | Yellow | |
| GPIO2 | Black | |
| Red | SDA (GPIO11) | |
| Brown | SCL (GPIO10) | |
| U0TXD | Orange | |
| U0RXD | Green | |
| Blue | 3v3 | |
| Purple | GND | |
| 5v | Gray |
Connect the female pin sockets from the uncut wires to the micro SD board like so:
| Cable color | Label on SD board | ESP32 pin |
|---|---|---|
| Blue | 3v3 | 3v3 |
| Brown | CS | SCL |
| Red (the one next to black on the cable) | MOSI | GPIO17 |
| Red (the one next to brown on the cable) | CLK | SDA |
| Black | MISO | GPIO18 |
| Purple | GND | GND |
Then wrap a bit of electrical tape around the male pins in order to create a makeshift connector that you can easily unplug and plug back. Detach it from the SD board for now.
⚠️ Warning: Be very careful never to plug your home made connector the wrong way: you'd swap the Ground and 3v3 lines and and most likely damage the hardware.
The first step is to glue the bezel on the front piece. If you aren't confident that you can one shot the alignment, use a piece of painter tape as a hinge to align the two pieces, then open it, add some cyanoacrylate or plastic glue, and snap it back in place.
The rest of the assembly requires no glue nor any tool and takes about 3 minutes, but please DO READ THE ADVICE BELOW VERY CAREFULLY BEFORE PROCEEDING.
⚠️ Warning: The tolerances are very tight, be gentle when manipulating the display or you might break it (trust me, I know). Watch the video and respect the insertion order of the display.
Assembly is quick, but there are 4 points to be pay attention to:
In case you need to reopen the case, look for the small notch (left side when facing the display), insert a flathead screwdriver and gently twist it. The case should snap back open. In my experience - and it depends on the filament used - it's rather difficult to open it with bare hands.
You can flash the latest build directly from this page: simply connect your ESP32 to this computer over USB C, click the Connect button, and follow the instructions.
Note: this is a "factory firmware", flashing it will erase the memory and any previous settings (WiFi etc.) that might be stored on your device. To update the firmware to a new version without losing your data, prefer the other methods below.
This project is built with PlatformIO. You can use the PlatformIO extension for VSCode or the command line interface.
To build the project locally and flash it to the device, connect the ESP32-S3 board via USB and run:
platformio run --target upload
Once the initial firmware is flashed, you can perform subsequent updates over the air. Connect to the device over WiFi, go to the Firmware tab, select your ota firmware file and click "Upload Firmware".
You can find a build of the latest OTA firmware here, or you can build it yourself as explained below.
platformio run
Then, navigate to the device's web UI, go to the "Firmware" tab, and upload the firmware.bin file located in the .pio/build/esp32-s3-devkitc-1/ directory of the project.
You'll need a FAT32 formatted SD Card, and properly encoded video files (AVI MJPEG). Keep the file names short, and place the files at the root of the SD Card. They will play in alphabetical order.
You can use this web page to convert video files in the expected format (max. output size 2Gb). It relies on ffmpeg.wasm for purely local, browser based conversion.
For much faster conversion, the ffmpeg command line tool is recommended. This is what the web version does:
ffmpeg -y -i input.mp4 -an -c:v mjpeg -q:v 10 \
-vf "scale=-1:240:flags=lanczos,crop=288:240:(in_w-288)/2:0,fps=25" \
out.avi
In case you arent ffmpeg fluent, here's a breakdown of what this does:
| Option/Parameter | Purpose |
|---|---|
-y |
Overwrite output without prompt. |
-i input.mp4 |
Input file (use your own file name here). |
-an |
No Audio. Discard the audio stream, we don't need it. |
-c:v mjpeg |
Video codec: Motion JPEG (MJPEG). |
-q:v 10 |
High Quality (Quantizer 10), ranges [1-31], lower value is higher quality. |
-vf "..." |
Video Filter Chain: |
scale=-1:240:flags=lanczos |
Scale to 240px height, auto-width, using Lanczos algorithm. |
crop=288:240:(in_w-288)/2:0 |
Crop to 288x240, horizontally centered. It's 8 pixels wider than the display, but the JPEG decoding library performs faster with multiples of 16. |
fps=25 |
Cap FPS to 25. |
out.avi |
Output file name and container. |
Long press the button (1 second) then release it to turn the Tinytron on and off.
If a FAT32 formatted SD card containing .avi files is detected at boot, the device will automatically start playing them in alphabetical order. You can use the button to control the playback:
In SD Card mode, WiFi is disabled to save battery.
If no SD card is detected, the device enters WiFi mode. It will attempt to connect to the previously configured WiFi network.
If the device fails to connect to a previously configured WiFi network (or if no network is configured), it will start in Access Point (AP) mode.
Tinytron.192.168.4.1.The web interface allows you to:
README.md with marked, new.css the Inter font and a GitHub corner.