A script to assist in renaming video files to prep them for Plex (or other self-hosted streaming services).
Please note: This is currently _entirely_ vibe coded. It's a tool I needed and it worked. I'm sorry.
- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .gitignore | ||
| README.md | ||
| rename_for_plex.py | ||
rename-for-plex
A script to assist in renaming video files to prep them for Plex (or other self-hosted streaming services).
Please note: This is currently entirely vibe coded. It's a tool I needed and it worked. I'm sorry.
✨ Features
- 🔍 Recursive scanning – Finds video files across nested directories
- 📺 Auto series detection – Pulls series names from parent folders, ignoring season subfolders (
Season_01,S02, etc.) - 🏷️ Metadata-first parsing – Extracts season, episode, and title from embedded
TITLEtags viaffprobe - 🔄 Smart fallback – If metadata is missing, parses
S01E02/Season 1, Episode 2patterns from filenames - 📦 Lossless MKV conversion – Remuxes non-MKV files without re-encoding video/audio (
-c copy) - 🗣️ Subtitle standardization – Converts embedded
eia_608,mov_text, and other formats to SRT - 🧹 Smart sanitization – Replaces spaces with
_, colons with-, removes unsafe chars, and collapses duplicates - 📐 Resolution snapping – Maps raw pixel heights to standard buckets (±5% tolerance):
1080p,720p,4K, etc. - 🛡️ Safe operations – Won't overwrite existing files, skips unparseable content, and supports full dry-run previews
📋 Prerequisites
- Python 3.8+
ffmpeg&ffprobeinstalled and available in your systemPATH- Read/write permissions for the target library directories
🚀 Usage
Preview changes (recommended first step)
py rename_for_plex.py "/path/to/TV/Library" --dry-run
Live rename only (keeps original container formats)
py rename_for_plex.py "/path/to/TV/Library"
Rename + convert non-MKV files to MKV
py rename_for_plex.py "/path/to/TV/Library" --convert-to-mkv
Custom log file location
py rename_for_plex.py "/path/to/TV/Library" -l "/tmp/my_plex_rename.log"
⚙️ CLI Arguments
| FLAG | SHORT | DESCRIPTION |
|---|---|---|
| root_directory | (positional) | Path to the parent folder containing your TV series |
| --dry-run | -d | Preview all renames/conversions without touching files |
| --convert-to-mkv | -c | |
| --log-file | -l | Path to write the operation log (default: plex_rename.log) |
🧠 How It Works
- Folder Traversal – Recursively walks your library and groups files by the directory they live in.
- Series Naming – If a folder matches a season pattern (Season 1, S02, Season_01, etc.), it bubbles up to the parent folder name.
- Metadata Extraction – Runs ffprobe to pull embedded TITLE tags. Parses Season X, Episode Y: Title format.
- Fallback Parsing – If no metadata exists, scans the filename for S/E or Season/Episode patterns.
- Sanitization – Series: Name → Series-Name, spaces → _, unsafe chars stripped, duplicates collapsed.
- Resolution Snapping – 1078p → 1080p, 704p → 720p, etc. (±5% tolerance to standard buckets).
- Safe Output – Generates Series-Name-s01e02-Episode-Title-[1080p].mkv. Skips if target exists or data is unparseable.
📁 Supported Directory Structure
Works with flat or nested layouts. Season subfolders are automatically recognized and ignored for naming purposes:
/TV Library
/Star_Trek-The_Next_Generation
/Season_01
file1.mp4
/Season_02
file2.mkv
/Breaking Bad
episode_01.avi
episode_02.mov
All files will inherit the correct parent series name regardless of nesting depth.
💡 Tips & Notes
- Always run
--dry-runfirst to verify naming behavior before committing changes. - Keep a backup or test on a copy of your library before live runs.
- Logs are written to both stdout and a
.logfile for easy troubleshooting. - If a file has no parseable metadata or filename patterns, it's skipped with a warning.
- Subtitle conversion is graceful: files without subs are untouched, files with proprietary subs get converted to SRT.