mirror of
https://github.com/davegallant/davegallant.github.io.git
synced 2025-08-05 08:13:40 +00:00
237 lines
9.8 KiB
HTML
237 lines
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html><head>
|
|
<meta charset="utf-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Watching YouTube in Private - davegallant</title><link rel="icon" type="image/png" href=https://davegallant.ca/favicon.ico /><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="description" content="" />
|
|
<meta property="og:image" content=""/>
|
|
<meta property="og:title" content="Watching YouTube in Private" />
|
|
<meta property="og:description" content="" />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:url" content="/blog/2022/12/10/watching-youtube-in-private/" /><meta property="article:section" content="post" />
|
|
<meta property="article:published_time" content="2022-12-10T21:46:55-05:00" />
|
|
<meta property="article:modified_time" content="2022-12-10T21:46:55-05:00" />
|
|
|
|
<meta name="twitter:card" content="summary"/>
|
|
<meta name="twitter:title" content="Watching YouTube in Private"/>
|
|
<meta name="twitter:description" content=""/>
|
|
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@1,500&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans&display=swap" rel="stylesheet">
|
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono" rel="stylesheet">
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" media="screen" href="/css/main.0e5aa3b634b92d61bafebfd908290cc7a034e4d50e6a0c59ce50044560179c4e.css" />
|
|
<link id="darkModeStyle" rel="stylesheet" type="text/css" href="/css/dark.b11f422ffce8151207bad84653d44cb512043f9efe93a0a049f836b9cc32b34a.css" disabled />
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript"
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
</script>
|
|
|
|
|
|
<script type="text/x-mathjax-config">
|
|
MathJax.Hub.Config({
|
|
tex2jax: {
|
|
inlineMath: [['$','$'], ['\\(','\\)']],
|
|
displayMath: [['$$','$$'], ['\[','\]']],
|
|
processEscapes: true,
|
|
processEnvironments: true,
|
|
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
|
TeX: { equationNumbers: { autoNumber: "AMS" },
|
|
extensions: ["AMSmath.js", "AMSsymbols.js"] }
|
|
}
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css">
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.js"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/contrib/auto-render.min.js" onload="renderMathInElement(document.body);"></script>
|
|
|
|
|
|
<script>
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
renderMathInElement(document.body, {
|
|
delimiters: [
|
|
{left: "$$", right: "$$", display: true},
|
|
{left: "$", right: "$", display: false}
|
|
]
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="/css/custom.2e59ff60a2d9c7e42e3c1af2aff0ba627da46f910a234867e98d178eb05c87dc.css">
|
|
|
|
</head>
|
|
<body>
|
|
<div class="content"><header>
|
|
<div class="main">
|
|
<a href="/">davegallant</a>
|
|
</div>
|
|
<nav>
|
|
|
|
<a href="/">Home</a>
|
|
|
|
<a href="/post">All posts</a>
|
|
|
|
<a href="/index.xml">RSS</a>
|
|
|
|
<a href="/tags">Tags</a>
|
|
|
|
<a href="/about">About</a>
|
|
|
|
| <span id="dark-mode-toggle" onclick="toggleTheme()"></span>
|
|
<script src="/js/themetoggle.js"></script>
|
|
|
|
</nav>
|
|
</header>
|
|
|
|
<main>
|
|
<article>
|
|
<div class="title">
|
|
<h1 class="title">Watching YouTube in Private</h1>
|
|
<div class="meta">Posted on Dec 10, 2022</div>
|
|
</div>
|
|
|
|
|
|
<section class="body"><p>I recently stumbled upon <a href="https://yewtu.be">yewtu.be</a> and found it intriguing. It not only allows you to watch YouTube without <em>being on YouTube</em>, but it also allows you to create an account and subscribe to channels without a Google account. What sort of wizardry is going on under the hood? It turns out that it’s a hosted instance of <a href="https://invidious.io/">invidious</a>.</p>
|
|
<p><img src="/images/watching-youtube-in-private/computerphile.png" alt="requestly"></p>
|
|
<p>The layout is simple, and <strong>JavaScript is not required</strong>.</p>
|
|
<p>I started using <a href="https://yewtu.be">yewtu.be</a> as my primary client for watching videos. I subscribe to several YouTube channels and I prefer the interface invidiuous provides due to its simplicity. It’s also nice to be in control of my search and watch history.</p>
|
|
<p>A few days ago, yewtu.be went down briefly, and that motivated me enough to self-host invidious. There are several other hosted instances listed <a href="https://docs.invidious.io/instances/">here</a>, but being able to easily backup my own instance (including subscriptions and watch history) is more compelling in my case.</p>
|
|
<h3 id="hosting-invidious">Hosting invidious<a href="#hosting-invidious" class="hanchor" ariaLabel="Anchor">#</a></h3>
|
|
<p>The quickest way to get invidious up is with docker-compose as mentioned in the <a href="https://docs.invidious.io/installation/">docs</a>.</p>
|
|
<p>I made a few modifications (such as pinning the container’s tag), and ended up with:</p>
|
|
<pre><code class="language-yaml">version: "3"
|
|
services:
|
|
|
|
invidious:
|
|
image: quay.io/invidious/invidious:5160d8bae39dc5cc5d51abee90571a03c08d0f2b
|
|
restart: unless-stopped
|
|
ports:
|
|
- "0.0.0.0:3000:3000"
|
|
environment:
|
|
INVIDIOUS_CONFIG: |
|
|
db:
|
|
dbname: invidious
|
|
user: kemal
|
|
password: kemal
|
|
host: invidious-db
|
|
port: 5432
|
|
check_tables: true
|
|
healthcheck:
|
|
test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/comments/jNQXAC9IVRw || exit 1
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 2
|
|
depends_on:
|
|
- invidious-db
|
|
|
|
invidious-db:
|
|
image: docker.io/library/postgres:14
|
|
restart: unless-stopped
|
|
volumes:
|
|
- postgresdata:/var/lib/postgresql/data
|
|
- ./config/sql:/config/sql
|
|
- ./docker/init-invidious-db.sh:/docker-entrypoint-initdb.d/init-invidious-db.sh
|
|
environment:
|
|
POSTGRES_DB: invidious
|
|
POSTGRES_USER: kemal
|
|
POSTGRES_PASSWORD: kemal
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
|
|
|
|
volumes:
|
|
postgresdata:
|
|
</code></pre>
|
|
<p>After invidious was up and running, I installed <a href="https://tailscale.com/">Tailscale</a> on it to leverage its MagicDNS, and I’m now able to access this instance from anywhere at <a href="http://invidious:3000/feed/subscriptions">http://invidious:3000/feed/subscriptions</a>.</p>
|
|
<h3 id="redirecting-youtube-links">Redirecting YouTube links<a href="#redirecting-youtube-links" class="hanchor" ariaLabel="Anchor">#</a></h3>
|
|
<p>I figured it would be nice to redirect existing YouTube links that others send me, so that I could seamlessly watch the videos using invidious.</p>
|
|
<p>I went looking for a way to redirect paths at the browser level. I found the lightweight proxy <a href="https://requestly.io/">requestly</a>, which can be used to modify http requests in my browser. I created the following rules:</p>
|
|
<p><img src="/images/watching-youtube-in-private/requestly-rules.png" alt="requestly"></p>
|
|
<p>Now the link <a href="https://www.youtube.com/watch?v=-lz30by8-sU">https://www.youtube.com/watch?v=-lz30by8-sU</a> will redirect to <a href="http://invidious:3000/watch?v=-lz30by8-sU">http://invidious:3000/watch?v=-lz30by8-sU</a></p>
|
|
<p>I’m still looking for ways to improve this invidious setup. There doesn’t appear to be a way to stream in 4K yet.</p></section>
|
|
|
|
<div class="post-tags">
|
|
|
|
|
|
<nav class="nav tags">
|
|
<ul class="tags">
|
|
|
|
<li><a href="/tags/invidious">invidious</a></li>
|
|
|
|
<li><a href="/tags/degoogle">degoogle</a></li>
|
|
|
|
<li><a href="/tags/youtube">youtube</a></li>
|
|
|
|
<li><a href="/tags/yewtu.be">yewtu.be</a></li>
|
|
|
|
<li><a href="/tags/tailscale">tailscale</a></li>
|
|
|
|
<li><a href="/tags/privacy">privacy</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
</article>
|
|
</main>
|
|
|
|
<section id='comments' class='comments'>
|
|
<div class='container sep-before'>
|
|
<div class='comments'><script>
|
|
|
|
var getTheme = window.localStorage && window.localStorage.getItem("theme-storage");
|
|
getTheme = getTheme == null ? 'light' : getTheme;
|
|
|
|
let theme = getTheme === 'dark' ? 'github-dark' : 'github-light';
|
|
let s = document.createElement('script');
|
|
s.src = 'https://utteranc.es/client.js';
|
|
s.setAttribute('repo', 'davegallant\/davegallant.github.io');
|
|
s.setAttribute('issue-term', 'pathname');
|
|
s.setAttribute('theme', theme);
|
|
s.setAttribute('crossorigin', 'anonymous');
|
|
s.setAttribute('async', '');
|
|
document.querySelector('div.comments').innerHTML = '';
|
|
document.querySelector('div.comments').appendChild(s);
|
|
</script>
|
|
</div>
|
|
</div>
|
|
</section><footer>
|
|
<div style="display:flex"><a class="soc" href="https://github.com/davegallant" rel="me" title="GitHub"><i data-feather="github"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://twitter.com/davega11ant/" rel="me" title="Twitter"><i data-feather="twitter"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://mastodon.social/@davegallant" rel="me" title="Mastodon"><i data-feather="speaker"></i></a>
|
|
<a class="border"></a><a class="soc" href="https://www.linkedin.com/in/dave-gallant/" rel="me" title="LinkedIn"><i data-feather="linkedin"></i></a>
|
|
<a class="border"></a></div>
|
|
<div class="footer-info">
|
|
2023 Dave Gallant
|
|
</div>
|
|
</footer>
|
|
|
|
|
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-V8WJDERTX9"></script>
|
|
<script>
|
|
var doNotTrack = false;
|
|
if (!doNotTrack) {
|
|
window.dataLayer = window.dataLayer || [];
|
|
function gtag(){dataLayer.push(arguments);}
|
|
gtag('js', new Date());
|
|
gtag('config', 'G-V8WJDERTX9', { 'anonymize_ip': false });
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
feather.replace()
|
|
</script></div>
|
|
</body>
|
|
</html>
|