Nomad: Ultimate Mini WIFI Media Server

by Jstudner10 in Circuits > Gadgets

15895 Views, 117 Favorites, 0 Comments

Nomad: Ultimate Mini WIFI Media Server

Jcorp Nomad Promo
IMG_20250811_123538_110.jpg
Screenshot 2025-08-11 063208.png

Hello Makers!

I’m Jackson Studner, a mechanical engineering student and hardware enthusiast who dove into coding, embedded systems, and web UI design through this very project. Nomad is my first major software/hardware hybrid project, a portable offline media server powered by the ESP32-S3 microcontroller, designed to be compact, reliable, and fully open-source.

What is Jcorp Nomad?

Nomad is a self-contained, battery-friendly media server that fits in your pocket. It creates a local Wi-Fi hotspot with no internet connection needed, allowing you to stream your own movies, shows, music, books, and more directly from a microSD card. It’s perfect for camping, road trips, classrooms, or any scenario where connectivity is limited or unavailable.

This device functions similarly to popular media servers like Jellyfin but is fully offline, ultra-portable, and simple to use. It supports multiple simultaneous streams (tested with up to 8 videos at once), offers a customizable Screen UI via SquareLine Studio and LVGL, and works with most browser compatible devices, phones, laptops, tablets, etc.

Why I Built This

As someone who loves camping and road trips, I frequently ran into problems with entertainment options. Streaming apps depend on cell signal and pre-downloading content can be restrictive or difficult to manage. Nomad solves this by letting you carry your own personal media server that anyone nearby can connect to, no cellular data, no cables, no fuss.

Key Features

  1. Local Wi-Fi hotspot with captive portal, no internet connection required
  2. Stream movies, shows, music, books via browser-based UI
  3. Media hosted on FAT32-formatted microSD card (up to 2TB in theory)
  4. Supports multiple concurrent streams (up to 8 tested, depends on your encoding)
  5. Compatible with a wide range of devices and browsers
  6. Admin panel controls that allow for basic development and file changes on the go

Who Should Use Nomad?

  1. Whether you’re a traveler, educator, parent, or hobbyist, Nomad offers a lightweight, offline media solution designed for maximum flexibility. It’s open source, so you can customize it or build your own version, no specialized skills required beyond basic hardware flashing and SD card management.

Supplies

6126iPTIR0L._AC_SL1280_.jpg
Screenshot 2025-07-07 195744.png
Screenshot 2025-07-07 192338.png

What You'll Need

Below is a general list of the hardware, software, and accessories you’ll need to complete the Jcorp Nomad project. I’ve included notes on options for customizing your build depending on your goals, whether you want to save money, maximize portability, or make it uniquely your own.

Note: The links below are Amazon affiliate links. If you click and buy something, I might earn a few cents—just enough to fund more SD cards and maybe one day a coffee that isn’t instant. Thanks for supporting the project (and keeping me caffeinated)!

Waveshare ESP32-S3 with 1.47" Display


Alternate link with better shipping times: Amazon Link (affiliate)

This all-in-one development board powers the entire project: Wi-Fi, display, and SD card support all on a single compact PCB. While it’s possible to build a Nomad using separate components, this board is by far the easiest, cleanest, and most space-efficient method.

MicroSD Card (16 GB or larger)


I recommend at least 64 GB if you want to store a decent media library, but the system will work with as little as 16 GB if you only need a few files. Make sure to format the card as FAT32, ESP32 has compatibility issues with exFAT and NTFS.

If you’re feeling adventurous (or just absurdly wealthy), the project should support 1.5–2 TB SD cards. I haven’t tested those sizes yet, but if you do, please get in touch, I’d love to build a custom UI for your glorious overkill setup.

SD Card Extenders

These are not required, and sadly you can only bulk buy ones that are the right length (if I can find a different version I will update) The appeal of these is that you can access the SD card from the back of the case without removing it, making it a fair bit more clean. If you don't need to access the card often you can skip this part.

These will make it easier to access the SD card without disassembling the entire unit and improve durability.

3D Printed Case (Optional but Recommended)

