fetchtv
v1.5.2
Published
A Node.js CLI tool to manage Fetch TV recordings.
Maintainers
Readme
fetchtv
A Node.js CLI tool to download Fetch TV recordings.
Based on lingfish/fetchtv-cli (Python) which is based on jinxo13/FetchTV-Helpers (also Python).
Contents
Demo
https://gist.github.com/user-attachments/assets/61dfab62-a715-4cc3-a4d1-93ee0db43827
Quick Start
Installation
- NPX (Easiest)
- Node.js from Source
- Docker from Source
Installation: NPX
[!NOTE] NPX requires Node.js installed and running on your system (suggestion: use Volta).
The easiest way to install fetchtv is via NPX.
First, ensure Node.js is running:
node --version # Ideally >= v22.x but fetchtv is >= v18.x compatibleThen, run fetchtv via NPX:
npx fetchtv # Run the tool
npx fetchtv@latest # (optional) "@latest" ensures package is up-to-date
npx -y fetchtv@latest # (optional) "-y" flag skips any prompts
npx fetchtv info
npx fetchtv shows
npx fetchtv recordings
# etc…If you encounter permissions errors with
npxtry runningnpx clear-npx-cacheprior to runningnpx -y fetchtv(this clears the cache and re-downloads the package).
Installation: Node.js from Source
[!NOTE] Node.js from source requires Node.js installed and running on your system (suggestion: use Volta).
- Clone the
fetchtvrepository:git clone https://github.com/furey/fetchtv.git - Navigate to the cloned repository directory:
cd /path/to/fetchtv - Ensure Node.js is running:
node --version # Ideally >= v22.x but fetchtv is >= v18.x compatible - Install Node.js dependencies:
npm ci - Run
fetchtv:node fetchtv.js node fetchtv.js info node fetchtv.js recordings node fetchtv.js shows # etc…
Optional: Link fetchtv Tool
You may optionally link the fetchtv tool to your system path for easier access:
npm linkThis will create a symlink to the fetchtv command in your global node_modules directory, allowing you to run it from anywhere in your terminal:
fetchtv
fetchtv info
fetchtv shows
fetchtv recordings
# etc…To uninstall the linked tool, run:
npm unlinkInstallation: Docker from Source
[!NOTE] Docker from source requires Docker installed and running on your system.
- Clone the
fetchtvrepository:git clone https://github.com/furey/fetchtv.git - Navigate to the cloned repository directory:
cd /path/to/fetchtv - Ensure Docker is running:
docker --version # Ideally >= v27.x - Build the Docker image:
docker build -t fetchtv . - Run the container:
docker run -t --rm fetchtv docker run -t --rm fetchtv info docker run -t --rm fetchtv shows docker run -t --rm fetchtv recordings # etc…
UPnP/SSDP Discovery Issues
UPnP/SSDP discovery can be unreliable in Docker containers.
To work around this, it's recommended to specify your Fetch TV server's IP address directly with the --ip (and optionally --port) option when running the container. For example:
docker run -t --rm fetchtv
docker run -t --rm fetchtv info --ip=192.168.86.71
docker run -t --rm fetchtv shows --ip=192.168.86.71
docker run -t --rm fetchtv recordings --ip=192.168.86.71
# etc…Usage
If you installed via NPX, you can run it from anywhere:
npx fetchtv <COMMAND> [OPTIONS]If you installed from Node.js source, you can run it from the cloned repo directory:
cd /path/to/fetchtv
node fetchtv.js <COMMAND> [OPTIONS]If you linked the tool after installing from source, you can run it from anywhere:
fetchtv <COMMAND> [OPTIONS]| Command/Option | Alias | Type | Description |
| ---------------- | ----- | --------- | ------------------------------------------------------------------------------- |
| info | | command | Returns Fetch TV server details |
| recordings | | command | List episode recordings |
| shows | | command | List show titles and not the episodes within |
| --ip | | string | Specify the IP Address of the Fetch TV server |
| --port | | number | Specify the port of the Fetch TV server (default: 49152) |
| --show | -s | array | Filter recordings to show titles containing the specified text (repeatable) |
| --exclude | -e | array | Filter recordings to show titles NOT containing the specified text (repeatable) |
| --title | -t | array | Filter recordings to episode titles containing the specified text (repeatable) |
| --is-recording | | boolean | Filter recordings to only those that are currently recording |
| --save | | string | Save recordings to the specified path |
| --template | | string | Template for save path/filename structure (uses --save as base path) |
| --for-plex | | boolean | Uses Plex-compatible template for saving recordings (overrides --template) |
| --overwrite | -o | boolean | Overwrite existing files when saving |
| --json | -j | boolean | Output show/recording/save results in JSON |
| --debug | -d | boolean | Enable verbose logging for debugging |
| --help | -h | boolean | Show help message |
Template Variables
[!IMPORTANT] When using
--template, the template string must be enclosed in single quotes (') to prevent shell expansion. For example:fetchtv recordings --save=./downloads --template='${show_title}/${recording_title}.${ext}'
When using --template, the following variables are available:
| Variable | Description | Example |
| -------------------------- | -------------------------------- | ---------------------------------------------- |
| ${show_title} | Title of the show | Australian Survivor |
| ${recording_title} | Title of the recording/episode | S10 E2 - Episode 2 of Season 10 - Tue 18 Feb |
| ${season_number} | Season number (if available) | 10 |
| ${season_number_padded} | Season number with leading zero | 10 |
| ${episode_number} | Episode number (if available) | 2 |
| ${episode_number_padded} | Episode number with leading zero | 02 |
| ${ext} | File extension (ts, mp4, etc) | ts |
Plex-Compatible Template
The --for-plex option uses a predefined template optimized for Plex media server:
`${show_title}/Season ${season_number}/${show_title} - S${season_number}E${episode_number_padded}.${ext}`Example Templates
Save recordings with show folder:
${show_title}/${recording_title}.${ext}Save recordings with show folder and SXXEXX episode naming:
${show_title}/S${season_number_padded}E${episode_number_padded}.${ext}Save recordings with show and season folders:
${show_title}/Season ${season_number}/${recording_title}.${ext}Examples
[!NOTE] The following examples assume you have a Fetch TV server on your local network and you've linked the tool to your system path.
Search for Fetch TV servers:
fetchtvDisplay Fetch box details (uses auto-discovery):
fetchtv infoList recorded show titles:
fetchtv shows --ip=192.168.86.71List recordings:
fetchtv recordings --ip=192.168.86.71List recordings and output as JSON:
fetchtv recordings --ip=192.168.86.71 --jsonSave new recordings to ./downloads (creates directory if needed):
fetchtv recordings --ip=192.168.86.71 --save=./downloadsSave new recordings but exclude show titles containing News:
fetchtv recordings --ip=192.168.86.71 --exclude=News --save=./downloadsSave new episodes for the show MasterChef:
fetchtv recordings --ip=192.168.86.71 --show=MasterChef --save=./downloadsSave & overwrite specific MasterChef episodes containing S04E12 or S04E13:
fetchtv recordings --ip=192.168.86.71 --show=MasterChef --title=S04E12 --title=S04E13 --save=./downloads --overwriteList only items currently being recorded:
fetchtv recordings --ip=192.168.86.71 --is-recordingSave only items currently being recorded:
fetchtv recordings --ip=192.168.86.71 --is-recording --save=./in-progressSave recordings using a custom path template:
fetchtv recordings --ip=192.168.86.71 --save=./downloads --template='${show_title}/${recording_title}.${ext}'Save recordings in Plex-compatible path format:
fetchtv recordings --ip=192.168.86.71 --save=./media --for-plexDisclaimer
This project:
- Is licensed under the GNU GPLv3 License.
- Is not affiliated with or endorsed by Fetch TV.
- Is a derivative work based on
lingfish/fetchtv-cli. - Is written with the assistance of AI and may contain errors.
- Is intended for educational and experimental purposes only.
- Is provided as-is with no warranty—please use at your own risk.
Support
If you've found this project helpful consider supporting my work through:
Buy Me a Coffee | GitHub Sponsorship
Contributions help me continue developing and improving this tool, allowing me to dedicate more time to add new features and ensuring it remains a valuable resource for the community.
