pronounced a bit like "cool tube"
Koutube is a web service, running in Cloudflare Workers, that fixes YouTube embeds on messenger platforms like Discord. It allows you to watch YouTube videos directly on Discord without opening a new tab or window.
s/y/k
(sounds like SIKE very funny)
- ๐ Displays likes, subscribers, publish/last update date, and view count on videos
- ๐ฆ Public database listing
- โฏ๏ธ Supports YouTube Music (
music.koutube.com
), including mixes โ๏ธ Supportsm.youtube.com
- ๐ฑ Supports shorts
- ๐บ Supports channels
- ๐ถ Supports playlists
- ๐คณ Supports livestreams
- ๐ Supports Return YouTube Dislike
- ๐งฟ Supports DeArrow
- ๐ผ Supports embedding with the regular player
- ๐ Displays timecodes, including the format
1h2m3s
- โ๏ธ Displays channel verification
- ๐ฒ Automatically opens the YouTube app on mobile
- ๐๏ธ Natively embeds videos on Discord
- ๐ Easily improve
youtu.be
links using https://koutu.be - ๐ก๏ธ Removes tracking on redirects
- ๐งช (BETA)
/img/
endpoint for generating embed images - ๐ฅ No random explosions (fixed!)
This project uses a 7-day cache of every URL that it processes to avoid hammering any services. Subject to change.
For image embeds, the cache is 1 year since I expect it to be used in more static applications.
I often clear the cache when I push a new update.
Not case-sensitive
nocache
- disables fetching the cached versionnothumb
- disable embedding the thumbnail, may help fix video cropping on mobile Discord clientsshorts
- treats the video as shortsdislikes
- shows dislikes, requests from Return YouTube Dislikeitag
- forces a specific video quality, onlyitag=22
for 720p anditag=18
for 360p are alloweddearrow
- requests the thumbnail and title from DeArrowstock
- embed the regular YouTube embed. Automatically set to true for some content like livestreams and premieres
The
dearrow
parameter uses SponsorBlock data licensed used under CC BY-NC-SA 4.0 from https://sponsor.ajay.app/.
Shorts and non-16:9 videos are not going to have a thumbnail in the embed due to the Discord embed prioritizing the image's aspect ratio over the video and cropping it incorrectly on mobile.
Example usage:
https://koutu.be/dQw4w9WgXcQ?nothumb&shorts
Note: remember URL param syntax, the first param is always defined by a question mark, the subsequent ones - by an ampersand.
This is an endpoint to generate embed images, for example for embedding into markdown. It renders the real YouTube embed as an image.
https://koutu.be/img/watch?v=dQw4w9WgXcQ
?size=hd720
- preset sizes:small
- 320x180medium
- 640x360large
- 854x480hd720
- 1280x720hd1080
- 1920x1080
Default is medium
.
[![Alt Text](https://koutu.be/img/watch?v=CpJSgoOD1-Y&size=small)](https://koutu.be/watch?v=CpJSgoOD1-Y)
To install Koutube, you need to have Node and Cloudflare's wrangler tool installed on your system. You also need to have a Cloudflare account and enabled Workers, as well as a Workers D1 database in Cloudflare. The Browser Rendering API is used for the image embed function.
To install wrangler, run the following command in your terminal:
npm install -g wrangler
Replace the binding in wrangler.toml
with your own ID:
[[d1_databases]]
binding = "D1_DB"
database_id = "1234abcd-5678-ef90-1234-5678ef901234" # <-- Replace with your D1 database ID
database_name = "koutube-db"
You will need to initialize the database with the following command:
npm run init-remote-db
Once you have everything set up, you can clone this repository and deploy Koutube to your own Workers domain.
git clone https://github.com/igerman00/koutube.git
cd koutube
npm i
wrangler deploy
You should see a message like this:
โ
๏ธ wrangler 3.9.0
------------------
Total Upload: 7.10 KiB / gzip: 2.45 KiB
Uploaded Koutube (1.96 sec)
Published Koutube (1.43 sec)
https://koutube.yourdomain.workers.dev
Current Deployment ID: 1234abcd-5678-efgh-9012-ijklmnopqrst
Now you can use Koutube by replacing https://www.youtube.com/watch?v=
with https://koutube.yourdomain.workers.dev/watch?v=
in any YouTube video URL and sending it to Discord.
Koutube is capable of working with a semi-private Invidious instance. All that is required for that is to define the secrets and Koutube will automatically pick your instance over every other.
To configure your own:
- Follow the Invidious installation guide
- Optionally restrict the instance to require an
Authorization header
Sidenote:/vi*
and/latest_version*
must be publicly accessible for Discord to validate the embed - Deploy secrets using Wrangler:
npx wrangler secret put IV_AUTH
# Follow the steps and enter your token value
npx wrangler secret put IV_DOMAIN
# Do the same but for your domain. For example, invidious.yourdoma.in
If you do not want to keep your instance private, you can either just add it in
constants.ts
or specify any authorization token value
If you want your secrets to be accessible during developement, create a file named .dev.vars
and populate it as such:
IV_DOMAIN=invidious.yourdoma.in
IV_AUTH=YourTok3n
To run Koutube locally for development, simply run:
wrangler dev
You should see a message like this:
โ
๏ธ wrangler 3.9.0
------------------
wrangler dev now uses local mode by default, powered by ๐ฅ Miniflare and ๐ท workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
โ Starting local server...
[mf:inf] Ready on http://0.0.0.0:8787
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
โ [b open a [d] open [l] turn off local [c] clear [x] to โ
โ browser, Devtools, mode, console, exit โ
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
To manually purge the production database, run:
npm run init-remote-db
To purge the local database, run:
npm run init-db
This will remove everything and initialize an empty D1 database.
Koutube is licensed under the GPL-3.0 License.
-
The cache listing, which is a list of the vast majority of links processed by Koutube is public
-
I try not to log anything I don't need, but I log some errors here and there and whenever a cached response is returned.
-
A private Invidious instance is used for now due to unreliable public ones. No logging is configured
I have to actively enable log streaming by typing a command or logging into the Cloudflare dashboard. As you can imagine, I don't do that unless I am debugging an error.
- @dylanpdx' vxtiktok for some embed template inspiration and bot user-agent list
- Invidious team for the easy-to-use API
- Return YouTube Dislike by @Anarios
- DeArrow by @ajayyy
- Cloudflare, for providing the free and easy-to-use serverless architecture and D1 database API for this project