A high-performance, native Plex Media Server client engineered from scratch in modern C++17 for the Nintendo 3DS (optimized for New Nintendo 3DS / New 2DS XL).
Plex3DS offloads heavy media transcoding to your Plex Media Server, delivering lightweight 400ร240 H.264 Baseline video and AAC/MP3 audio streams perfectly tailored for the 3DS display and ARM11 architecture.
-
๐ฑ Instant QR Code & PIN Sign-In:
- Scan the on-screen QR code with your smartphone camera to authenticate instantly at
plex.tv/link. - Fallback 4-digit link code or direct username/password sign-in with on-screen keyboard (SWKBD).
- Plaintext password memory buffers are wiped immediately after authentication.
- Scan the on-screen QR code with your smartphone camera to authenticate instantly at
-
๐ฅ๏ธ Dual-Screen Citro2D Interface:
- Top Screen (400ร240): High-resolution poster artwork, live metadata previews (synopsis, director/artist, release year, duration), and playback status.
- Bottom Screen (320ร240): Touch-driven library navigation, character-by-character horizontal marquee scrolling for long titles, and interactive playback scrubbers.
-
๐ฌ Hardware-Tuned Video Playback:
- Live Plex universal transcoding to 400ร240 H.264 Baseline at 24/30 FPS via bundled ARMv6k FFmpeg.
- Automatic & Manual Aspect Ratio Control: Automatically detects 4:3 (pillarboxed to 320ร240) and 16:9 / widescreen (letterboxed to 400ร225) video streams, or cycle manually (
Auto/4:3/16:9/Full5:3 stretch) anytime during playback via touch orSELECT. - Subtitle stream selection and automatic server-side burn-in.
- Smart Resume / Restart: Asks to resume from your last position or restart from the beginning, automatically persisting progress in
resume.json.
-
๐ต Clamshell Music Playback & Pocket Mode:
- Listen to albums and audio tracks with the 3DS clamshell closed like a dedicated portable MP3 player.
- Bypasses standard console sleep mode (
aptSetSleepAllowed(false)) to maintain audio decoding threads while powering off display backlights to maximize battery life. - Pocket Controls: Use the physical
(L)and(R)shoulder buttons to skip tracks, and press(START)or(L + R)to toggle play/pause directly through your pocket without opening the console.
-
๐ก Intelligent Screen Dimming & Touch Protection:
- Bottom screen backlight automatically turns off during video (10s) and music (15s) playback to conserve battery and eliminate glare.
- Accidental Touch Prevention: The first touch on a dimmed screen simply restores brightness without triggering any UI buttons.
-
๐พ Offline Media Downloads (Zero-Wi-Fi Playback):
- Download TV episodes, movies, and music tracks directly to your SD card (
sdmc:/3ds/plex-3ds/downloads/). - Album & Season Batch Downloads: Dedicated
[DL (Y)]touch buttons and(Y)shortcut let you download an entire music album or TV show season with one tap/press. - "DL All" Container Button: Inside an album or season tracklist, tap
[DL All (Y)]in the header or press(Y)to queue all remaining tracks/episodes. - Sequential Background Queue: Multi-item downloads run automatically in the background without UI lag, showing live progress (
DL (3/12): 45%) and skipping files already downloaded. - 100% Offline Access: Press
(L)or tap[Downloads (L)]on the server selection or sign-in screens to access your downloaded library at any timeโeven with 0% Wi-Fi or no internet connection. - If launched offline with downloaded media on SD, Plex3DS automatically opens your offline library.
- Full path traversal protection, background download progress tracking, and automatic cleanup of partial files.
- Download TV episodes, movies, and music tracks directly to your SD card (
-
๐ Multi-Server & Paginated Libraries:
- Discover and switch between multiple local and remote Plex servers seamlessly.
- Automatic pagination (
--> [Load Next 100 Items...]) for massive libraries without memory spikes.
-
๐ Security & Graceful Home Menu Handling:
- Full
aptHookintegration for clean exits via the HOME Menu or Power button without console hangs or audio buzzing. - Optional custom CA certificate verification via
sdmc:/3ds/plex-3ds/cacert.pem.
- Full
The Nintendo 3DS OS firmware automatically powers down the wireless radio at the hardware level whenever the clamshell lid is shut. As a result, active TCP connections drop and the 3DS cannot fetch new media streams over Wi-Fi while closed.
Plex3DS solves this with two complementary systems:
- Full-Track RAM Buffering (Streaming): When streaming audio online, Plex3DS downloads the entire track into memory within 2โ3 seconds at maximum Wi-Fi throughput. The current song continues playing smoothly through your headphones even after you close the lid.
- Offline Downloads (Recommended for Walkman Mode): By downloading albums, playlists, or videos to your SD card, playback has zero network dependencies. When playing downloaded tracks with the lid closed, Plex3DS seamlessly auto-advances through your entire playlist track by track.
| Input | Action |
|---|---|
| L Shoulder | Previous track |
| R Shoulder | Next track |
| START or L + R | Toggle play / pause |
| Input | Action |
|---|---|
| L Shoulder | Open Offline Downloads (from Server Select, Sign-In, or Library screen) |
| START | Gracefully exit application |
| Input | Action |
|---|---|
| D-Pad Up / Down or Circle Pad | Scroll through servers, libraries, and media items |
| A or Touch Item | Select / Open item details / Connect to server |
| B | Return to previous screen / Return from Downloads |
| X | Remove selected server (on Server Select) or delete downloaded item (in Downloads) |
| Y | Download Album / Season / Movie (in Item List), Download All (inside album/season), or Sync servers (on Server Select) |
| Touch [DL (Y)] | Download highlighted album or TV season directly from the list |
| Touch [DL All (Y)] | Queue all tracks/episodes when viewing an album or season |
| SELECT | Switch to Plex Account / Sign-In screen |
| Input | Action |
|---|---|
| A or Touch Play / Resume | Start playback (or resume from saved timestamp) |
| Y or Touch Restart | Restart playback from beginning (0:00) |
| X or Touch Download / Delete | Download item to SD card, or delete existing download |
| SELECT or Touch CC | Cycle subtitle tracks and closed captions (Video) |
| B or Touch Back | Return to item list |
| Input | Action |
|---|---|
| A or Touch Play/Pause | Toggle playback |
| D-Pad Left / Right | Seek backward / forward 15 seconds |
| Touch Progress Bar | Jump / scrub directly to timestamp |
| L / R Shoulders | Previous / Next episode or audio track |
| X or Touch [CC] | Cycle subtitle / closed caption tracks (Video) |
| SELECT or Touch [AR: Auto] | Cycle video aspect ratio (Auto / 4:3 / 16:9 / Full 5:3 stretch) |
| Y or Touch Hide UI | Collapse / expand bottom-screen playback controls |
| B or Touch Stop | Stop playback and return to browser |
| Touch Screen (When Dimmed) | Wake display (suppresses accidental button click) |
Tired of opening Rosalina Menu (L + Down + Select) and taking over a title every time you use homebrew? Install the Homebrew Launcher as a standalone title on your 3DS HOME Menu:
- Download
Homebrew_Launcher.cia(or grab the bundled copy from this repository). - Copy
Homebrew_Launcher.ciato your 3DS SD card. - Open FBI on your 3DS, navigate to
SD-> locateHomebrew_Launcher.cia, and select Install and delete CIA. - Press
HOMEto unwrap the Homebrew Launcher gift box on your HOME Menu. - Place
Plex3DS.3dsxandPlex3DS.smdhinsdmc:/3ds/Plex3DS/. - Launch Homebrew Launcher directly from your HOME Menu anytime and select Plex3DS!
- Download the latest
Plex3DS.3dsxandPlex3DS.smdhfrom the Releases page. - Insert your 3DS SD card into your computer.
- Place
Plex3DS.3dsxandPlex3DS.smdhinto/3ds/Plex3DS/on your SD card:sdmc:/ โโโ 3ds/ โโโ Plex3DS/ โโโ Plex3DS.3dsx โโโ Plex3DS.smdh - Launch via Homebrew Launcher.
If your 3DS is connected to Wi-Fi:
- In Homebrew Launcher, press
Yto activate NetLoader, then send the binary directly:or run:3dslink -a <3DS_IP> Plex3DS.3dsx
python tools/auto_deploy.py <3DS_IP>
On first launch, Plex3DS will generate a QR code and link PIN. Once paired, your server configuration and credentials are saved to sdmc:/3ds/plex-3ds/config.json.
You can also pre-configure a server manually by copying config.example.json to sdmc:/3ds/plex-3ds/config.json:
{
"clientIdentifier": "plex-3ds-custom",
"token": "YOUR_PLEX_TOKEN",
"serverName": "MyPlexServer",
"serverUrl": "http://192.168.1.100:32400",
"videoResolution": "400x240",
"videoBitrate": 1000,
"audioCodec": "aac"
}If your Plex server uses a private certificate authority (CA) or self-signed certificate, copy your PEM-formatted root bundle to:
sdmc:/3ds/plex-3ds/cacert.pem
Install the devkitPro toolchain with the Nintendo 3DS development group:
# On Arch / Manjaro or using dkp-pacman:
sudo dkp-pacman -S devkitARM libctru citro2d citro3d 3ds-curl 3ds-mpg123 3ds-flac 3ds-liboggPlex3DS includes an automated test suite verifying time formatters, transcode URL builders, path sanitizers, and resume logic:
make testmake -j$(nproc)This will produce Plex3DS.3dsx, Plex3DS.smdh, and Plex3DS.elf.
plex-3ds/
โโโ .github/workflows/ # GitHub Actions CI & automated releases
โโโ external/ # Bundled ARMv6k FFmpeg static libraries & headers
โ โโโ include/ # libavcodec, libavformat, libavutil, libswscale
โ โโโ lib/ # Precompiled static archives for 3DS
โโโ include/ # Header declarations & lightweight dependencies
โ โโโ types.hpp # Server, library, and media data structures
โ โโโ cJSON.h # Fast ANSI C JSON parser
โ โโโ qrcodegen.h # Embedded QR Code generator
โโโ source/ # Implementation
โ โโโ main.cpp # State machine, input handler & event loop
โ โโโ network/ # libcurl HTTP/HTTPS client with TLS support
โ โโโ plex/ # Plex REST API, PIN pairing & XML/JSON models
โ โโโ player/ # NDSP audio stream buffer & FFmpeg video pipeline
โ โโโ download/ # Offline download manager with path sanitization
โ โโโ ui/ # Citro2D / Citro3D dual-screen renderer
โโโ tests/ # Core logic regression test suite
โโโ tools/ # Wireless deployment & network discovery utilities
โโโ Makefile # devkitARM makefile
โโโ config.example.json # Sample configuration template
Contributions, issues, and feature requests are welcome! Feel free to check out the issues page.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Run unit tests (
make test) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
- devkitPro & libctru developers for making 3DS homebrew possible.
- Core-2-Extreme for 3DS video player reference implementations.
- Project Nayuki for the fast, embedded QR code generation library.
- Dave Gamble for the ultra-lightweight cJSON library.