Fabio Manganiello<p>📦 <a class="hashtag" href="https://manganiello.social/tag/platypush" rel="nofollow noopener noreferrer" target="_blank">#Platypush</a> <a href="https://pypi.org/project/platypush/" rel="nofollow noopener noreferrer" target="_blank">1.3.5 is out</a>!</p><p>The main feature of this release is the support for multiple backends in the <a href="https://docs.platypush.tech/platypush/plugins/youtube.html" rel="nofollow noopener noreferrer" target="_blank"><code>youtube</code> plugin</a>.</p><p>It allows you to watch ad-free YouTube videos on any supported media player and manage your playlists and subscriptions through multiple YouTube implementations.</p><strong>Support for multiple YouTube backends</strong><p>Earlier only <a class="hashtag" href="https://manganiello.social/tag/piped" rel="nofollow noopener noreferrer" target="_blank">#Piped</a> was supported, but given the state of the project and most instances (all the ones I’ve tested, including my own, are still blocked by <a class="hashtag" href="https://manganiello.social/tag/youtube" rel="nofollow noopener noreferrer" target="_blank">#YouTube</a>’s new restrictions) I’ve added support for <a class="hashtag" href="https://manganiello.social/tag/invidious" rel="nofollow noopener noreferrer" target="_blank">#Invidious</a> too, and that’s currently the recommended backend.</p><p>The in-browser YouTube player now plays videos using the Invidious embedded player if you configure the <code>invidious</code> backend, so the UI can be used as a full alternative frontend for Invidious.</p><p>I’ve also added a new <code>google</code> backend that leverages the official <a href="https://developers.google.com/youtube/v3" rel="nofollow noopener noreferrer" target="_blank">YouTube Data API</a> to search and fetch your playlists and subscriptions, but keep in mind that:</p><ul><li><p>It requires you to register a project on the Google Cloud developers console.</p></li><li><p>It doesn’t support <a href="https://docs.platypush.tech/platypush/plugins/youtube.html#platypush.plugins.youtube.YoutubePlugin.get_feed" rel="nofollow noopener noreferrer" target="_blank">the <code>get_feed()</code> action</a> (YouTube has removed the endpoint in v3), so you won’t be able to get the latest videos published by your subscribed channel.</p></li><li><p>All searches and activities will be logged on your Google account, so it’s probably not the best option if you are looking for a privacy-aware experience (but video streaming will still be ad-free).</p></li></ul><strong>State of YouTube media support</strong><p>The <code>youtube</code> plugin should work in tandem with any supported Platypush media integrations (tested with <a href="https://docs.platypush.tech/platypush/plugins/media.mpv.html" rel="nofollow noopener noreferrer" target="_blank"><code>media.mpv</code></a>, <a href="https://docs.platypush.tech/platypush/plugins/media.vlc.html" rel="nofollow noopener noreferrer" target="_blank"><code>media.vlc</code></a>, <a href="https://docs.platypush.tech/platypush/plugins/media.gstreamer.html" rel="nofollow noopener noreferrer" target="_blank"><code>media.gstreamer</code></a>, <a href="https://docs.platypush.tech/platypush/plugins/media.kodi.html" rel="nofollow noopener noreferrer" target="_blank"><code>media.kodi</code></a> and <a href="https://docs.platypush.tech/platypush/plugins/media.chromecast.html" rel="nofollow noopener noreferrer" target="_blank"><code>media.chromecast</code></a>), but <code>media.mpv</code> is recommended. The reason is that <code>mpv</code> provides the <code>--ytdl</code> option out of the box to leverage <code>yt-dlp</code> to download and stream videos on the fly, while other media plugins will have to first download the full video locally before streaming it (I’ve tried to implement my own real-time media streaming server, but I’m still not very happy with its stability).</p><strong>Leveraging the support for multiple backends to migrate your data around</strong><p>I’ve always been baffled by the fact that there isn’t a standard format to export playlists/subscriptions across different backend implementations (even among alternative backends, such as Piped and Invidious).</p><p>As someone who has migrated through different YouTube backends and apps depending on the state of restrictions implemented by Google, I’ve often had to write my own scripts to convert CSV/JSON exports from one platform or app to a format understood by the new solution.</p><p>Since the Platypush <code>youtube</code> plugin exposes the same API regardless of the backend, it is possible to configure multiple backends, and write a small script that fetches all playlists and subscriptions from one and imports them into another:</p><pre><code>from platypush import run
# Get all the playlists from e.g. the Piped backend
piped_playlists = run("youtube.get_playlists", backend="piped")
piped_playlists_with_videos = {
pl["id"]: {
item["id"]
for item in run(
"youtube.get_playlist",
id=pl["id"],
backend="piped"
)
}
for pl in piped_playlists
}
# Create the playlists on Invidious and populate them
for pl in piped_playlists:
invidious_playlist = run(
"youtube.create_playlist",
name=pl["name"],
backend="invidious"
)
run(
"youtube.add_to_playlist",
playlist_id=invidious_playlist["id"],
item_ids=piped_playlists_with_videos[pl["id"]] or [],
backend="invidious"
)</code></pre><p>Note that the simple script above doesn’t handle merge of existing playlists and items, but it can be easily adapted - if there’s enough interest I may write a small blog article with a more complete example.</p><strong>Other release features</strong><p>The full changelog of the new release <a href="https://git.platypush.tech/platypush/platypush/src/branch/master/CHANGELOG.md#1-3-5" rel="nofollow noopener noreferrer" target="_blank">is here</a>. Besides the <code>youtube</code> integration changes, this release includes the following features:</p><ul><li><p>Many stability/performance improvements for the <code>music.mopidy</code> integration - especially in handling connection recoveries.</p></li><li><p>Support for ungrouped lights in the <code>light.hue</code> plugin.</p></li><li><p>Added a new <em>Application</em> tab to the UI, which allows you to monitor all events and requests handled by the service.</p></li><li><p>Adapted <code>ssl</code> layer to Python 3.12 (which has deprecated <code>ssl.wrap_socket()</code>).</p></li><li><p>Migrated the <code>kafka</code> integration to <code>kafka-python-ng</code> instead of <code>kafka</code>, which is currently broken and basically unmaintained.</p></li></ul>