⚠️ This project is no longer in active development. See YouTubeCast for an alternative.
Create podcast feeds for YouTube channels, users and playlists
- Generate RSS feeds that can be added to podcast apps with support for video podcasts (e.g. Apple Podcasts or Pocket Casts)
- Simple web server for serving RSS feed data and video files
- Download YouTube videos from channels, users, or playlists for higher quality
Prerequisites:
- Ensure docker is set up and running on your machine (https://docs.docker.com/get-docker)
- Set up a hostname that can be used to access your machine from the internet (can use a static IP address as well)
- Get a YouTube API v3 key (https://developers.google.com/youtube/v3/getting-started)
To run this application using docker:
- Create a directory to store data files (can be on an external drive or NAS, which is handy when using the highQualityVideo option)
- Create the configuration files as described below (
docker-compose.yml
,config.json
, and optionallycookies.txt
) - Run
docker-compose up -d
in the folder where yourdocker-compose.yml
lives - Check the logs using
docker-compose logs -f
to see if there are any errors in your configuration - (Optional) - Replace
cover.png
files in the data directory with custom cover artwork (YouTube channel or user profile pictures are pulled automatically on first run) - Wait for the first update run to pull feed data and download any videos if applicable
- Add podcast feeds to your podcast app of choice with the URL
http://hostname/feedId
version: '3'
services:
youtube-podcast-feeds:
image: trevorsharp/youtube-podcast-feeds:latest
container_name: youtube-podcast-feeds
restart: always
ports:
- 80:80
volumes:
- REPLACE_WITH_CONFIG_DIRECTORY_PATH/config.json:/app/config.json
- REPLACE_WITH_DATA_DIRECTORY_PATH:/app/data
# Remove the following line if you are not using a cookies.txt file
- REPLACE_WITH_COOKIES_DIRECTORY_PATH/cookies.txt:/app/cookies.txt
Create a file named docker-compose.yml
with the contents above and substitute in the file path to your config files and the file path to your data directory.
{
"hostname" : "http://example.com",
"apiKey" : "YOUTUBE_API_KEY",
"timeZone" : "America/New_York",
"updateInterval" : 2,
"maxResults": 5,
"maxEpisodes" : 10,
"feeds" : [
{
"id" : "h3podcast",
"title" : "H3 Podcast",
"channel" : "UCLtREJY21xRfCuEKvdki1Kw",
"filter" : "H3 Podcast #[0-9]+"
}
]
}
Create a file named config.json
with the contents above and fill in the following parameters:
- hostname - Hostname that will be used to access podcast feeds and content
- apiKey - YouTube API v3 key
- feed.id - Unique identifier for each feed (letters, numbers and hyphens only, no spaces)
- feed.title - Title for the podcast (read by podcast clients)
- feed.channel - YouTube channel id (from https://youtube.com/channel/CHANNEL_ID)
- feed.user - YouTube username (from https://youtube.com/user/USERNAME)
- feed.playlist - YouTube playlist id (from https://www.youtube.com/playlist?list=PLAYLIST_ID)
- timeZone - Name of time zone used for logging - Default: America/New_York
- updateInterval - Interval for updating feeds (in hours) - Default: 2
- maxResults - Number of videos to search for when updating (per feed) - Default: 5
- maxEpisodes - Maximum number of videos to keep (per feed), useful when using the highQualityVideo option to limit storage usage - Default: unlimited
- highQualityVideo - If true, podcast feeds will default to downloading videos from YouTube into the data folder using the highest quality available in mp4 format (usually 1080p vs 720p without using this option). Will provide the lower quality version until the high quality version has downloaded. - Default: false
WARNING: Setting highQualityVideo to true will significantly increase the amount of storage space and CPU usage required to run
- feed.highQualityVideo - Overrides the global setting for a specific podcast feed - Default: none / uses global setting
- feed.maxEpisodes - Overrides the global setting for a specific podcast feed - Default: none / uses global setting
- feed.filter - String containing regex used to filter videos. Only videos with titles that have a match for this regex will be added to the feed - Default: none
See Advanced Parameters for more options
Note: Regex are evaluated case insensitive. Be sure to double escape any backslashes (e.g. use "\\s"
for a whitespace character instead of just "\s"
)
If you want to download YouTube content that requires user authentication to download, you will need to add a cookies.txt file to your configuration. One reason for needing this is to download members-only videos. Note that the source of these videos (channel, user, or playlist) still must be either public or unlisted. For members-only videos, I recommend going to the channel's home page and scrolling down to find an auto-generated playlist titled "Members-only videos" which will contain all the videos posted for members of the channel.
To generate this file:
- To get a cookies.txt file, download a browser extension (such as this one for Chrome)
- Log in to YouTube
- With a YouTube tab open, open the cookies.txt extension and click the export/download button
- Rename the downloaded file to
cookies.txt
Files will be stored in the data directory using the following structure:
data
|
└── content
| └── videoId1.mp4
| └── videoId2.mp4
| └── videoId3.mp4
| ...
|
└── feedId1
| └── cover.png
| └── feedData.json
|
└── feedId2
└── cover.png
└── feedData.json
...
- feed.episodeNumbers - String containing regex used to extract episode number from video title - Default: no episode numbers
- feed.cleanTitles - Array of 2-item sub-arrays where the first element of each sub-array is a regex to match part of an episode title and the second element is a string replacement for any matches found - Default: empty
- feed.titleCase - When set to true, episode titles are converted to title case - Default: false
In these regex, you must place the leftmost set of parentheses around the actual episode number. For example, "#([0-9]+)"
or "Episode ([0-9]+)."
will work, but "(#[0-9]+)"
or "[0-9]+"
will not work.
Example: "Ep ([0-9]+)"
would be used to extract the episode number (123
) from a video title that looks like this: This is my podcast title | Ep 123
.
The string replacement (second element of the sub-array) can use the RegExp.$1-$9 properties (see here for more info on how these are used). Common separators (-
and |
) are cleaned up automatically.
Example: [["Podcast Name", ""], ["Ep ([0-9]+)", "#$1"]]
will transform Podcast Episode Title | Podcast Name | Ep 123
into Podcast Episode Title | #123
.
These features are experimental, and they may reduce compatibility, increase resource usage, and cause problems. Proceed with caution.
- maxQualityVideo - If true, video quality downloads will be allowed to exceed 1080p. Must be used in conjunction with
highQualityVideo
parameter set to true - Default: false - maxVideoHeight - Number to represent the maximum height of downloaded videos in pixels. Must be used in conjunction with
maxQualityVideo
parameter set to true. Suggested values are 2160 and 1440 - Default: 2160