All apps · 0 apps
Schedules-Direct-XMLTV
Docker app from heroeswearkapes Community Apps' Repository
Overview
Readme
View on GitHubSchedules Direct XMLTV
A lightweight Docker service that automatically fetches TV guide data from Schedules Direct, converts it to XMLTV format, keeps it updated on a schedule, and serves the resulting XMLTV file over HTTP.
This is particularly useful for providing Schedules Direct guide data to applications such as:
- Threadfin
- Jellyfin
- Plex
- Emby
- TVHeadend
- Other applications that accept an XMLTV URL
Features
- Automatically downloads TV listings from Schedules Direct
- Converts Schedules Direct data to XMLTV
- First-run setup mode for discovering Schedules Direct lineups
- No lineup ID required before initial installation
- Performs an initial guide download when a lineup is configured
- Automatically refreshes guide data every day
- Serves
tvxml.xmlusing nginx - Configurable Schedules Direct lineups
- Supports multiple comma-separated lineups
- Configurable number of guide days to download
- Configurable timezone
- Persistent XMLTV data
- Docker Compose support
- Unraid Community Applications support
- Multi-architecture Docker images
linux/amd64linux/arm64
Docker Image
The current image is:
heroeswearkapes/schedules-direct-xmltv:latest
During the migration period, the same image is also published under the legacy repository:
heroeswearkapes/schedules-direct-update-and-serve:latest
New installations should use:
heroeswearkapes/schedules-direct-xmltv
Requirements
You will need:
- Docker or Docker Compose
- A valid Schedules Direct subscription
Schedules Direct credentials are provided to the container at runtime and are not stored in the Docker image.
You do not need to know your Schedules Direct lineup ID before installing the container.
If SD_LINEUPS is left blank, the container starts in setup mode so you can discover and add a lineup using the included Schedules Direct configuration wizard.
Quick Start
Clone the repository:
git clone https://github.com/heroeswearkapes/schedules-direct-xmltv.git
cd schedules-direct-xmltv
Create your runtime configuration:
cp .env.example .env
Edit .env:
nano .env
At minimum, configure your Schedules Direct credentials:
SCHEDULES_DIRECT_USERNAME=your_schedules_direct_username
SCHEDULES_DIRECT_PASSWORD=your_schedules_direct_password
If you already know your Schedules Direct lineup ID, you can also configure:
SD_LINEUPS=USA-OTA-10001
If you do not know your lineup ID yet, leave it blank:
SD_LINEUPS=
Then start the container:
docker compose up -d
If SD_LINEUPS is blank, the container will start in setup mode. See First-Time Setup: Finding Your Schedules Direct Lineup below.
Docker Compose
The included docker-compose.yaml uses:
services:
xmltv:
image: heroeswearkapes/schedules-direct-xmltv:latest
container_name: schedules-direct-xmltv
environment:
SD_USERNAME: ${SCHEDULES_DIRECT_USERNAME}
SD_PASSWORD: ${SCHEDULES_DIRECT_PASSWORD}
SD_LINEUPS: ${SD_LINEUPS:-}
SD_FETCH_DAYS: ${SD_FETCH_DAYS:-2}
TZ: ${TZ:-America/New_York}
ports:
- "${XMLTV_PORT:-51969}:80"
volumes:
- xmltv_data:/var/www/html
restart: unless-stopped
volumes:
xmltv_data:
Configuration
The public .env.example contains all runtime options required by Docker Compose.
Schedules Direct Username
SCHEDULES_DIRECT_USERNAME=your_schedules_direct_username
Your Schedules Direct account username.
Schedules Direct Password
SCHEDULES_DIRECT_PASSWORD=your_schedules_direct_password
Your Schedules Direct account password.
Schedules Direct Lineups
Schedules Direct lineup IDs are supplied using SD_LINEUPS.
If you already know your lineup ID:
SD_LINEUPS=USA-OTA-10001
Multiple lineups may be supplied as a comma-separated list:
SD_LINEUPS=USA-OTA-10001,USA-YOUTUBE-X
If you do not know your lineup ID yet, leave the value blank:
SD_LINEUPS=
The container will start in setup mode instead of attempting to download guide data.
While in setup mode:
- The container remains running.
- nginx remains available.
- The initial XMLTV synchronization is skipped.
- Scheduled synchronization through cron is disabled.
- The Schedules Direct configuration wizard can be used to discover or add a lineup.
Once a lineup ID is configured and the container is restarted, normal XMLTV synchronization begins automatically.
First-Time Setup: Finding Your Schedules Direct Lineup
With the newer Schedules Direct SD-JSON service, you do not need to obtain a lineup ID from the Schedules Direct website before installing the container.
If you don't know your lineup ID, leave:
SD_LINEUPS=
and start the container.
The logs should indicate:
[INFO] No Schedules Direct lineup configured.
[INFO] Starting in setup mode.
[INFO] Initial XMLTV synchronization skipped.
[INFO] Cron disabled while running in setup mode.
You can monitor the logs with:
docker logs -f schedules-direct-xmltv
1. Start the Schedules Direct Configuration Wizard
For a standard Docker Compose installation:
docker exec -it schedules-direct-xmltv \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
For Unraid, the default container name is:
Schedules-Direct-XMLTV
Run:
docker exec -it Schedules-Direct-XMLTV \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
2. Accept the Default Cache File
The first prompt will look similar to:
Cache file for lineups, schedules and programs.
Cache file: [/root/.xmltv/tv_grab_zz_sdjson.cache]
Press Enter to accept the default cache-file location.
The prompt may appear to be waiting without explicitly telling you to continue. This is normal. Press Enter to proceed.
3. Select the Channel ID Format
You will be asked:
Select channel ID format:
0: Default Format (eg: I12345.json.schedulesdirect.org)
1: tv_grab_na_dd Format (eg: I12345.labs.zap2it.com)
2: MythTV Internal DD Grabber Format (eg: 12345)
Select one: [0,1,2 (default=0)]
For a normal new installation, press Enter to use option 0.
4. Select the Previously Shown Format
The next prompt is:
Select previously shown format:
0: Date Only
1: Date And Time
Select one: [0,1 (default=0)]
For a normal installation, press Enter to use Date Only.
5. Enter Your Schedules Direct Credentials
The wizard will request your Schedules Direct username and password.
It will then authenticate with the Schedules Direct SD-JSON service and retrieve the lineups currently enabled for your account.
6. Add or Manage Account Lineups
The wizard will display any lineups currently enabled for your Schedules Direct account.
For example:
Current lineups enabled for your Schedules Direct account:
#. Lineup ID | Name | Location | Transport
1. USA-OTA-10001 | Local Broadcast Listings | 10001 | Antenna
You will then see:
Edit account lineups: [continue,add,delete (default=continue)]
If the lineup you need is already listed, press Enter to continue.
If you need to find or add a lineup, enter:
add
7. Search for a Lineup
The wizard asks:
Lineup ID or Country (ISO-3166-1 alpha 3 such as USA or CAN):
If you already know a lineup ID, you may enter it directly.
If you do not know it, enter your three-letter country code.
For the United States:
USA
For Canada:
CAN
For this example:
USA
The wizard will query Schedules Direct and then ask for your ZIP or postal code:
Zip Code:
For this example:
10001
Schedules Direct will return the available providers and lineups for that location.
For example:
#. Lineup ID | Name | Location | Transport
1. USA-0000001-CUSTOM | ChannelsDVR TV-Everywhere | National | IPTV
...
37. USA-OTA-10001 | Antenna | 10001 | Antenna
The actual list will depend on your location and available television providers.
Select the number corresponding to the lineup you want.
For this example:
37
This adds:
USA-OTA-10001
to the Schedules Direct account.
8. Continue After Adding the Lineup
After adding a lineup, the wizard returns to the list of currently enabled account lineups.
The newly added lineup should now appear.
At:
Edit account lineups: [continue,add,delete (default=continue)]
press Enter to continue.
9. Select Lineup Mode
The wizard asks:
Select mode: [lineups,channels (default=lineups)]
Press Enter to use complete lineups.
This matches the SD_LINEUPS configuration used by this container.
10. Select the Lineup
The wizard will ask which enabled lineup or lineups should be used for the configuration.
For example:
USA-OTA-10001 [yes,no,all,none (default=no)]
Enter:
yes
If additional lineups are enabled on your account, the wizard may ask about each one individually.
11. Configure SD_LINEUPS
You now know the lineup ID required by the container.
For the example above:
USA-OTA-10001
Update your Docker Compose .env file:
SD_LINEUPS=USA-OTA-10001
For multiple lineups:
SD_LINEUPS=USA-OTA-10001,USA-YOUTUBE-X
Then recreate the container:
docker compose up -d
For Unraid:
- Open the Docker tab.
- Edit Schedules Direct XMLTV.
- Enter the lineup ID into Schedules Direct Lineups.
- Apply the changes.
- Restart the container if necessary.
12. Verify Normal Operation
After restarting with a valid lineup, the logs should show the lineup being added and the initial XMLTV synchronization starting.
Monitor the logs with:
docker logs -f schedules-direct-xmltv
The resulting guide will be available at:
http://YOUR-SERVER-IP:51969/tvxml.xml
You can verify the XMLTV endpoint with:
curl -I http://YOUR-SERVER-IP:51969/tvxml.xml
A successful response should resemble:
HTTP/1.1 200 OK
Content-Type: text/xml
You can also inspect the beginning of the generated XMLTV file:
curl -s http://YOUR-SERVER-IP:51969/tvxml.xml | head -20
Guide Days
SD_FETCH_DAYS=2
Controls how many days of guide data are downloaded during each synchronization.
For example:
SD_FETCH_DAYS=7
downloads seven days of guide data.
Timezone
TZ=America/New_York
The container performs its scheduled guide refresh at midnight according to the configured timezone.
Examples:
America/New_York
America/Chicago
America/Denver
America/Los_Angeles
HTTP Port
XMLTV_PORT=51969
This controls the host port used to access the XMLTV file.
The container itself serves HTTP through nginx on port 80.
Accessing XMLTV
With the default configuration, the generated guide is available at:
http://YOUR-SERVER-IP:51969/tvxml.xml
For example:
http://192.168.1.100:51969/tvxml.xml
Use this URL as the XMLTV source in Threadfin, Jellyfin, Plex, Emby, TVHeadend, or another compatible application.
How It Works
When the container starts, it checks whether SD_LINEUPS has been configured.
Setup Mode
If SD_LINEUPS is blank:
- Runtime configuration is read from environment variables.
- The container enters setup mode.
- A base
tv_grab_zz_sdjsonconfiguration file is generated. - Initial XMLTV synchronization is skipped.
- Scheduled synchronization through cron is disabled.
- nginx starts and keeps the container running.
- The included
tv_grab_zz_sdjsonconfiguration wizard can be used to discover or add a Schedules Direct lineup.
Setup mode allows a new user to install and start the container before knowing their Schedules Direct lineup ID.
Normal Mode
If SD_LINEUPS contains one or more lineup IDs:
- Runtime configuration is read from environment variables.
- A
tv_grab_zz_sdjsonconfiguration file is generated. - The configured Schedules Direct lineups are added.
- Any stale Schedules Direct cache is removed.
- An initial XMLTV synchronization is performed.
- Cron is started for scheduled updates.
- nginx starts and serves the generated XMLTV data.
The initial synchronization and scheduled synchronization both use:
tv_grab_zz_sdjson
The generated XMLTV file is stored at:
/var/www/html/tvxml.xml
Scheduled Updates
When a lineup is configured, the container automatically refreshes the guide every day at midnight:
00:00
The configured TZ environment variable determines which timezone is used for the scheduled refresh.
Cron is disabled while the container is running in setup mode with an empty SD_LINEUPS.
Container logs show synchronization activity.
View logs with:
docker logs -f schedules-direct-xmltv
Typical output resembles:
[SYNC] Starting Schedules Direct data fetch...
[SYNC] Fetching 2 day(s) of guide data...
[SYNC] Completed Schedules Direct data fetch.
[SYNC] XMLTV output: /var/www/html/tvxml.xml
Persistent Data
The Docker Compose configuration uses the named volume:
xmltv_data
mounted at:
/var/www/html
This stores the generated XMLTV data and Schedules Direct configuration outside the container's writable layer.
The primary generated file is:
/var/www/html/tvxml.xml
Manual Docker Example
The container can also be run without Docker Compose.
If you already know your lineup ID:
docker run -d \
--name schedules-direct-xmltv \
-e SD_USERNAME="your_username" \
-e SD_PASSWORD="your_password" \
-e SD_LINEUPS="USA-OTA-10001" \
-e SD_FETCH_DAYS="2" \
-e TZ="America/New_York" \
-p 51969:80 \
-v xmltv_data:/var/www/html \
--restart unless-stopped \
heroeswearkapes/schedules-direct-xmltv:latest
Then access:
http://YOUR-SERVER-IP:51969/tvxml.xml
Manual Docker Setup Mode
If you do not know your lineup ID yet, omit SD_LINEUPS:
docker run -d \
--name schedules-direct-xmltv \
-e SD_USERNAME="your_username" \
-e SD_PASSWORD="your_password" \
-e SD_FETCH_DAYS="2" \
-e TZ="America/New_York" \
-p 51969:80 \
-v xmltv_data:/var/www/html \
--restart unless-stopped \
heroeswearkapes/schedules-direct-xmltv:latest
Then run the configuration wizard:
docker exec -it schedules-direct-xmltv \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
After discovering your lineup ID, recreate the container with SD_LINEUPS configured.
Unraid
Schedules Direct XMLTV is available through Unraid Community Applications.
Search Community Applications for:
Schedules Direct XMLTV
During initial installation:
- Enter your Schedules Direct username.
- Enter your Schedules Direct password.
- Leave Schedules Direct Lineups blank if you do not know your lineup ID yet.
- Configure the desired guide days and timezone.
- Configure the persistent XMLTV data path.
The container will start in setup mode when the lineup field is blank.
Open an Unraid terminal and run:
docker exec -it Schedules-Direct-XMLTV \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
Follow the lineup discovery procedure documented above.
Once you have the lineup ID:
- Edit the Schedules Direct XMLTV container.
- Enter the ID into Schedules Direct Lineups.
- Apply the changes.
- The container will restart and perform its initial guide synchronization.
Multi-Architecture Support
Published Docker images support:
linux/amd64
linux/arm64
This allows the same image to run on standard x86-64 Docker hosts as well as ARM64 systems such as compatible Raspberry Pi devices.
Updating
Docker Compose
docker compose pull
docker compose up -d
Docker CLI
docker pull heroeswearkapes/schedules-direct-xmltv:latest
Then recreate the container using the same environment variables, port mapping, and persistent volume.
Unraid
Updates can be installed through the normal Unraid Docker update process.
Persistent XMLTV data remains stored outside the container.
Troubleshooting
Container exits immediately
Check the logs:
docker logs schedules-direct-xmltv
The container requires both:
SD_USERNAME
SD_PASSWORD
If either is missing, startup will fail.
SD_LINEUPS is optional.
Leaving SD_LINEUPS blank does not cause the container to exit. The container starts in setup mode instead.
Container starts in setup mode
If the logs show:
[INFO] No Schedules Direct lineup configured.
[INFO] Starting in setup mode.
then SD_LINEUPS is blank.
This is expected for a first-time installation.
Run the configuration wizard:
docker exec -it schedules-direct-xmltv \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
For Unraid:
docker exec -it Schedules-Direct-XMLTV \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
After discovering your lineup ID, add it to SD_LINEUPS and recreate or restart the container.
Configuration wizard appears stuck at the cache prompt
The first wizard prompt looks like:
Cache file for lineups, schedules and programs.
Cache file: [/root/.xmltv/tv_grab_zz_sdjson.cache]
The wizard is waiting for input.
Press Enter to accept the default cache file and continue.
No lineup is shown on the Schedules Direct website
The newer Schedules Direct SD-JSON service manages lineups through applications using the API.
Use the included configuration wizard to query available lineups.
When prompted:
Edit account lineups: [continue,add,delete (default=continue)]
enter:
add
Then enter your country code and ZIP/postal code.
The wizard will query Schedules Direct and display the available lineups for your location.
XMLTV file is unavailable
Verify the container is running:
docker ps
Then check:
docker logs schedules-direct-xmltv
If the container is in setup mode, a valid guide will not be generated until SD_LINEUPS is configured.
Once a lineup is configured, allow the initial Schedules Direct synchronization to complete before accessing:
http://YOUR-SERVER-IP:51969/tvxml.xml
Verify the XMLTV endpoint
Run:
curl -I http://YOUR-SERVER-IP:51969/tvxml.xml
A working endpoint should return:
HTTP/1.1 200 OK
Content-Type: text/xml
You can also inspect the generated XML:
curl -s http://YOUR-SERVER-IP:51969/tvxml.xml | head -20
Incorrect or missing channels
Verify that SD_LINEUPS contains valid lineup IDs associated with your Schedules Direct account.
For example:
SD_LINEUPS=USA-OTA-10001
Multiple lineups must be separated by commas:
SD_LINEUPS=USA-OTA-10001,USA-YOUTUBE-X
You can use the configuration wizard to review the lineups currently enabled for your account.
Invalid lineup ID
If the container attempts synchronization and reports that the configured lineup is unavailable or invalid, verify the lineup through:
docker exec -it schedules-direct-xmltv \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
For Unraid:
docker exec -it Schedules-Direct-XMLTV \
tv_grab_zz_sdjson \
--configure \
--config-file /tmp/sdjson-setup.conf
Then update SD_LINEUPS with the correct lineup ID.
Scheduled updates are not running
Scheduled updates are disabled while the container is in setup mode.
Verify that SD_LINEUPS is configured.
Then check the logs:
docker logs schedules-direct-xmltv
A normal startup with a valid lineup should include:
[INFO] Starting cron...
If cron does not start after a lineup is configured, recreate the container and check the startup logs for errors.
Change the number of guide days
Set:
SD_FETCH_DAYS=7
and recreate the container:
docker compose up -d
For Unraid, edit Guide Days, apply the changes, and restart the container.
Guide data appears stale
Check when the XMLTV file was last modified:
docker exec schedules-direct-xmltv \
ls -lh /var/www/html/tvxml.xml
Then inspect recent synchronization logs:
docker logs schedules-direct-xmltv
The container normally refreshes the guide once per day at midnight according to the configured TZ.
Timezone or refresh time is incorrect
Verify:
TZ=America/New_York
or your preferred IANA timezone.
Examples:
America/New_York
America/Chicago
America/Denver
America/Los_Angeles
After changing the timezone, recreate or restart the container.
Port 51969 is already in use
Change:
XMLTV_PORT=51969
to another unused host port.
For example:
XMLTV_PORT=51970
The XMLTV URL would then become:
http://YOUR-SERVER-IP:51970/tvxml.xml
View container logs
Docker Compose:
docker compose logs -f
Docker CLI:
docker logs -f schedules-direct-xmltv
Unraid:
docker logs -f Schedules-Direct-XMLTV
Security
Schedules Direct credentials are runtime configuration.
Do not commit your .env file to Git.
The included .gitignore excludes:
.env
build.env
The .env.example file contains placeholders only and is safe to commit.
For Unraid, the Schedules Direct password field is masked in the Community Applications template.
Source
Project source:
https://github.com/heroeswearkapes/schedules-direct-xmltv
Docker Hub:
https://hub.docker.com/r/heroeswearkapes/schedules-direct-xmltv
Inspiration and Acknowledgements
This project was inspired by the original schedules-direct-update-and-serve project created by John Corser and its contributors.
Schedules Direct XMLTV is a separate implementation created to provide a maintained, multi-architecture Docker solution with simplified configuration, Docker Compose support, and Unraid integration.
This project uses tv_grab_zz_sdjson from the XMLTV utilities to retrieve guide data from Schedules Direct.
Community feedback and issue reports help improve the setup experience and documentation for new users.
Disclaimer
This is an independent community project.
It is not affiliated with or endorsed by Schedules Direct, XMLTV, Threadfin, Jellyfin, Plex, Emby, TVHeadend, Docker, or Unraid.
License
This project is licensed under the MIT License.
See the LICENSE file for the full license text.
Requirements
A valid Schedules Direct subscription is required.
If you already know your Schedules Direct lineup ID, enter it in the Schedules Direct Lineups field during installation.
If you do not know your lineup ID, leave Schedules Direct Lineups blank. The container will start in setup mode.
After the container starts, open either the Unraid Terminal or the container Console and run:
tv_grab_zz_sdjson --configure --config-file /tmp/sdjson-setup.conf
If using the Unraid Terminal instead of the container Console, run:
docker exec -it Schedules-Direct-XMLTV tv_grab_zz_sdjson --configure --config-file /tmp/sdjson-setup.conf
The configuration wizard will allow you to search for and add a Schedules Direct lineup using your country and ZIP/postal code.
After discovering your lineup ID, edit the container, enter the lineup ID in Schedules Direct Lineups, apply the changes, and restart the container.
The generated XMLTV guide will then be available at:
http://YOUR-UNRAID-IP:51969/tvxml.xml
Categories
Download Statistics
Related apps
Explore more like this
Explore allDetails
heroeswearkapes/schedules-direct-xmltv:latestRuntime arguments
- Network
bridge- Shell
bash- Privileged
- false
Template configuration
Host port used to serve the generated tvxml.xml file.
- Target
- 80
- Default
- 51969
- Value
- 51969
Your Schedules Direct account username.
- Target
- SD_USERNAME
Your Schedules Direct account password.
- Target
- SD_PASSWORD
Optional comma-separated Schedules Direct lineup IDs. Leave blank during initial setup if you do not know your lineup ID yet. After the container starts, use the SD-JSON configuration wizard to discover or add a lineup. Example: USA-OTA-10001
- Target
- SD_LINEUPS
Number of days of guide data to download during each synchronization.
- Target
- SD_FETCH_DAYS
- Default
- 2
- Value
- 2
Timezone used by the container and the scheduled midnight guide refresh.
- Target
- TZ
- Default
- America/New_York
- Value
- America/New_York
Persistent storage for generated XMLTV data and Schedules Direct configuration.
- Target
- /var/www/html
- Default
- /mnt/user/appdata/schedules-direct-xmltv
- Value
- /mnt/user/appdata/schedules-direct-xmltv