Derp. Fix missing constant post rename
This commit is contained in:
@@ -62,7 +62,7 @@ section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin:0 auto;
|
margin:0 auto;
|
||||||
width:auto;
|
width:auto;
|
||||||
display:table
|
display:table
|
||||||
@@ -82,13 +82,16 @@ pre {
|
|||||||
|
|
||||||
code, pre {
|
code, pre {
|
||||||
font-family: "Comic Mono", monospace;
|
font-family: "Comic Mono", monospace;
|
||||||
font-size: 1.0em;
|
/* font-size: 1.0em; */
|
||||||
|
font-size: .9em;
|
||||||
color: var(--color1);
|
color: var(--color1);
|
||||||
text-align: center
|
/* text-align: center */
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-size: .8em
|
/* font-size: .8em; (fixing it messes up mobile view) */
|
||||||
|
font-size: .8em
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
text-justify: none;
|
text-justify: none;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ i konsthol.eu 70
|
|||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
i## Log 📜 konsthol.eu 70
|
i## Log 📜 konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
|
112-01-2025 - Simple way to extend yt-dlp /log/simple_way_to_extend_yt_dlp-12-01-2025.txt konsthol.eu 70
|
||||||
119-12-2024 - The magic of Wake-On-LAN /log/the_magic_of_wake_on_lan-19-12-2024.txt konsthol.eu 70
|
119-12-2024 - The magic of Wake-On-LAN /log/the_magic_of_wake_on_lan-19-12-2024.txt konsthol.eu 70
|
||||||
125-02-2023 - WebCall /log/webcall-25-02-2023.txt konsthol.eu 70
|
125-02-2023 - WebCall /log/webcall-25-02-2023.txt konsthol.eu 70
|
||||||
117-08-2022 - wpgtk is just more convenient /log/choose_wpgtk_over_just_pywal-17-08-2022.txt konsthol.eu 70
|
117-08-2022 - wpgtk is just more convenient /log/choose_wpgtk_over_just_pywal-17-08-2022.txt konsthol.eu 70
|
||||||
@@ -101,11 +102,11 @@ iI could be livestreaming at konsthol.eu 70
|
|||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
hOwncast url:https://tv.konsthol.eu konsthol.eu 70
|
hOwncast url:https://tv.konsthol.eu konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
i## Piped 📹 konsthol.eu 70
|
i## Invidious 📹 konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
iMy Piped instance which you can use resides at konsthol.eu 70
|
iMy Invidious instance which you can use, resides at konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
hPiped url:https://piped.konsthol.eu/ konsthol.eu 70
|
hInvidious url:https://piped.konsthol.eu/ konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
i## Gopher 🕳️ konsthol.eu 70
|
i## Gopher 🕳️ konsthol.eu 70
|
||||||
i konsthol.eu 70
|
i konsthol.eu 70
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ My Thesis can be found here
|
|||||||
|
|
||||||
## Log 📜
|
## Log 📜
|
||||||
|
|
||||||
|
=> /log/simple_way_to_extend_yt_dlp-12-01-2025.gmi 12-01-2025 - Simple way to extend yt-dlp
|
||||||
=> /log/the_magic_of_wake_on_lan-19-12-2024.gmi 19-12-2024 - The magic of Wake-On-LAN
|
=> /log/the_magic_of_wake_on_lan-19-12-2024.gmi 19-12-2024 - The magic of Wake-On-LAN
|
||||||
=> /log/webcall-25-02-2023.gmi 25-02-2023 - WebCall
|
=> /log/webcall-25-02-2023.gmi 25-02-2023 - WebCall
|
||||||
=> /log/choose_wpgtk_over_just_pywal-17-08-2022.gmi 17-08-2022 - wpgtk is just more convenient
|
=> /log/choose_wpgtk_over_just_pywal-17-08-2022.gmi 17-08-2022 - wpgtk is just more convenient
|
||||||
@@ -101,11 +102,11 @@ I could be livestreaming at
|
|||||||
|
|
||||||
=> https://tv.konsthol.eu Owncast
|
=> https://tv.konsthol.eu Owncast
|
||||||
|
|
||||||
## Piped 📹
|
## Invidious 📹
|
||||||
|
|
||||||
My Piped instance which you can use resides at
|
My Invidious instance which you can use, resides at
|
||||||
|
|
||||||
=> https://piped.konsthol.eu/ Piped
|
=> https://piped.konsthol.eu/ Invidious
|
||||||
|
|
||||||
## Gopher 🕳️
|
## Gopher 🕳️
|
||||||
|
|
||||||
|
|||||||
13
index.html
13
index.html
@@ -88,6 +88,9 @@
|
|||||||
</p>
|
</p>
|
||||||
<h2 id="log">Log 📜</h2>
|
<h2 id="log">Log 📜</h2>
|
||||||
<p>
|
<p>
|
||||||
|
<a href="/log/simple_way_to_extend_yt_dlp-12-01-2025.html"
|
||||||
|
>12-01-2025 - Simple way to extend yt-dlp</a
|
||||||
|
><br />
|
||||||
<a href="/log/the_magic_of_wake_on_lan-19-12-2024.html"
|
<a href="/log/the_magic_of_wake_on_lan-19-12-2024.html"
|
||||||
>19-12-2024 - The magic of Wake-On-LAN</a
|
>19-12-2024 - The magic of Wake-On-LAN</a
|
||||||
><br />
|
><br />
|
||||||
@@ -125,9 +128,9 @@
|
|||||||
<h2 id="owncast">Owncast 📺</h2>
|
<h2 id="owncast">Owncast 📺</h2>
|
||||||
<p>I could be livestreaming at</p>
|
<p>I could be livestreaming at</p>
|
||||||
<p><a href="https://tv.konsthol.eu">Owncast</a><br /></p>
|
<p><a href="https://tv.konsthol.eu">Owncast</a><br /></p>
|
||||||
<h2 id="piped">Piped 📹</h2>
|
<h2 id="invidious">Invidious 📹</h2>
|
||||||
<p>My Piped instance which you can use resides at</p>
|
<p>My Invidious instance which you can use, resides at</p>
|
||||||
<p><a href="https://piped.konsthol.eu/">Piped</a><br /></p>
|
<p><a href="https://piped.konsthol.eu/">Invidious</a><br /></p>
|
||||||
<h2 id="gopher">Gopher 🕳️</h2>
|
<h2 id="gopher">Gopher 🕳️</h2>
|
||||||
<p>My Gopher Hole for this homepage is accessible via</p>
|
<p>My Gopher Hole for this homepage is accessible via</p>
|
||||||
<p><a href="gopher://konsthol.eu">Gopher 🦫</a><br /></p>
|
<p><a href="gopher://konsthol.eu">Gopher 🦫</a><br /></p>
|
||||||
@@ -182,8 +185,8 @@ function action() {
|
|||||||
<p>I accept donations for any reason</p>
|
<p>I accept donations for any reason</p>
|
||||||
<p><a href="donate.html">Donate</a><br /></p>
|
<p><a href="donate.html">Donate</a><br /></p>
|
||||||
<h2>Daily Unique Visitors</h2><p>
|
<h2>Daily Unique Visitors</h2><p>
|
||||||
Saturday 28/12/24 15:36:55
|
Saturday 19/04/25 20:47:56
|
||||||
3
|
2
|
||||||
</p>
|
</p>
|
||||||
<h2 id="also-on-the-web">Also on the web 🕸️</h2>
|
<h2 id="also-on-the-web">Also on the web 🕸️</h2>
|
||||||
<p><a href="https://konsthol.eu">http website</a><br /></p>
|
<p><a href="https://konsthol.eu">http website</a><br /></p>
|
||||||
|
|||||||
75
log/simple_way_to_extend_yt_dlp-12-01-2025.gmi
Normal file
75
log/simple_way_to_extend_yt_dlp-12-01-2025.gmi
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
> DATE: Sun 12 Jan 2025 15:51 By: konsthol@pm.me
|
||||||
|
|
||||||
|
# Simple way to extend yt-dlp
|
||||||
|
|
||||||
|
Lots of people use yt-dlp either directly or indirectly through mpv. It's a powerful tool that acts as a website scraper and it supports thousands of websites. The website its mostly used for is like the name suggests YouTube. Now, YouTube is a great resource but usage through the website is quite unpleasant so lots of people opt out to use alternative frontends like Invidious or Piped. Lots of times you just want to use mpv to stream a YouTube video by providing the link like:
|
||||||
|
|
||||||
|
> mpv https://youtube.com/watch?v=[VideoID]
|
||||||
|
|
||||||
|
That works like a charm, but what happens when you provide a link of an alternative frontend? Well, it translates it to the aforementioned format in order to work. But there are so many instances of Invidious and Piped, so how does it know what to do? That was my question as well since I use a self hosted Piped instance and it does not recognize the domain. Obviously.
|
||||||
|
|
||||||
|
Thankfully, yt-dlp is an open source project so you can actually see what goes on behind the scenes. In my case, I installed it with the Arch Linux package manager and it resides at:
|
||||||
|
|
||||||
|
> /usr/lib/python3.13/site-packages/yt_dlp/
|
||||||
|
|
||||||
|
The way yt-dlp works is that it has a folder called "extractor" in that path and in that folder there is a python file for each supported website. In YouTube's case it's youtube.py. I opened it and I saw this:
|
||||||
|
|
||||||
|
```
|
||||||
|
class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
|
"""Provide base functions for Youtube extractors"""
|
||||||
|
|
||||||
|
_RESERVED_NAMES = (
|
||||||
|
r'channel|c|user|playlist|watch|w|v|embed|e|live|watch_popup|clip|'
|
||||||
|
r'shorts|movies|results|search|shared|hashtag|trending|explore|feed|feeds|'
|
||||||
|
r'browse|oembed|get_video_info|iframe_api|s/player|source|'
|
||||||
|
r'storefront|oops|index|account|t/terms|about|upload|signin|logout')
|
||||||
|
|
||||||
|
_PLAYLIST_ID_RE = r'(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL|LL|LM)'
|
||||||
|
|
||||||
|
# _NETRC_MACHINE = 'youtube'
|
||||||
|
|
||||||
|
# If True it will raise an error if no login info is provided
|
||||||
|
_LOGIN_REQUIRED = False
|
||||||
|
|
||||||
|
_INVIDIOUS_SITES = (
|
||||||
|
# invidious-redirect websites
|
||||||
|
r'(?:www\.)?redirect\.invidious\.io',
|
||||||
|
r'(?:(?:www|dev)\.)?invidio\.us',
|
||||||
|
# Invidious instances taken from https://github.com/iv-org/documentation/blob/master/docs/instances.md
|
||||||
|
r'(?:www\.)?invidious\.pussthecat\.org',
|
||||||
|
r'(?:www\.)?invidious\.zee\.li',
|
||||||
|
[more instances here]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
There is a class called YoutubeBaseInfoExtractor that has an array of instances called _INVIDIOUS_SITES that uses a regex to catch every domain there. Now, I saw at the GitHub page of yt-dlp a lot of people asking the maintainers to add more instances on this list. Theoretically you also can just edit the file and add a domain so that it recognizes that one too. But, in my personal opinion it's never a good idea to edit upstream files because as the program updates your changes will be overwritten. So I found another way to deal with this.
|
||||||
|
|
||||||
|
You see, yt-dlp is not just a command line utility. You can use it as a library to make your own extractors for websites. The way you do that is by creating your own plugins. In my case, I didn't actually want to make a new extractor but somehow extend an array of an already existing one. Not all extractors use this method but since YouTube does, it would work. So I made this file at this location:
|
||||||
|
|
||||||
|
> ~/.config/yt-dlp/plugins/piped/yt_dlp_plugins/extractor/piped.py
|
||||||
|
|
||||||
|
The contents are simple:
|
||||||
|
|
||||||
|
```
|
||||||
|
from yt_dlp.extractor.youtube import YoutubeBaseInfoExtractor, YoutubeIE
|
||||||
|
|
||||||
|
class CustomYoutubeBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||||
|
_INVIDIOUS_SITES = YoutubeBaseInfoExtractor._INVIDIOUS_SITES + (
|
||||||
|
r'(?:www\.)?piped\.konsthol\.eu',
|
||||||
|
)
|
||||||
|
|
||||||
|
class PipedKonstholYoutubeIE(YoutubeIE, CustomYoutubeBaseInfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?piped\.konsthol\.eu/watch\?v=(?P<id>[0-9A-Za-z_-]{11})'
|
||||||
|
IE_NAME = 'piped.konsthol.eu'
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
We import the class that contains the array we need and the youtube extractor. We make a new class in which we provide the one that has the array. We access the array and add a new regex for our domain. Then we make a new class for the extractor, provide the one we just created and the YouTube extractor class and we tell it to work for urls that look like the one we provided. In that way, this pseudo extractor is being activated when we provide a url that looks like this, it extends the actual YouTube extractor and activates that one, only this time it works for our domain too.
|
||||||
|
|
||||||
|
It's amazing what you can do with open source software just by observing how a program works. Now every time someone needs a new domain for an alternative YouTube frontend added, instead of asking the developers to do that, using this simple solution he/she can just add it to the plugin.
|
||||||
|
|
||||||
|
=> https://github.com/yt-dlp/yt-dlp/ yt-dlp GitHub page
|
||||||
|
|
||||||
|
=> /cgi-bin/nimlike/show/log/simple_way_to_extend_yt_dlp-12-01-2025.gmi View likes and comments!
|
||||||
|
|
||||||
|
=> ..
|
||||||
151
log/simple_way_to_extend_yt_dlp-12-01-2025.html
Normal file
151
log/simple_way_to_extend_yt_dlp-12-01-2025.html
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Konsthol</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
|
<link rel="alternate" type="application/atom+xml" title="RSS Feed" href="/rss.xml">
|
||||||
|
<link rel="stylesheet" href="/css/style.css" >
|
||||||
|
<link rel="shortcut icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function(d,t) {
|
||||||
|
var BASE_URL="https://chat.konsthol.eu";
|
||||||
|
var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
||||||
|
g.src=BASE_URL+"/packs/js/sdk.js";
|
||||||
|
g.defer = true;
|
||||||
|
g.async = true;
|
||||||
|
s.parentNode.insertBefore(g,s);
|
||||||
|
window.chatwootSettings = {
|
||||||
|
darkMode: "dark"
|
||||||
|
};
|
||||||
|
g.onload=function(){
|
||||||
|
window.chatwootSDK.run({
|
||||||
|
websiteToken: 'rYqPF7TtnospKkLhtjf5LkPy',
|
||||||
|
baseUrl: BASE_URL
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})(document,"script");
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section>
|
||||||
|
<blockquote>
|
||||||
|
<p>DATE: Sun 12 Jan 2025 15:51 By: konsthol@pm.me</p>
|
||||||
|
</blockquote>
|
||||||
|
<h1 id="simple-way-to-extend-yt-dlp">Simple way to extend yt-dlp</h1>
|
||||||
|
<p>
|
||||||
|
Lots of people use yt-dlp either directly or indirectly through mpv. It’s a
|
||||||
|
powerful tool that acts as a website scraper and it supports thousands of
|
||||||
|
websites. The website its mostly used for is like the name suggests YouTube.
|
||||||
|
Now, YouTube is a great resource but usage through the website is quite
|
||||||
|
unpleasant so lots of people opt out to use alternative frontends like
|
||||||
|
Invidious or Piped. Lots of times you just want to use mpv to stream a YouTube
|
||||||
|
video by providing the link like:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>mpv https://youtube.com/watch?v=[VideoID]</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
That works like a charm, but what happens when you provide a link of an
|
||||||
|
alternative frontend? Well, it translates it to the aforementioned format in
|
||||||
|
order to work. But there are so many instances of Invidious and Piped, so how
|
||||||
|
does it know what to do? That was my question as well since I use a self
|
||||||
|
hosted Piped instance and it does not recognize the domain. Obviously.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Thankfully, yt-dlp is an open source project so you can actually see what goes
|
||||||
|
on behind the scenes. In my case, I installed it with the Arch Linux package
|
||||||
|
manager and it resides at:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>/usr/lib/python3.13/site-packages/yt_dlp/</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
The way yt-dlp works is that it has a folder called “extractor” in that path
|
||||||
|
and in that folder there is a python file for each supported website. In
|
||||||
|
YouTube’s case it’s youtube.py. I opened it and I saw this:
|
||||||
|
</p>
|
||||||
|
<pre><code>class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
|
"""Provide base functions for Youtube extractors"""
|
||||||
|
|
||||||
|
_RESERVED_NAMES = (
|
||||||
|
r'channel|c|user|playlist|watch|w|v|embed|e|live|watch_popup|clip|'
|
||||||
|
r'shorts|movies|results|search|shared|hashtag|trending|explore|feed|feeds|'
|
||||||
|
r'browse|oembed|get_video_info|iframe_api|s/player|source|'
|
||||||
|
r'storefront|oops|index|account|t/terms|about|upload|signin|logout')
|
||||||
|
|
||||||
|
_PLAYLIST_ID_RE = r'(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL|LL|LM)'
|
||||||
|
|
||||||
|
# _NETRC_MACHINE = 'youtube'
|
||||||
|
|
||||||
|
# If True it will raise an error if no login info is provided
|
||||||
|
_LOGIN_REQUIRED = False
|
||||||
|
|
||||||
|
_INVIDIOUS_SITES = (
|
||||||
|
# invidious-redirect websites
|
||||||
|
r'(?:www\.)?redirect\.invidious\.io',
|
||||||
|
r'(?:(?:www|dev)\.)?invidio\.us',
|
||||||
|
# Invidious instances taken from https://github.com/iv-org/documentation/blob/master/docs/instances.md
|
||||||
|
r'(?:www\.)?invidious\.pussthecat\.org',
|
||||||
|
r'(?:www\.)?invidious\.zee\.li',
|
||||||
|
[more instances here]
|
||||||
|
)</code></pre>
|
||||||
|
<p>
|
||||||
|
There is a class called YoutubeBaseInfoExtractor that has an array of
|
||||||
|
instances called _INVIDIOUS_SITES that uses a regex to catch every domain
|
||||||
|
there. Now, I saw at the GitHub page of yt-dlp a lot of people asking the
|
||||||
|
maintainers to add more instances on this list. Theoretically you also can
|
||||||
|
just edit the file and add a domain so that it recognizes that one too. But,
|
||||||
|
in my personal opinion it’s never a good idea to edit upstream files because
|
||||||
|
as the program updates your changes will be overwritten. So I found another
|
||||||
|
way to deal with this.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You see, yt-dlp is not just a command line utility. You can use it as a
|
||||||
|
library to make your own extractors for websites. The way you do that is by
|
||||||
|
creating your own plugins. In my case, I didn’t actually want to make a new
|
||||||
|
extractor but somehow extend an array of an already existing one. Not all
|
||||||
|
extractors use this method but since YouTube does, it would work. So I made
|
||||||
|
this file at this location:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>~/.config/yt-dlp/plugins/piped/yt_dlp_plugins/extractor/piped.py</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>The contents are simple:</p>
|
||||||
|
<pre><code>from yt_dlp.extractor.youtube import YoutubeBaseInfoExtractor, YoutubeIE
|
||||||
|
|
||||||
|
class CustomYoutubeBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||||
|
_INVIDIOUS_SITES = YoutubeBaseInfoExtractor._INVIDIOUS_SITES + (
|
||||||
|
r'(?:www\.)?piped\.konsthol\.eu',
|
||||||
|
)
|
||||||
|
|
||||||
|
class PipedKonstholYoutubeIE(YoutubeIE, CustomYoutubeBaseInfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?piped\.konsthol\.eu/watch\?v=(?P<id>[0-9A-Za-z_-]{11})'
|
||||||
|
IE_NAME = 'piped.konsthol.eu'
|
||||||
|
</code></pre>
|
||||||
|
<p>
|
||||||
|
We import the class that contains the array we need and the youtube extractor.
|
||||||
|
We make a new class in which we provide the one that has the array. We access
|
||||||
|
the array and add a new regex for our domain. Then we make a new class for the
|
||||||
|
extractor, provide the one we just created and the YouTube extractor class and
|
||||||
|
we tell it to work for urls that look like the one we provided. In that way,
|
||||||
|
this pseudo extractor is being activated when we provide a url that looks like
|
||||||
|
this, it extends the actual YouTube extractor and activates that one, only
|
||||||
|
this time it works for our domain too.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
It’s amazing what you can do with open source software just by observing how a
|
||||||
|
program works. Now every time someone needs a new domain for an alternative
|
||||||
|
YouTube frontend added, instead of asking the developers to do that, using
|
||||||
|
this simple solution he/she can just add it to the plugin.
|
||||||
|
</p>
|
||||||
|
<p><a href="https://github.com/yt-dlp/yt-dlp/">yt-dlp GitHub page</a><br /></p>
|
||||||
|
<p><a href="..">..</a></p>
|
||||||
|
<footer>
|
||||||
|
<a id="gemyo" href="gemini://konsthol.eu/"><img src="/images/best_viewed_on_gemini.png" /><br /></a>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
128
log/simple_way_to_extend_yt_dlp-12-01-2025.txt
Normal file
128
log/simple_way_to_extend_yt_dlp-12-01-2025.txt
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
> DATE: Sun 12 Jan 2025 15:51 By: konsthol@pm.me
|
||||||
|
|
||||||
|
# Simple way to extend yt-dlp
|
||||||
|
|
||||||
|
Lots of people use yt-dlp either directly or indirectly through mpv.
|
||||||
|
It's a powerful tool that acts as a website scraper and it supports
|
||||||
|
thousands of websites. The website its mostly used for is like the
|
||||||
|
name suggests YouTube. Now, YouTube is a great resource but usage
|
||||||
|
through the website is quite unpleasant so lots of people opt out to
|
||||||
|
use alternative frontends like Invidious or Piped. Lots of times you
|
||||||
|
just want to use mpv to stream a YouTube video by providing the link
|
||||||
|
like:
|
||||||
|
|
||||||
|
> mpv https://youtube.com/watch?v=[VideoID]
|
||||||
|
|
||||||
|
That works like a charm, but what happens when you provide a link of
|
||||||
|
an alternative frontend? Well, it translates it to the aforementioned
|
||||||
|
format in order to work. But there are so many instances of Invidious
|
||||||
|
and Piped, so how does it know what to do? That was my question as
|
||||||
|
well since I use a self hosted Piped instance and it does not
|
||||||
|
recognize the domain. Obviously.
|
||||||
|
|
||||||
|
Thankfully, yt-dlp is an open source project so you can actually see
|
||||||
|
what goes on behind the scenes. In my case, I installed it with the
|
||||||
|
Arch Linux package manager and it resides at:
|
||||||
|
|
||||||
|
> /usr/lib/python3.13/site-packages/yt_dlp/
|
||||||
|
|
||||||
|
The way yt-dlp works is that it has a folder called "extractor" in
|
||||||
|
that path and in that folder there is a python file for each
|
||||||
|
supported website. In YouTube's case it's youtube.py. I opened it and
|
||||||
|
I saw this:
|
||||||
|
|
||||||
|
|
||||||
|
class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
|
"""Provide base functions for Youtube extractors"""
|
||||||
|
|
||||||
|
_RESERVED_NAMES = (
|
||||||
|
|
||||||
|
r'channel|c|user|playlist|watch|w|v|embed|e|live|watch_popup|clip|'
|
||||||
|
|
||||||
|
r'shorts|movies|results|search|shared|hashtag|trending|explore|feed|fe
|
||||||
|
eds|'
|
||||||
|
r'browse|oembed|get_video_info|iframe_api|s/player|source|'
|
||||||
|
|
||||||
|
r'storefront|oops|index|account|t/terms|about|upload|signin|logout')
|
||||||
|
|
||||||
|
_PLAYLIST_ID_RE =
|
||||||
|
r'(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL
|
||||||
|
|LL|LM)'
|
||||||
|
|
||||||
|
# _NETRC_MACHINE = 'youtube'
|
||||||
|
|
||||||
|
# If True it will raise an error if no login info is provided
|
||||||
|
_LOGIN_REQUIRED = False
|
||||||
|
|
||||||
|
_INVIDIOUS_SITES = (
|
||||||
|
# invidious-redirect websites
|
||||||
|
r'(?:www\.)?redirect\.invidious\.io',
|
||||||
|
r'(?:(?:www|dev)\.)?invidio\.us',
|
||||||
|
# Invidious instances taken from
|
||||||
|
https://github.com/iv-org/documentation/blob/master/docs/instances.md
|
||||||
|
r'(?:www\.)?invidious\.pussthecat\.org',
|
||||||
|
r'(?:www\.)?invidious\.zee\.li',
|
||||||
|
[more instances here]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
There is a class called YoutubeBaseInfoExtractor that has an array of
|
||||||
|
instances called _INVIDIOUS_SITES that uses a regex to catch every
|
||||||
|
domain there. Now, I saw at the GitHub page of yt-dlp a lot of people
|
||||||
|
asking the maintainers to add more instances on this list.
|
||||||
|
Theoretically you also can just edit the file and add a domain so
|
||||||
|
that it recognizes that one too. But, in my personal opinion it's
|
||||||
|
never a good idea to edit upstream files because as the program
|
||||||
|
updates your changes will be overwritten. So I found another way to
|
||||||
|
deal with this.
|
||||||
|
|
||||||
|
You see, yt-dlp is not just a command line utility. You can use it as
|
||||||
|
a library to make your own extractors for websites. The way you do
|
||||||
|
that is by creating your own plugins. In my case, I didn't actually
|
||||||
|
want to make a new extractor but somehow extend an array of an
|
||||||
|
already existing one. Not all extractors use this method but since
|
||||||
|
YouTube does, it would work. So I made this file at this location:
|
||||||
|
|
||||||
|
> ~/.config/yt-dlp/plugins/piped/yt_dlp_plugins/extractor/piped.py
|
||||||
|
|
||||||
|
The contents are simple:
|
||||||
|
|
||||||
|
|
||||||
|
from yt_dlp.extractor.youtube import YoutubeBaseInfoExtractor,
|
||||||
|
YoutubeIE
|
||||||
|
|
||||||
|
class CustomYoutubeBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||||
|
_INVIDIOUS_SITES = YoutubeBaseInfoExtractor._INVIDIOUS_SITES + (
|
||||||
|
r'(?:www\.)?piped\.konsthol\.eu',
|
||||||
|
)
|
||||||
|
|
||||||
|
class PipedKonstholYoutubeIE(YoutubeIE,
|
||||||
|
CustomYoutubeBaseInfoExtractor):
|
||||||
|
_VALID_URL =
|
||||||
|
r'https?://(?:www\.)?piped\.konsthol\.eu/watch\?v=(?P<id>[0-9A-Za-z_-]
|
||||||
|
{11})'
|
||||||
|
IE_NAME = 'piped.konsthol.eu'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
We import the class that contains the array we need and the youtube
|
||||||
|
extractor. We make a new class in which we provide the one that has
|
||||||
|
the array. We access the array and add a new regex for our domain.
|
||||||
|
Then we make a new class for the extractor, provide the one we just
|
||||||
|
created and the YouTube extractor class and we tell it to work for
|
||||||
|
urls that look like the one we provided. In that way, this pseudo
|
||||||
|
extractor is being activated when we provide a url that looks like
|
||||||
|
this, it extends the actual YouTube extractor and activates that one,
|
||||||
|
only this time it works for our domain too.
|
||||||
|
|
||||||
|
It's amazing what you can do with open source software just by
|
||||||
|
observing how a program works. Now every time someone needs a new
|
||||||
|
domain for an alternative YouTube frontend added, instead of asking
|
||||||
|
the developers to do that, using this simple solution he/she can just
|
||||||
|
add it to the plugin.
|
||||||
|
|
||||||
|
yt-dlp GitHub page
|
||||||
|
https://github.com/yt-dlp/yt-dlp/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -3,6 +3,10 @@ Previous Log entries are archived here.
|
|||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
|
|
||||||
|
## 2025
|
||||||
|
|
||||||
|
=> /log/simple_way_to_extend_yt_dlp-12-01-2025.gmi 12-01-2025 - Simple way to extend yt-dlp
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
|
|
||||||
=> /log/the_magic_of_wake_on_lan-19-12-2024.gmi 19-12-2024 - The magic of Wake-On-LAN
|
=> /log/the_magic_of_wake_on_lan-19-12-2024.gmi 19-12-2024 - The magic of Wake-On-LAN
|
||||||
|
|||||||
@@ -33,21 +33,27 @@
|
|||||||
<h1 id="all-log-posts---the-archive">ALL Log Posts - The Archive</h1>
|
<h1 id="all-log-posts---the-archive">ALL Log Posts - The Archive</h1>
|
||||||
<p>Previous Log entries are archived here.</p>
|
<p>Previous Log entries are archived here.</p>
|
||||||
<h1 id="logs">Logs</h1>
|
<h1 id="logs">Logs</h1>
|
||||||
<h2 id="section">2024</h2>
|
<h2 id="section">2025</h2>
|
||||||
|
<p>
|
||||||
|
<a href="/log/simple_way_to_extend_yt_dlp-12-01-2025.html"
|
||||||
|
>12-01-2025 - Simple way to extend yt-dlp</a
|
||||||
|
><br />
|
||||||
|
</p>
|
||||||
|
<h2 id="section-1">2024</h2>
|
||||||
<p>
|
<p>
|
||||||
<a href="/log/the_magic_of_wake_on_lan-19-12-2024.html"
|
<a href="/log/the_magic_of_wake_on_lan-19-12-2024.html"
|
||||||
>19-12-2024 - The magic of Wake-On-LAN</a
|
>19-12-2024 - The magic of Wake-On-LAN</a
|
||||||
><br />
|
><br />
|
||||||
</p>
|
</p>
|
||||||
<h2 id="section-1">2023</h2>
|
<h2 id="section-2">2023</h2>
|
||||||
<p><a href="/log/webcall-25-02-2023.html">25-02-2023 - WebCall</a><br /></p>
|
<p><a href="/log/webcall-25-02-2023.html">25-02-2023 - WebCall</a><br /></p>
|
||||||
<h2 id="section-2">2022</h2>
|
<h2 id="section-3">2022</h2>
|
||||||
<p>
|
<p>
|
||||||
<a href="/log/choose_wpgtk_over_just_pywal-17-08-2022.html"
|
<a href="/log/choose_wpgtk_over_just_pywal-17-08-2022.html"
|
||||||
>17-08-2022 - wpgtk is just more convenient</a
|
>17-08-2022 - wpgtk is just more convenient</a
|
||||||
><br />
|
><br />
|
||||||
</p>
|
</p>
|
||||||
<h2 id="section-3">2021</h2>
|
<h2 id="section-4">2021</h2>
|
||||||
<p>
|
<p>
|
||||||
<a href="/log/easy_file_sharing-12-09-2021.html"
|
<a href="/log/easy_file_sharing-12-09-2021.html"
|
||||||
>12-09-2021 - Awesome file sharing tool</a
|
>12-09-2021 - Awesome file sharing tool</a
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ Previous Log entries are archived here.
|
|||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
|
|
||||||
|
## 2025
|
||||||
|
|
||||||
|
12-01-2025 - Simple way to extend yt-dlp
|
||||||
|
1simple_way_to_extend_yt_dlp-12-01-2025 /log/simple_way_to_extend_yt_dlp-12-01-2025.txt konsthol.eu 70
|
||||||
|
|
||||||
|
|
||||||
## 2024
|
## 2024
|
||||||
|
|
||||||
19-12-2024 - The magic of Wake-On-LAN
|
19-12-2024 - The magic of Wake-On-LAN
|
||||||
|
|||||||
119
rss.xml
119
rss.xml
@@ -6,6 +6,125 @@
|
|||||||
<link>https://konsthol.eu/rss.xml</link>
|
<link>https://konsthol.eu/rss.xml</link>
|
||||||
<atom:link href="https://konsthol.eu/rss.xml" rel="self" type="application/rss+xml"/>
|
<atom:link href="https://konsthol.eu/rss.xml" rel="self" type="application/rss+xml"/>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<title>Simple way to extend yt-dlp</title>
|
||||||
|
<link>https://konsthol.eu/log/simple_way_to_extend_yt_dlp-12-01-2025.html</link>
|
||||||
|
<pubDate>Sun, 12 Jan 2025</pubDate>
|
||||||
|
<description><![CDATA[<blockquote>
|
||||||
|
<p>DATE: Sun 12 Jan 2025 15:51 By: konsthol@pm.me</p>
|
||||||
|
</blockquote>
|
||||||
|
<h1 id="simple-way-to-extend-yt-dlp">Simple way to extend yt-dlp</h1>
|
||||||
|
<p>
|
||||||
|
Lots of people use yt-dlp either directly or indirectly through mpv. It’s a
|
||||||
|
powerful tool that acts as a website scraper and it supports thousands of
|
||||||
|
websites. The website its mostly used for is like the name suggests YouTube.
|
||||||
|
Now, YouTube is a great resource but usage through the website is quite
|
||||||
|
unpleasant so lots of people opt out to use alternative frontends like
|
||||||
|
Invidious or Piped. Lots of times you just want to use mpv to stream a YouTube
|
||||||
|
video by providing the link like:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>mpv https://youtube.com/watch?v=[VideoID]</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
That works like a charm, but what happens when you provide a link of an
|
||||||
|
alternative frontend? Well, it translates it to the aforementioned format in
|
||||||
|
order to work. But there are so many instances of Invidious and Piped, so how
|
||||||
|
does it know what to do? That was my question as well since I use a self
|
||||||
|
hosted Piped instance and it does not recognize the domain. Obviously.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Thankfully, yt-dlp is an open source project so you can actually see what goes
|
||||||
|
on behind the scenes. In my case, I installed it with the Arch Linux package
|
||||||
|
manager and it resides at:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>/usr/lib/python3.13/site-packages/yt_dlp/</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
The way yt-dlp works is that it has a folder called “extractor” in that path
|
||||||
|
and in that folder there is a python file for each supported website. In
|
||||||
|
YouTube’s case it’s youtube.py. I opened it and I saw this:
|
||||||
|
</p>
|
||||||
|
<pre><code>class YoutubeBaseInfoExtractor(InfoExtractor):
|
||||||
|
"""Provide base functions for Youtube extractors"""
|
||||||
|
|
||||||
|
_RESERVED_NAMES = (
|
||||||
|
r'channel|c|user|playlist|watch|w|v|embed|e|live|watch_popup|clip|'
|
||||||
|
r'shorts|movies|results|search|shared|hashtag|trending|explore|feed|feeds|'
|
||||||
|
r'browse|oembed|get_video_info|iframe_api|s/player|source|'
|
||||||
|
r'storefront|oops|index|account|t/terms|about|upload|signin|logout')
|
||||||
|
|
||||||
|
_PLAYLIST_ID_RE = r'(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL|LL|LM)'
|
||||||
|
|
||||||
|
# _NETRC_MACHINE = 'youtube'
|
||||||
|
|
||||||
|
# If True it will raise an error if no login info is provided
|
||||||
|
_LOGIN_REQUIRED = False
|
||||||
|
|
||||||
|
_INVIDIOUS_SITES = (
|
||||||
|
# invidious-redirect websites
|
||||||
|
r'(?:www\.)?redirect\.invidious\.io',
|
||||||
|
r'(?:(?:www|dev)\.)?invidio\.us',
|
||||||
|
# Invidious instances taken from https://github.com/iv-org/documentation/blob/master/docs/instances.md
|
||||||
|
r'(?:www\.)?invidious\.pussthecat\.org',
|
||||||
|
r'(?:www\.)?invidious\.zee\.li',
|
||||||
|
[more instances here]
|
||||||
|
)</code></pre>
|
||||||
|
<p>
|
||||||
|
There is a class called YoutubeBaseInfoExtractor that has an array of
|
||||||
|
instances called _INVIDIOUS_SITES that uses a regex to catch every domain
|
||||||
|
there. Now, I saw at the GitHub page of yt-dlp a lot of people asking the
|
||||||
|
maintainers to add more instances on this list. Theoretically you also can
|
||||||
|
just edit the file and add a domain so that it recognizes that one too. But,
|
||||||
|
in my personal opinion it’s never a good idea to edit upstream files because
|
||||||
|
as the program updates your changes will be overwritten. So I found another
|
||||||
|
way to deal with this.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You see, yt-dlp is not just a command line utility. You can use it as a
|
||||||
|
library to make your own extractors for websites. The way you do that is by
|
||||||
|
creating your own plugins. In my case, I didn’t actually want to make a new
|
||||||
|
extractor but somehow extend an array of an already existing one. Not all
|
||||||
|
extractors use this method but since YouTube does, it would work. So I made
|
||||||
|
this file at this location:
|
||||||
|
</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>~/.config/yt-dlp/plugins/piped/yt_dlp_plugins/extractor/piped.py</p>
|
||||||
|
</blockquote>
|
||||||
|
<p>The contents are simple:</p>
|
||||||
|
<pre><code>from yt_dlp.extractor.youtube import YoutubeBaseInfoExtractor, YoutubeIE
|
||||||
|
|
||||||
|
class CustomYoutubeBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||||
|
_INVIDIOUS_SITES = YoutubeBaseInfoExtractor._INVIDIOUS_SITES + (
|
||||||
|
r'(?:www\.)?piped\.konsthol\.eu',
|
||||||
|
)
|
||||||
|
|
||||||
|
class PipedKonstholYoutubeIE(YoutubeIE, CustomYoutubeBaseInfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?piped\.konsthol\.eu/watch\?v=(?P<id>[0-9A-Za-z_-]{11})'
|
||||||
|
IE_NAME = 'piped.konsthol.eu'
|
||||||
|
</code></pre>
|
||||||
|
<p>
|
||||||
|
We import the class that contains the array we need and the youtube extractor.
|
||||||
|
We make a new class in which we provide the one that has the array. We access
|
||||||
|
the array and add a new regex for our domain. Then we make a new class for the
|
||||||
|
extractor, provide the one we just created and the YouTube extractor class and
|
||||||
|
we tell it to work for urls that look like the one we provided. In that way,
|
||||||
|
this pseudo extractor is being activated when we provide a url that looks like
|
||||||
|
this, it extends the actual YouTube extractor and activates that one, only
|
||||||
|
this time it works for our domain too.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
It’s amazing what you can do with open source software just by observing how a
|
||||||
|
program works. Now every time someone needs a new domain for an alternative
|
||||||
|
YouTube frontend added, instead of asking the developers to do that, using
|
||||||
|
this simple solution he/she can just add it to the plugin.
|
||||||
|
</p>
|
||||||
|
<p><a href="https://github.com/yt-dlp/yt-dlp/">yt-dlp GitHub page</a><br /></p>
|
||||||
|
<p><a href="..">..</a></p>]]></description>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
|
||||||
<item>
|
<item>
|
||||||
<title>The magic of Wake-On-LAN</title>
|
<title>The magic of Wake-On-LAN</title>
|
||||||
<link>https://konsthol.eu/log/the_magic_of_wake_on_lan-19-12-2024.html</link>
|
<link>https://konsthol.eu/log/the_magic_of_wake_on_lan-19-12-2024.html</link>
|
||||||
|
|||||||
Reference in New Issue
Block a user