A self-hosted media server that lets you stream your personal movie and TV show collection through the StreamflixAA Android app — on your phone, tablet, or Android Auto.
Join the betatest here: streamflixaa.online
- Stream local video files (MP4, MKV, AVI, M4V, WebM, MOV) to the StreamflixAA app
- Automatic detection of movies, TV shows, episodes, and seasons
- Subtitle support (SRT, VTT, ASS, SSA, SUB)
- Cover image detection (poster, cover, folder art)
- Web-based admin UI for configuration and library management
- Folder browser for easy setup
- Auto-scan on a timer
- Works over LAN, Wi-Fi, or Tailscale/VPN
- Python 3.10+
- Flask 3.0+
- StreamflixAA app installed on your Android device
Download and install Python 3.10 or newer from python.org.
Make sure to check "Add Python to PATH" during installation.
Open a terminal in the streamflix-server folder and run:
pip install -r requirements.txtpython server.pyThe server will start on port 8642 by default.
Open http://localhost:8642 in your browser to access the admin UI.
docker build -t streamflix-server .
docker run -d \
--name streamflix-server \
-p 8642:8642 \
-v /path/to/your/movies:/media/movies \
-v /path/to/your/tvshows:/media/tvshows \
-v ./config.json:/app/config.json \
-e STREAMFLIX_MOVIES_DIR=/media/movies \
-e STREAMFLIX_TVSHOWS_DIR=/media/tvshows \
streamflix-serverImportant: Create
config.jsonon the host before starting the container.
If the file does not exist, Docker will create a directory instead and the server will fail to write config.
You can copyconfig.default.jsonas your starting point:cp config.default.json config.json
Create a docker-compose.yml:
services:
streamflix-server:
build: .
container_name: streamflix-server
ports:
- "8642:8642"
volumes:
- ./config.json:/app/config.json
- /path/to/your/movies:/media/movies
- /path/to/your/tvshows:/media/tvshows
environment:
- STREAMFLIX_MOVIES_DIR=/media/movies
- STREAMFLIX_TVSHOWS_DIR=/media/tvshows
restart: unless-stoppedThen run:
cp config.default.json config.json # only needed on first run
docker compose up -d| Variable | Description | Example |
|---|---|---|
STREAMFLIX_MOVIES_DIR |
Movie folder(s) inside the container (comma-separated) | /media/movies |
STREAMFLIX_TVSHOWS_DIR |
TV show folder(s) inside the container (comma-separated) | /media/tvshows |
STREAMFLIX_PORT |
Override the server port | 8642 |
STREAMFLIX_SERVER_NAME |
Override the server display name | My Media Server |
Environment variables take precedence over config.json values.
All settings can be changed from the web UI at http://localhost:8642 under the Settings tab.
| Setting | Description | Default |
|---|---|---|
| Server Name | Display name shown in the app | My Media Server |
| Port | HTTP port the server listens on | 8642 |
| Language | 2-letter language code (en, de, es, fr, it, etc.) | en |
| Auto-Scan Interval | Minutes between automatic library rescans (0 = disabled) | 0 |
| Movie Folders | Folders containing your movie files | (empty) |
| TV Show Folders | Folders containing your TV show directories | (empty) |
| Video Extensions | File extensions treated as video | .mp4, .mkv, .avi, .m4v, .webm, .mov |
| Subtitle Extensions | File extensions treated as subtitles | .srt, .vtt, .ass, .ssa, .sub |
Configuration is saved to config.json next to server.py.
A config.default.json template is included in the repository — copy it to config.json on first run if one doesn't exist yet.
When running in Docker, environment variables (STREAMFLIX_MOVIES_DIR, etc.) override the corresponding config.json values.
Each movie should be a video file inside one of your configured movie folders.
Movies can be in the root of the folder or inside individual subfolders.
Recommended structure (subfolder per movie):
Movies/
├── The Dark Knight (2008) [1080p]/
│ ├── The.Dark.Knight.2008.1080p.BluRay.x265.mkv
│ ├── The.Dark.Knight.2008.1080p.BluRay.x265.srt
│ ├── The.Dark.Knight.2008.1080p.BluRay.x265.en.srt
│ └── poster.jpg
├── Inception (2010) [4K]/
│ ├── Inception.2010.2160p.WEB-DL.x265.mp4
│ ├── Inception.2010.2160p.WEB-DL.x265.srt
│ └── poster.jpg
└── Interstellar (2014)/
└── Interstellar.2014.1080p.BluRay.mkv
Also works (flat structure):
Movies/
├── The.Dark.Knight.2008.1080p.BluRay.mkv
├── Inception.2010.2160p.WEB-DL.mp4
└── Interstellar.2014.1080p.BluRay.mkv
TV shows must be organized with one subfolder per show inside your configured TV show folders.
Episodes should be in season subfolders (recommended) or directly in the show folder.
Recommended structure:
TVShows/
├── Breaking Bad/
│ ├── poster.jpg
│ ├── Season 01/
│ │ ├── Breaking.Bad.S01E01.1080p.BluRay.mkv
│ │ ├── Breaking.Bad.S01E01.srt
│ │ ├── Breaking.Bad.S01E02.1080p.BluRay.mkv
│ │ └── Breaking.Bad.S01E02.srt
│ └── Season 02/
│ ├── Breaking.Bad.S02E01.1080p.BluRay.mkv
│ └── Breaking.Bad.S02E02.1080p.BluRay.mkv
├── The Office/
│ ├── Season 1/
│ │ ├── The.Office.S01E01.720p.mkv
│ │ └── The.Office.S01E02.720p.mkv
│ └── Season 2/
│ ├── The.Office.S02E01.720p.mkv
│ └── The.Office.S02E02.720p.mkv
The scanner recognizes these episode naming patterns:
| Pattern | Example |
|---|---|
S01E01 |
Breaking.Bad.S01E01.1080p.mkv |
s1e1 |
show.s1e1.mkv |
1x01 |
show.1x01.mkv |
Episode 01 |
Show Episode 01.mkv |
Season folders are detected by names like Season 01, Season 1, S01, S1.
If no season/episode info is found in the filename, the server assigns Season 1 and auto-numbers episodes.
The server automatically detects cover images. Place them alongside your video files:
For movies (checked in this order):
<video-filename>.jpg/.png/.webp(e.g.,Inception.2010.jpg)poster.jpg/poster.png/poster.webpcover.jpg/folder.jpg/thumb.jpg- Any image file in the same folder
For TV shows:
poster.jpgin the show's root foldercover.jpg/folder.jpg/thumb.jpg- Any image file in the show folder
Subtitles are auto-detected when placed next to the video file:
| File | Detected As |
|---|---|
movie.srt |
SRT |
movie.en.srt |
EN |
movie.de.srt |
DE |
movie.vtt |
VTT |
To set a custom provider icon in the app, place a file named logo.jpg, logo.png, or logo.webp in the same folder as server.py.
The server must be reachable from your phone. You can use:
- LAN IP (e.g.,
192.168.1.100) — phone must be on the same Wi-Fi network - Tailscale IP (e.g.,
100.x.x.x) — works from anywhere with Tailscale installed on both devices
Note:
localhost/127.0.0.1will NOT work — that refers to the phone itself, not your PC.
In the StreamflixAA app, go to Settings → Import Providers and paste:
[{"id": "localserver", "baseUrl": "http://YOUR_IP:8642", "language": "en"}]Replace YOUR_IP with your actual server IP address and en with your preferred language code.
Make sure port 8642 is allowed through your firewall.
Windows (run as Administrator):
netsh advfirewall firewall add rule name="StreamflixAA Server" dir=in action=allow protocol=TCP localport=8642Linux:
sudo ufw allow 8642/tcpAccess the admin panel at http://localhost:8642 with three tabs:
- Configure server name, port, language
- Add/remove movie and TV show folders using the folder browser
- Set video and subtitle file extensions
- Save settings and trigger a library scan
- View all detected movies and TV shows
- See title, quality, and ID for each item
- Copy-paste the import JSON for the StreamflixAA app
- Shows the current server address and language
| Endpoint | Method | Description |
|---|---|---|
/api/home |
GET | Home screen categories (featured + movies + TV shows) |
/api/movies?page=1 |
GET | Paginated movie list |
/api/tvshows?page=1 |
GET | Paginated TV show list |
/api/movie/<id> |
GET | Movie details |
/api/tvshow/<id> |
GET | TV show details with seasons |
/api/season/<id>/episodes |
GET | Episodes for a season |
/api/search?query=text |
GET | Search movies and TV shows |
/api/servers/<id> |
GET | Streaming servers for an item |
/api/video/<id> |
GET | Video URL for playback |
/api/stream/<id> |
GET | Stream video file (supports byte-range) |
/api/poster/<id> |
GET | Poster image for an item |
/api/subtitle/<id> |
GET | Subtitle file |
/api/scan |
POST | Trigger library scan |
/api/config |
GET/POST | Read/update server configuration |
/api/info |
GET | Server info (name, version, counts) |
/api/browse?path=... |
GET | Browse directories (for folder picker) |
/api/provider-json |
GET | Provider import JSON for the app |
- Verify the server is running (
http://localhost:8642should load in a browser) - Check you're using the correct IP (not
localhost) - Ensure the phone and PC are on the same network (or connected via Tailscale)
- Check the Windows Firewall allows port 8642
- Verify the folders are added in Settings and saved before scanning
- Check that your video files have supported extensions (
.mp4,.mkv, etc.) - Make sure the folder paths are correct and accessible
- The server must be reachable from the phone on the same IP used in the import JSON
- Try opening
http://YOUR_IP:8642/api/poster/serverin your phone's browser
- Ensure the video format is supported by Android (MP4/H.264 is most compatible)
- MKV with H.265/HEVC may not play on all devices — re-encode to MP4/H.264 if needed
Using Docker with restart: unless-stopped (as shown in the Docker Compose example above) is the simplest way to keep the server running in the background and auto-start on boot.
Create a batch file start-server.bat:
@echo off
cd /d "%~dp0"
python server.pyTo run at startup, create a shortcut to this batch file in:
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
Create a systemd service file /etc/systemd/system/streamflixaa.service:
[Unit]
Description=StreamflixAA Media Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/path/to/streamflix-server
ExecStart=/usr/bin/python3 server.py
Restart=always
[Install]
WantedBy=multi-user.targetThen enable and start:
sudo systemctl enable streamflixaa
sudo systemctl start streamflixaaThis project is provided as-is for personal use.