SDL2/GStreamer DLNA browser for R36S by Matteo Benedetto
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Matteo Benedetto 6fc467127c Add publication metadata 8 hours ago
.github Initial import 8 hours ago
docs Initial import 8 hours ago
src/r36s_dlna_browser Initial import 8 hours ago
tests Initial import 8 hours ago
.gitignore Initial import 8 hours ago
LICENSE Initial import 8 hours ago
README.md Add publication metadata 8 hours ago
environment.yml Initial import 8 hours ago
pyproject.toml Add publication metadata 8 hours ago
requirements.txt Initial import 8 hours ago

README.md

R36S DLNA Browser

A lightweight DLNA media browser for the R36S handheld, built with Python, SDL2, and GStreamer.

Author: Matteo Benedetto

Features

  • Discover DLNA/UPnP media servers on local LAN via SSDP
  • Browse media libraries hierarchically with D-pad navigation
  • Play audio and video locally via integrated GStreamer playback inside the SDL window
  • Optimised for 640×480 screen and low-power RK3326 hardware

System Prerequisites

Install these system packages before running (Ubuntu/Debian-based):

sudo apt install libsdl2-2.0-0 libsdl2-ttf-2.0-0 python3 python3-pip python3-gi gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good

On Fedora the equivalent runtime packages are:

sudo dnf install SDL2_ttf python3-gobject gstreamer1 gstreamer1-plugins-base gstreamer1-plugins-good python3 python3-pip

The current playback path is SDL-only: GStreamer decodes into frames and the app renders them inside the SDL renderer. This avoids any dependency on X11, Wayland embedding, or a window manager and is aligned with DRM/KMS-only targets.

On ArkOS-derived firmware the SDL2 libraries are typically pre-installed.

A TrueType font is bundled inside the package at src/r36s_dlna_browser/assets/ so packaged builds do not depend on a system font path. System font fallbacks are still kept for development machines.

Quick Start

cd /path/to/R36SHack
python3 -m pip install -e ".[dev]"
python3 -m r36s_dlna_browser

Miniforge / Conda Deploy

Use Miniforge or Miniconda when you want a reproducible Linux development or packaging environment with GStreamer and SDL dependencies managed together.

cd /path/to/R36SHack
conda env create -f environment.yml
conda activate r36s-dlna-browser
python -m r36s_dlna_browser

To update an existing environment after dependency changes:

conda env update -f environment.yml --prune
conda activate r36s-dlna-browser

Or without installing:

cd /path/to/R36SHack
pip install -r requirements.txt
PYTHONPATH=src python3 -m r36s_dlna_browser

Controls

Key / Button Action
Up / Down Navigate items
Left / Right Page up / down
A (Return) Select / Enter
B (Escape) Back
Start Quit

During playback, the same controls are remapped to transport actions:

  • A: pause / resume
  • B: stop and return to browser
  • Left / Right: seek -10s / +10s
  • Up / Down: volume +5 / -5
  • H / Y: cycle HUD mode (auto / fixed / hidden)

On-Device (R36S / ArkOS)

  1. Copy the project to /roms/ports/ or another writable location.
  2. Ensure Wi-Fi is connected.
  3. Run via PortMaster or a launch script:
cd /roms/ports/R36SHack
PYTHONPATH=src python3 -m r36s_dlna_browser

Git / Release Workflow

For publication on a Gitea instance with tea, initialize git locally, create a remote repository, then push the current branch.

git init
git add .
git commit -m "Initial import"
tea repos create --name R36SHack --description "SDL2/GStreamer DLNA browser for R36S" --owner enne2
git remote add origin ssh://git@git.enne2.net:222/enne2/R36SHack.git
git push -u origin main

Published repository: https://git.enne2.net/enne2/R36SHack

Project Structure

src/r36s_dlna_browser/
├── __main__.py          # Entrypoint
├── app.py               # Application lifecycle
├── assets/
│   └── NotoSans-Regular.ttf
├── dlna/
│   ├── discovery.py     # SSDP media-server discovery
│   ├── client.py        # ContentDirectory browsing via DmsDevice
│   ├── models.py        # Domain models for servers/items
│   └── browser_state.py # Navigation stack and cache
├── ui/
│   ├── sdl_app.py       # SDL2 window, event loop, rendering
│   ├── screens.py       # Screen definitions
│   └── theme.py         # Layout constants for 640×480
├── player/
│   ├── backend.py       # Player interface
│   └── gstreamer_backend.py # integrated GStreamer playback backend
└── platform/
    ├── controls.py      # Input mapping
    └── runtime.py       # Runtime detection and logging

License

MIT