A Node.js/TypeScript server that fetches Electronic Program Guide (EPG) data directly from your HDHomeRun device and converts it to standard XMLTV format for Plex, Jellyfin, Emby, and other media servers.
- Direct HDHomeRun Integration - No Schedules Direct subscription required
- Standard XMLTV Output - Compatible with Plex, Jellyfin, Emby, xTeVe, Threadfin
- Memory-Efficient Streaming - Handles any EPG size with constant memory usage
- Versioned EPG Files - Automatic backups with rollback capability
- Dummy Programming - Fills channels without EPG data with placeholder programs
- Flexible Query Parameters - Customize output on-demand
- Automatic Updates - Configurable cron scheduling
- Health Monitoring - Built-in health checks and status endpoints
- Create
docker-compose.yml:
services:
hdhr-epg:
image: ghcr.io/metacolin/hdhomerun2xmltv:latest
container_name: hdhr-epg-server
restart: unless-stopped
ports:
- "8083:8083"
environment:
HDHOMERUN_HOST: 192.168.1.100 # Change to your HDHomeRun IP
TZ: America/Chicago
CRON_SCHEDULE: "0 3 * * *"
DAYS: 7
ENABLE_DUMMY_PROGRAMMING: true
volumes:
- ./epg-output:/app/output- Start the container:
docker-compose up -d- Access EPG at:
http://localhost:8083/epg.xml
docker run -d \
--name hdhr-epg-server \
-p 8083:8083 \
-e HDHOMERUN_HOST=192.168.1.100 \
-e TZ=America/Chicago \
-v ./epg-output:/app/output \
ghcr.io/metacolin/hdhomerun2xmltv:latest- Open Community Applications
- Search for "HDHomeRun EPG"
- Click Install
- Configure your HDHomeRun IP address
- Set your timezone
- Click Apply
The EPG will be available at: http://[UNRAID-IP]:8083/epg.xml
| Variable | Default | Description |
|---|---|---|
HDHOMERUN_HOST |
Required | IP address of your HDHomeRun device |
TZ |
America/Chicago |
Timezone for scheduling |
WEB_PORT |
8083 |
HTTP server port |
CRON_SCHEDULE |
0 3 * * * |
Update schedule (cron format) |
DAYS |
7 |
Days of EPG data to fetch (1-14) |
HOURS_INCREMENT |
3 |
Hour increment for EPG fetching (1-6) |
RUN_ON_START |
true |
Fetch EPG immediately on start |
ENABLE_DUMMY_PROGRAMMING |
true |
Add placeholder programs for empty channels |
DUMMY_PROGRAM_TITLE |
No Information |
Title for dummy programmes |
DUMMY_PROGRAM_DESC |
No program information... |
Description template |
/epg.xml- Standard XMLTV format/xmltv.xml- Alias for/epg.xml/guide.xml- Alias for/epg.xml
Dummy Programming:
?dummy=30min- 30-minute blocks?dummy=1hr- 1-hour blocks?dummy=2hr- 2-hour blocks?dummy=3hr- 3-hour blocks?dummy=6hr- 6-hour blocks
Days Filter:
?days=1- Limit to 1 day?days=3- Limit to 3 days?days=7- Full week
Combined:
?dummy=1hr&days=3- 1-hour blocks, 3 days only
/status- JSON status information/health- Health check (returns "OK")/- HTML dashboard with examples
- Settings → Live TV & DVR → DVR Settings
- Electronic Program Guide → XMLTV
- Enter:
http://[SERVER-IP]:8083/epg.xml
- Dashboard → Live TV
- EPG Guide Data Provider → XMLTV
- File or URL:
http://[SERVER-IP]:8083/epg.xml
- Settings → Live TV
- Guide → XMLTV
- URL:
http://[SERVER-IP]:8083/epg.xml
30-minute blocks for smaller EPG:
http://[SERVER-IP]:8083/epg.xml?dummy=30min&days=3
2-hour blocks for minimal bandwidth:
http://[SERVER-IP]:8083/epg.xml?dummy=2hr&days=1
- Node.js 20 or higher
- npm or yarn
- Docker (for containerization)
# Clone repository
git clone https://github.com/metaColin/HDHomeRun2XMLTV.git
cd HDHomeRun2XMLTV
# Install dependencies
npm install
# Copy environment template
cp .env.example .env
# Edit .env with your HDHomeRun IP
nano .env
# Build
npm run build
# Start
npm start# Build image
docker build -t hdhomerun2xmltv:latest .
# Test locally
docker run -d \
--name hdhr-epg-test \
-p 8083:8083 \
-e HDHOMERUN_HOST=192.168.1.100 \
-v ./output:/app/output \
hdhomerun2xmltv:latest
# View logs
docker logs -f hdhr-epg-test
# Or use the public image
docker pull ghcr.io/metacolin/hdhomerun2xmltv:latest- Node.js 20 LTS - Runtime
- TypeScript 5 - Type safety
- Express - HTTP server
- node-cron - Scheduling
- axios - HTTP client with retry logic
- fast-xml-parser - XML parsing
- Transform Streams - Memory-efficient processing
- EPG Generation: ~7 seconds for 7 days
- Memory Usage: ~50MB constant (streaming)
- Image Size: 214MB (Alpine-based)
- Streaming Operations: <200ms for filters
Check logs:
docker logs hdhr-epg-serverVerify HDHomeRun IP is accessible:
curl http://[HDHOMERUN-IP]/discover.jsonCheck cron schedule:
docker exec hdhr-epg-server printenv CRON_SCHEDULETrigger manual update:
docker restart hdhr-epg-serverEnable dummy programming:
-e ENABLE_DUMMY_PROGRAMMING=trueOr use query parameter:
http://[SERVER-IP]:8083/epg.xml?dummy=1hr
This project is in active development. Contributions, issues, and feature requests are welcome.
Use AGPL-3.0 with a commercial licensing option:
This project is dual-licensed:
- AGPL-3.0 for open-source use
- Commercial License available for proprietary use
This software is free to use, modify, and distribute under the GNU Affero General Public License v3.0, provided that:
- You give appropriate credit
- You share your modifications under the same license
- If you run a modified version as a service, you must make your source code available
If you want to use this software in a commercial product without open-sourcing your code, please contact me for a commercial license.
Contact via github or kofi
Built to help HDHomeRun users avoid unnecessary Schedules Direct subscriptions while providing a reliable, efficient EPG solution for self-hosted media servers.
- Issues: https://github.com/metaColin/HDHomeRun2XMLTV/issues
- Documentation: https://github.com/metaColin/HDHomeRun2XMLTV
If you find HDHomeRun2XMLTV useful and it's saving you from a Schedules Direct subscription, consider supporting its development:
Your support helps maintain and improve this project. Thank you!