Included in the project files is a 3D printable case for the project. This mainly serves to protect the screen as its not very durable and the sides / wiring can get damaged easily. I will soon update a version that doesn't have the SD card extender, and instead uses screws. You can glue the screen cover on, but in general it should be fine as a snap fit.

Want to customize it? Add your name to the backplate, decals, ventilation holes, or accessory mounts. As a mechanical engineering student, I recommend trying TinkerCAD for easy 3D modeling.

Software (All Free and Open Source)

  1. SquareLine Studio – For editing the touchscreen UI using LVGL
  2. Arduino IDE or PlatformIO – To compile and upload the firmware to the ESP32-S3
  3. Web Browser – For testing the media portal and UI after flashing

All software tools used are free, cross-platform, and beginner-friendly. No professional coding experience is needed, if you can copy-paste, follow a few instructions, and tolerate some compile errors, you’ll do great.

My code isn’t perfect (it’s held together with duct tape and good vibes), but if you get stuck, feel free to drop a comment and I’ll try to help however I can! Also check out the discussions page on github, lots of documentation of past issues and ideas.

Get the Code and SD Card Layout

All source code, firmware, UI files, and a downloadable SD card template with the required folder structure and sample media are available here:

GitHub Repository: https://github.com/Jstudner/jcorp-nomad

Clone or download the repository to get started.

Prepare the SD Card

Screenshot 2025-07-07 200625.png
Screenshot 2025-07-07 200703.png

