Automatically overlay a "New Season" banner on Plex show posters when a new season is added within the last 21 days. Features intelligent cleanup that automatically removes overlays when seasons are no longer "new" and smart processing that converts preview overlays to live overlays.
- Smart Detection: Scans your Plex library for shows with 2+ seasons where the latest season aired within the last 21 days
- Automatic Overlay: Adds a custom "New Season" banner to both show and season posters
- Preview Mode: Generates preview images before making changes (toggle with
PREVIEW_MODE) - Intelligent Cleanup: Automatically removes overlays when seasons are no longer "new" (21+ days old)
- Preview-to-Live Conversion: Seamlessly converts preview overlays to live overlays when switching modes
- Comprehensive Logging: Tracks all changes in
overlaid_log.jsonwith timestamps and mode tracking - Skip Processing: Automatically skips already-processed shows to avoid duplicates
- Robust Error Handling: Enhanced error handling with detailed logging and graceful fallbacks
- Safe Filename Handling: Sanitizes filenames to prevent filesystem issues
- Python 3.7+
- Plex Media Server (PlexPass not required)
- Network Access to your Plex server
- Write Permissions in the script directory
pip install -r requirements.txtRequired Python packages:
plexapi- Plex API interfacePillow- Image processingrequests- HTTP requests
- Open Plex Web App
- Play any media item
- Open browser developer tools (F12)
- Go to Network tab and look for requests containing
X-Plex-Token - Copy the token value
Open overlay_season_preview.py and update these settings:
# === CONFIGURATION ===
PLEX_URL = 'http://192.168.1.100:32400' # Your Plex server URL
PLEX_TOKEN = 'YOUR_PLEX_TOKEN_HERE' # Your Plex token
OVERLAY_PATH = 'new_season.png' # Path to your overlay image
LOG_FILE = 'overlaid_log.json' # Log file location
PREVIEW_MODE = False # Toggle preview/live mode
PREVIEW_FOLDER = 'preview_posters' # Preview images folderPlace your custom overlay image in the root folder and name it new_season.png
Overlay Requirements:
- Format: PNG with transparency support
- Size: Any size (will be automatically resized to 85% of poster width)
- Position: Will be placed at the bottom-center of posters
# Set PREVIEW_MODE = True in the script
python overlay_season_preview.pyWhat happens:
- Scans your library for eligible shows
- Creates preview images in
preview_posters/folder - Logs potential changes without modifying Plex
- Shows you exactly what will be changed
# Set PREVIEW_MODE = False in the script
python overlay_season_preview.pyWhat happens:
- Applies overlays to show and season posters in Plex
- Converts existing preview overlays to live overlays
- Saves backup preview images in preview folder
- Updates
overlaid_log.jsonwith changes - Skips already-processed shows
The script now automatically handles cleanup by:
- Checking all previously overlaid shows
- Removing overlays from seasons older than 21 days
- Restoring original posters automatically
- Updating log file to reflect changes
- Eligibility Check: Only processes shows with 2+ seasons where latest season aired within 21 days
- Duplicate Prevention: Skips shows that already have overlays applied
- Preview-to-Live Conversion: Automatically converts preview overlays to live when switching modes
- Inaccessible Show Cleanup: Removes log entries for shows that can no longer be accessed
- Graceful Fallbacks: Multiple methods for poster reset if primary method fails
- Detailed Logging: Comprehensive error reporting with stack traces
- Safe File Operations: Proper temp file cleanup and error recovery
- Filename Sanitization: Removes invalid characters from filenames
- Temporary File Cleanup: Automatically removes temp files after processing
- Log File Validation: Handles corrupted log files gracefully
plex-new-season-overlay/
├── overlay_season_preview.py # Main script
├── new_season.png # Your overlay image
├── requirements.txt # Python dependencies
├── overlaid_log.json # Processing log (auto-generated)
├── preview_posters/ # Preview & temp images (auto-generated)
│ ├── Show_Name_show.png
│ ├── Show_Name_season.png
│ └── temp_files...
└── README.md # This file
The overlaid_log.json tracks each processed show:
{
"12345": {
"title": "Example Show",
"timestamp": "2025-01-15T14:30:00",
"preview_only": false
}
}Fields:
title: Show nametimestamp: When overlay was appliedpreview_only: Whether it's a preview or live overlay
The script handles maintenance automatically:
- Removes overlays from shows that no longer qualify
- Cleans up inaccessible show entries from the log
- Converts preview overlays to live overlays when mode changes
"No module named 'plexapi'"
pip install plexapi Pillow requests"Connection refused" or "Unauthorized"
- Verify your
PLEX_URLis correct - Check that your
PLEX_TOKENis valid - Ensure Plex server is running and accessible
"Overlay file not found"
- Verify
new_season.pngexists in the script directory - Check file permissions
Poster reset issues
- The script uses multiple fallback methods for poster reset
- If posters don't reset, try restarting your Plex server
- Check Plex logs for additional error information
Add this to the script for detailed logging:
import logging
logging.basicConfig(level=logging.DEBUG)# Change the "new season" timeframe (default: 21 days)
cutoff = now - timedelta(days=30) # 30 days instead of 21
# Modify overlay size and position
new_width = int(width * 0.75) # 75% instead of 85%
y = height - new_height - 50 # Add 50px margin from bottom# Use different overlays based on show type or season number
if 'Comedy' in show.genres:
overlay_path = 'comedy_new_season.png'
elif latest_season.index > 5:
overlay_path = 'veteran_show_overlay.png'
else:
overlay_path = 'new_season.png'- Speed: Processes ~100 shows in 30-60 seconds
- Resources: Uses minimal CPU/memory
- Network: Downloads poster images (can be bandwidth-intensive)
- Efficiency: Skips already-processed shows to minimize redundant work
- Requires direct network access to Plex server
- Only works with shows that have air dates
- Overlay position is fixed (bottom-center)
- Depends on Plex API availability
Contributions are welcome! Here's how to help:
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Commit your changes:
git commit -am 'Add feature' - Push to the branch:
git push origin feature-name - Submit a pull request
- Web interface for configuration
- Multiple overlay templates
- Real-time monitoring with file watchers
- Docker containerization
- Integration with other media management tools
- Custom overlay positioning options
MIT License - free for personal and commercial use.
See LICENSE file for details.
If this script saves you time and enhances your Plex experience, consider supporting future development:
- Buy Me a Coffee - Clean, PayPal-free option
- Ko-fi - Another trusted platform
Butta Jones
- GitHub: @buttajones
- Twitter/X: @buttajones
- Email: Available via GitHub profile
- ✅ Enhanced error handling and recovery
- ✅ Improved poster reset functionality with multiple fallback methods
- ✅ Added filename sanitization for cross-platform compatibility
- ✅ Automatic preview-to-live conversion
- ✅ Better inaccessible show cleanup
- ✅ Improved temporary file management
- ✅ Enhanced logging with detailed error reporting
- ✅ Added automatic cleanup functionality
- ✅ Improved poster reset mechanism
- ✅ Enhanced error handling and logging
- ✅ Better filename sanitization
- ✅ Preview mode improvements
- ✅ Initial release
- ✅ Basic overlay functionality
- ✅ Preview mode
- ✅ JSON logging
- PlexAPI developers for the excellent Python library
- Plex community for feedback and testing
- Contributors who helped improve this script
Made with ❤️ for the Plex community