Before powering up Nomad, you’ll need to prepare the SD card with the correct folder structure, media files, and interface content. This is how your ESP32-S3 knows what to serve and how to present it to connected devices.

  1. Important: The SD card must be formatted as FAT32, or the ESP32-S3 won’t be able to read it properly. (this is a hardware limitation. you can do this using fat32format software linked below.

Formatting SD Cards

Windows won’t let you format cards larger than 32GB as FAT32 by default, but don't worry, there's a free and easy workaround.

Use the GUIFormat Tool:

  1. Download the tool from https://fat32format-gui.en.lo4d.com/windows. (updated to a safer version)
  2. Insert your SD card into your computer.
  3. Launch the guiformat.exe program (no install needed).
  4. Select your SD card’s drive letter.
  5. Set:
  6. Allocation size: 32K
  7. Volume label: whatever you want!
  8. Quick Format: ✅ Checked
  9. Click Start. It’ll format the entire card as FAT32, even if it’s 64GB or 256GB.
  10. Remember the key limitation of fat32 is that no single file can be bigger than 4GB

⚠️ Double-check that you selected the correct drive letter, this will erase everything on that card!


Required Folder Structure

Here’s the standard layout your SD card should follow:

/assets #JS libraries
/Books #directory (folder)
/Movies #directory (folder)
/Music #directory (folder)
/Shows #directory (folder)
/Files #directory (folder)
/Gallery #directory (folder)
appleindex.html
index.html
menu.html
books.html
movies.html
music.html
shows.html
gallery.html
files.html
admin.html
favicon.ico
Logo.png
placeholder.jpg
media.json

A downloadable SD card template is included in the GitHub repository. You can download that directly to your SD card to get started. It include sample media you can use to test before gathering all of your real content.

Requirements:

  1. Books, Movies, Music, Shows, Gallery, and Files folders must be present, even if they’re empty.
  2. The Shows folder must contain subfolders for each show:
/Shows/The Office/
/Shows/Breaking Bad/
  1. Inside each show folder, place the individual episode video files.
  2. You can rename the media files to whatever you want, but it’s strongly recommended to use a consistent format like:
  3. Shows only take a jpg image for the folder, they should not go inside the folder and the episodes will not use images.
S01E01 - Pilot.mp4
S02E03 - Cool Episode Name.mp4
  1. This helps keep the episodes in order (it sorts alphabetically).
  2. Music also supports playlists in the same manner.

File Descriptions

Here’s what each of the key files does:

  1. appleindex.html
  2. This page is shown only on Apple devices (iPhones, iPads, etc.) due to how iOS handles captive portals. It includes special instructions for connecting and using the system.
  3. index.html
  4. This is the default homepage for all non-Apple devices. It automatically redirects based on device type.
  5. menu.html
  6. The first screen users see after connecting. It displays links to Movies, Shows, Books, Music, Gallery, and Files. You can remove a section by editing this file and deleting its link (e.g., remove the “Books” link if you're not including books).
  7. books.html, movies.html, music.html, shows.html, gallery.html, and files.html
  8. These are the individual section pages. They list the content available for each category. a search bar is included that uses in text search.
  9. For Movies each video file should also get a matching jpg image with the exact same name. I recommend getting your Show and Movie Images from https://www.themoviedb.org/?language=en-US
  10. For Shows each show gets one image, it should be in the /Shows directory and named the same as the directory that your episode files are in. Episodes don't have images, it will just display the filename.
  11. For Books you can use PDF or Epub, PDF can be read in browser, epub will only let you download. Include a cover image of the same name.
  12. For Music use mp3, wav, or flac files. You can also have subdirectories like with shows, items in the subdirectories will show on the main page, but also in sorted lists in the playlist page.
  13. favicon.ico
  14. The site’s tiny tab icon. Replace it with your own if you like, but keep the same size and format.
  15. Logo.png
  16. Displayed on the site’s header. Feel free to swap it out with a logo of your own just use the same aspect ratio.
  17. placeholder.jpg
  18. Shown when media items don’t have a cover image. You can replace this too just keep the same size.
  19. Music will be assigned this in media.json, but it doesnt matter since the frontend wont request images.
  20. media.json
  21. This is the database of your media library. It’s read by the interface to display titles and file paths. It must match the files in your folders. This is a SUPER important file, I would not edit this ever unless you know what you are doing. (it contains the paths to images, files, and data for every file on the system.)

File Management & Admin Panel

  1. The admin.html page provides:
  2. File browser to upload, rename, delete, and create folders directly on the SD card via web UI.
  3. Controls to restart the device or toggle USB Mass Storage Mode.
  4. RGB LED control and brightness adjustment.
  5. Wi-Fi credentials and admin password changes.
  6. Manual generation of media.json for large libraries.
  7. SD card storage usage statistics with progress bar.
  8. Tons more, check the github docs.


What You Can Customize

You can edit any of the HTML or image files from the admin panel. Feel free to:

  1. Change colors and layout in menu.html and section pages
  2. Replace the logo, favicon, or placeholder image
  3. Remove content categories (like Books or Music) by deleting the links in menu.html

Just remember: the system is expecting specific file and folder names, so don’t rename core files unless you know how to update the code to match.

Flashing the Firmware

Screenshot 2025-07-07 200059.png
Screenshot 2025-08-12 182316.png
Screenshot 2025-07-07 120144.png
Screenshot 2025-07-07 120322.png

Now that your SD card is ready, it’s time to upload the firmware to the ESP32-S3 board.

The Waveshare board used in this project makes things easy, it has a USB Type-A male connector, just like a flash drive. You can plug it directly into any available USB port on your laptop or PC, no adapters or extra cables required.

Installing Arduino IDE

If you haven’t already, download and install the Arduino IDE from:

https://www.arduino.cc/en/software

Once installed, open it up, you’ll use this to flash the Nomad firmware to the board.

Opening the Project

  1. Download the firmware files from the GitHub page.
  2. Open the .ino file in Arduino IDE.
  3. Ensure you download all of the files in the "firmware/JcorpNomadProject" directory, when you run the ino those files need to be preset for it to function.
  4. The project should load all necessary tabs and files automatically. (if they don't load check its in the right spot as above)

Board Setup in Arduino IDE

You’ll need to tell Arduino IDE how to talk to the ESP32 board. Follow these steps:

  1. Go to File > Preferences
  2. Under "Additional Board Manager URLs", paste this:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  1. Then go to Tools > Board > Board Manager
  2. Search for and install “esp32 by Espressif Systems”

Now configure the board:

  1. Board: ESP32S3 Dev Module
  2. USB Mode: USB-OTG (tinyUSB)
  3. CDC on Boot > Enabled
  4. Port: Select the correct COM port once the device is plugged in
  5. Partition Scheme: 16MB Flash (3MB APP/9.9MB FATFS)
  6. PSRAM: OPI PSRAM
  7. Upload Speed: 921600

⚠️ These settings are based on the Waveshare 1.47" display model, other boards may need adjustments. Also check the picture of the settings above.


Flashing the Code

Once everything is set:

  1. Click the Upload (right arrow) button in Arduino IDE.
  2. Wait for the compile and upload process to finish.
  3. If successful, you’ll see a “Done uploading” message.
  4. Check the serial output to see if everything launched correctly. There will be debugging logs for your convenience.

If you get errors, make sure the correct COM port is selected and the board is seated properly. Try pressing the boot/reset button on the ESP32 if needed during upload. For missing library errors

A guide for this ESP32 board can be found at This Link, it may help troubleshooting.


Editing the screen UI

  1. You can change what displays on the screen, currently it displays a SD usage bar, the current SSID, # of connected users, and WIFI/SD card status.
  2. Editing the screen will involve downloading Squareline studios and using the free version to edit the files in the github.


Library issues:

  1. If you encounter an error while flashing along the lines of: fatal error: <libraryname>.h: No such file or directory
  2. It usually means your libraries are the wrong version. I recommend cleaning out everything in your library folder (usually C:\Users\<yourusername>\Documents\Arduino\libraries on windows) and replacing it with the libraries here (extract the file into libraries)
  3. Then try to re-flash, it should work.
  4. This software is extremely reliant on very specific library versions, so its usually easier to just use the exact versions above than to try and find the correct ones online.

Case

3dgifmaker76112.gif
Screenshot 2025-08-11 063229.png
Screenshot 2025-08-12 182756.png

Once your ESP32-S3 board has been flashed and tested, you can enclose it in the 3D-printed case. I strongly recommend waiting until after you’ve verified the device is fully working before snapping the case together, It should come apart, but the more often you do it the weaker the tabs will get.

Heads-Up Before You Start:

  1. The front screen is very fragile I broke several during development, the case is intended to protect it so be very gentle when installing it, I recommend starting from the USB side and pressing down gently while sliding it backwards with the far side from the USB going on last. The new design is more forgiving, but still be careful adding and removing it.
  2. Test everything before assembling. Seriously. Connect to the Wi-Fi, open the menu, stream a file, only then move on to the case.


🔥 About Heat

This device runs hot. Like, really hot. The ESP32-S3 chip and SD card area can get toasty under load, especially when multiple people are streaming content.

Here’s how to keep it cool:

  1. Add a tiny thermal pad or dab of thermal paste between the ESP32-S3 chip and the case shell
  2. Keep an eye on SD card health, high temps can shorten their lifespan, using a quality card will help greatly.

So far I haven’t burned out a board, but I wouldn’t rule it out either. Just plan for heat, and you’ll be fine.

Common Issues & Fixes

Screenshot 2025-07-07 125304.png
Screenshot 2025-07-07 120144.png
Screenshot 2025-07-07 200931.png

Even though Nomad is pretty straightforward, there are a few quirks and bugs I’ve encountered that you might run into too. Here's a breakdown of the most common issues and how to troubleshoot them:

1. SD Card Failure or Read Errors

Symptoms:

  1. Captive portal loads, but crashes after connecting
  2. Device hangs or reboots randomly
  3. Media won’t load or throws read errors
  4. Serial output shows sdmmc_read_blocks failed (0x107) or similar
  5. If you are using the Experimental Branch the SD indicator on the LCD will be off (Grey)

What’s Going On:

  1. The most common cause is the card not being formatted to FAT32. Windows won’t format cards larger than 32GB to FAT32 by default, so I recommend using fat32format.com.
  2. If it was working but suddenly stopped, the card may have overheated or degraded, this is really common with cheap SD cards. It may still work fine on your PC, but the ESP32 is way more sensitive.

Fixes:

  1. Format to FAT32 using the above tool
  2. Check the serial monitor in Arduino IDE, I’ve added debug messages to help pinpoint SD issues
  3. Try a brand-name SD card (SanDisk or Samsung are good bets)
  4. Add a dab of thermal paste or a thermal pad to the chip under the SD card, this helps a lot
  5. If it fails in a loop, you’ll need to unplug/replug the device to reset it, This presents as a working device, but when you try to play or access any media the server crashes and boots you off the wifi.

2. Wi-Fi Not Showing / Redirect Not Working

Symptoms:

  1. You see the Wi-Fi network, but nothing happens when you connect.
  2. It connects, but the page doesn’t load or you’re stuck at a blank screen.
  3. You connect but it just says "cant provide wifi" or "no wifi available".
  4. If you are using the Experimental Branch the WIFI indicator will be off (grey) > if its on WIFI is starting and its likely an issue with the device you are trying to connect.

What’s Going On:

  1. The ESP32 uses a captive portal trick to load the main menu, this works on most phones and laptops, but some devices (especially Android variants) need specific handling
  2. I’ve included separate HTML files (index.html and appleindex.html) for different platforms, the device auto-detects and serves the correct one, Android should be the only one you need to mess with.
  3. That said, some phones (Pixel, OnePlus, etc.) have weird network behavior and may need custom tweaks

Fixes:

  1. Check the serial output, if it says WiFi Online, the network is up and running, but the device handling is messed up.
  2. Make sure appleindex.html and index.html are both present on the SD card
  3. If you're using a "weird" phone model and it's not redirecting, you may need to tweak the code, I’ve added comments in the firmware to help you do that. Check online for what captive DNS endpoint your phone expects and add it to the code following the same format.

3. Range Request Failure (Video Seek Not Working)

Symptoms:

  1. Videos play, but you can’t skip ahead or fast forward
  2. Sometimes causes the player to hang or reload

What’s Going On:

  1. This is due to range request handling, and it is by far the most annoying thing I’ve dealt with
  2. Video players expect the server to respond with very specific byte ranges when skipping ahead, and the ESP32 isn’t great at handling this

Fixes:

  1. If it happens, check the serial monitor, I’ve added tons of logs around range requests for this exact reason
  2. If you get a broken link image (it wont let you pause or play the video, then something else is broken and the range issue is just a symptom)
  3. This is still a work in progress, improvements are welcome!

4. Screen Glitches or UI Breakage

Symptoms:

  1. The screen doesn’t turn on
  2. Graphics are distorted, menus don’t load properly
  3. Display looks fine at first but goes wonky after a few seconds

What’s Going On:

  1. Could be a damaged screen, I’ve broken two Waveshare boards myself, and trust me, it’s easy to do when disassembling
  2. Could also be due to corrupted GUI files from SquareLine Studio
  3. As a note the default screen with my branding shows an sd card and wifi slider, early on I had those as a visual indicator of the status of those systems, I didn't re add it, but those being off isn't an issue, its just lazy coding on my part.

Fixes:

  1. If the screen stays black, confirm your firmware flashed correctly and double-check your display connection, check if the LED is on (if off its not getting power or its a larger firmware problem)
  2. If it’s a graphical issue, try replacing your SquareLine Studio .bin files from a fresh export
  3. If your screen is cracked, sorry… there’s really no saving it. Be gentle when assembling the front cover!

Media Prep & Best Practices

Screenshot 2025-07-07 201103.png

Let’s be real, how you get your media is up to you. Personally, I rip my own DVDs and Blu-rays, which gives me full control over the format and quality. But however you source your movies, shows, music, and ebooks, there are some important formatting rules and optimization tips you’ll want to follow to make everything work smoothly on Nomad.

Supported Formats (Very Important)

The ESP32-S3 isn’t exactly a media powerhouse, so we have to keep things lightweight and consistent.

  1. Movies & Shows: .mp4, .mov, .mkv, .webm
  2. Keep resolution and bitrate modest (more on this below)
  3. Music: .mp3, .flac, .wav
  4. Books: .pdf, .epub
  5. Images: .jpg
  6. Each Movie, Show folder, and Book should have a matching .jpg file for the poster/cover image


Tip: There’s an included script called img.py that you can run to compress all .jpg files in a folder. It helps save space and keeps load times fast. (smaller images load quicker in the web UI)

Optimize Videos with HandBrake

HandBrake is an awesome free tool for converting and compressing videos. I use it to prep almost all of my media for Nomad.

Why compress?

  1. Lower file size = faster load & more streams at once!
  2. Avoids crashes during playback
  3. Saves SD card space = more media space

🔧 Recommended HandBrake Settings

  1. Open HandBrake and drag your video file in, or select a file with multiple and que them.
  2. Under Format, choose: MP4
  3. Under Video tab:
  4. Preset: Fast 480p (check web optimized on)
  5. Video Codec: H.264 (x264)
  6. Framerate (FPS): Same as source, Constant Framerate
  7. Quality: Use the RF slider, set it to around 22–24 for a good size/quality balance
  8. Under Audio tab:
  9. Keep a single stereo track, AAC codec
  10. Under Subtitles:
  11. Burn In any you need.
  12. If you don't burn them in (say for anime) they will not show up. so be sure to do this if you need it.
  13. File naming:
  14. For episodes, I recommend naming like:
  15. S01E01 - The Pilot.mp4
  16. Keeping things alphabetized will prevent playback order issues, media.py sorts alphabetically so plan for that.

Once you're happy with your settings, click "Start Encode" and you’re good to go. For more detailed steps check online, handbrake is widely used and well documented. If you are in a rush or have tons of files (or just willing to use more space just doing the fast 480p preset and web optimizing is usually fine for most uses.


Clean Folder Structure

Nomad depends on a specific folder and file layout to function properly. Here’s what it should look like:

/Movies/
Interstellar.mp4
Interstellar.jpg
/Shows/
The Office/
S01E01 - Pilot.mp4
S01E02 - Diversity Day.mp4
The Office.jpg //NOT in "/The Office", it's in "/Shows" with the office folder not inside the office folder.
/Books/
The Martian.pdf
The Martian.jpg
/Music/
track01.mp3
albumcover.jpg //This wont show up so you realy dont need to include it, just for potential future explansion.

Naming Tips

  1. Keep file names simple and clean (avoid emojis, long symbols, or extra punctuation)
  2. For shows, using SxxExx - Title helps avoid weird sorting issues
  3. Covers must match the name of the main media file/folder (e.g., Interstellar.mp4 + Interstellar.jpg)

Conclusion & What’s Next

Thanks for Checking Out the Jcorp Nomad Project!

What started as a quick side project has turned into months of tinkering, debugging, and learning new skills I never expected to pick up. I didn’t originally plan to publish this, so it’s been amazing to see how much interest it’s gotten.

Nomad works well today, but there’s still plenty I want to add, and plenty of room for others to take it further. Some ideas in the pipeline:

  1. Offline Maps – Inspired by the Backcountry Beacon project, store map tiles on the SD card so you can see your position without cell service. I’ve tested a few approaches, but it’s not quite nailed down yet.
  2. HTML5 Games – Lightweight, browser-based games (similar to Gams Offline). Most will work best with a keyboard, but they’re small in size and a fun optional extra. > Idealy I would like to get something like emulatorJS working for ROM emulation.
  3. Audiobook-Friendly Mode – An option in the books section for playing audiobooks alongside other items.
  4. Custom Content Players – Better video support (subtitles, multiple audio tracks), proper EPUB reading, and CBZ/CBX comic navigation. Webtoon style infinite scroll, general improvements over the default browser players.
  5. Playback tracking – cache where the user left off and remember the last few played items / where they left off, would offer resume functionality.
  6. UI Upgrades – Consistent custom icons and emojis for a cleaner, more unified look.

If you decide to build your own version of Nomad, I’d love to see it. Share photos, fork the repo, or drop a comment if you get stuck or come up with a cool feature idea. This project is open source so others can help it grow in ways I can’t on my own.

Happy hacking ✌️

— Jackson Studner