Playlet February 2026 Update #827
iBicha
announced in
Announcements
Replies: 1 comment
-
|
Another related update: #229 (comment) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I've been doing less and less feature development and releases recently with Playlet.
This is because I've been busy rewriting Playlet from the ground up. For the second time (yes, I've done this before)
NB: this is not written by AI.
The progress
I just want to not get anyone wondering when this will be released: I just got started, so this is a big project that will take at least a few months. I think realistically, this could be sometime in the summer or end of summer of 2026. Until then, here's some sneak peak screenshots.
The goal
The goal of Playlet remains the same, but summarized in two points: being able to find content you want to watch, and being able to watch.
If there's a feature that you want to see in Playlet, and is not present in the https://github.com/iBicha/playlet/issues , now is the time to ask, so I can have time to think about it.
Finding content
One of the main asks of Playlet's users was integration with YouTube's account, curated feeds, and recommendation system.
Most people I interacted with didn't care about privacy, because those who did care, they already had Invidious to cover that area.
Most people (and if this doesn't apply to you, that's ok, I said most, not all) have very simple ask: being able to browse videos intuitively, and playing videos without ads or interruptions. That's sums it up.
A while back I figured that if I added support to cast videos, most people would have this need fulfilled. Turns out, while casting is a widely used feature (just from feedback) not everyone wants to hold their phone while watching YouTube. Some people like exploring content and watching it on the same screen.
With that in mind, this rewrite will try to expose more of the curated feeds from YouTube into Playlet, and bring the experience closer to the official TV app.
I'm still working through (and evaluating) how Playlet specific features (such as Bookmarks) integrate into the new design, as well as taking inspirations from other apps, such as SmartTube. For example, being able to pin/bookmark a channel to the nav bar is a nice addition, and will probably come to Playlet at some point.
Watching content
This one is simple in theory, but complex in implementation. Playlet will need to support certain features, such as PoTokens - aka Proof-Of-Origin tokens - , and SABR streaming - aka Server-side Adaptive Bitrate streaming. This is probably the only way to make sure there are less playback errors than the state of this today. This requires lots of engineering work, a beefier server, and client code that could be too CPU heavy for the cheap Roku devices they are.
Additionally, the UI of the Player will need a complete overhaul, in order to allow for all the features requested, such as showing description, comments, finding what to watch next, playback controls (play next, previous, captions, playback speed, etc)
I admit all of this work needs to be done, but at the time of writing, I made zero progress on this part.
What I'm trying to fix
Brighterscript v1
Playlet is being rewritten using brighterscript v1 alpha, which introduces typed interfaces. This is a great to capture bugs at compile time. Additionally, I will be investing a bit more time into unit and integration tests.
Performance considerations
Things are being written to consider the amount of compute vs memory needed. For example, in the new design, screens will be closed when you navigate away, instead of just become hidden, to prevent memory hogging. Additionally, screens showing content shouldn't immediately refresh if the user changes (login/logout), only if the a screen has focus. This prevents doing compute prematurely, and show perform better.
Finally, new async pattern is established, reducing (but not completely eliminating) the amount of rendezvous needed, and make race conditions less likely to occur. For example, if a user trying to load a screen, the task for loading the screen should wait for a dependency task to refresh an access token.
Node dependencies
In the new version, I'm simplifying how components depend on each other. I'm removing the custom plugins that allows to declaratively link nodes together, and use simpler patterns instead.
Screen management
Screen management is also being redone, to allow certain screens to be both a root screen (can be opened from the navbar) and a pop-up screen. This allows the search page to be shown on top of another screen for example. This is possible where the home screen have buttons that navigate to the search screen, or navigate to the login screen.
UI/UX changes
Certain UX changes are being done to be more consistent with what to expect from a YouTube-like app, and from Roku app.
For example, it makes more sense for context menus to show up by using the Options(*) button instead of long press OK button.
Additionally, I'm evaluating the possibility of using icon fonts, instead of pngs generated from SVGs. This makes icons more crisp while keeping video memory required to a minimum. This is because Roku uses SDF fonts. And since YouTube TV app also uses fonts to display icons, it becomes possible to display icons similar to the official app (you can spot this in the screenshots, in case you missed it)
Finally, I'm evaluating if Playlet can be designed in FHD resolution. Playlet is currently designed in HD (1280x720) and scales up in higher resolutions. This is tricky to achieve without breaking existing version, but we'll see how to go about this. This is also a lot of work since every single ui item size and position needs to be readjusted.
Error management
I'm reworking error management to make it a bit more consistent across the code, and to make it possible for me to capture critical issues through anonymous telemetry.
Splitting Innertube and Invidious backends
When I first started Playlet, I discovered Innertube, YouTube's API that returns basically everything you see on screen when watching YouTube. It's a complicated, over-engineered beast that got out of hand as YouTube kept adding features over the years.
I found that Invidious did a great job abstracting away the complexity, and allowed for a developer friendly API to fetch info a show it on screen. The dozens of public servers was also a bonus, it meant non-tech-savy users that didn't know how to host a server were not excluded.
As I dug into Innertube more and more (especially when no public instances were left, at least ones with public API enabled I started to form an opinion on the parser approach of Invidious (and few similar projects even) and what I wanted for Playlet.
Innertube by design, has a built-in layout system. It means, you tell it which platform you're on, device, language, profile, etc, and it will return the layout to display.
For example, YouTube might not always return the length of videos as a dedicated field in the response, but might tell you to show "3:25" as an overlay in the bottom right corner of the thumbnail. Or it could be other text, like "LIVE", "SHORTS", "UPCOMING", "MIX", "6 SONGS", or any other arbitrary text.
Invidious attempts to parse this text, and extract meaning from it. It does this with few other things, which means it has major limitations unfortunately, such as sticking with only English, and also often be subject to breakage when text changes.
By trying to display content similar to how YouTube wants to show it, things render correctly more often, and break less frequently.
This is how Playlet can show things like "2800 watching now" under live videos for example. Because Playlet simply tries to display whatever Innertube returns, as close as it reasonably can.
Playlet was built entirely on how Invidious did things, and when Innertube was added, it was clear that the abstraction didn't work.
For example, users were asking for recommended videos for their profile. But Invidious didn't have an endpoint for that.
So what I did was adding a query param to the "popular" videos endpoint
/api/v1/popular?recommended=true, and when people used playlet backend, that returned recommended videos. On Invidious, the backend would ignore therecommendedparam, and just returned popular videos on the server. This was the simplest way I could add a feature on an abstraction that didn't support it. This also means/api/v1/popularis now considered authenticated in some context, and unauthenticated in another.Do you see the mess this created? This was spread out into the entire code base, abstractions that didn't fit together, but were forced, limiting what I can implement as features, and making it very easy to break abstractions since everything is so brittle.
Instead, Playlet now defines the abstractions, and backends (Innertube and Invidious) implement them. This way, features can be added consistently, and backends remain decoupled for the most part. For example, Playlet has a "Movies" screen, but it doesn't mean both backends have to support it. This is what Invidious would show on the "Movies" screen:
This means it's possible to to implement features such as curated/recommended videos from YouTube without an account (Watch as guest) - As you watch videos, YouTube would recommend videos - among other features
Rework web server
Another thing I'm moving away from is an Innertube backend that implements the Invidious APIs. First, hitting localhost endpoint incurs additional compute and memory usage that is not needed (data copied, sockets created, etc). Second, sockets in Roku can't cross thread boundary, so I'm stuck with a single thread for the web server. I would prefer that web server only does work that can't be achieved otherwise, such as serving DASH to the player, or serving content to the web app. This will have good performance benefits.
Features removed
With this change, certain features might be removed.
For example, there's a whole screen that displays public invidious servers. That will probably go away.
Another thing that Playlet did was "patch up" things to cover for an Invidious bug or missing feature.
For example, Watch History does not show titles of Videos. Invidious doesn't store all metadata of videos in watch history, but only video ids in the database. This means we either display only the thumbnails, or make an Innertube call to fetch video titles, channel names, durations, etc. Playlet currently does the former, for convenience, but arguably it shouldn't. First, it's because Invidious' front end shows only thumbnails in watch history. Second, if someone is using Invidious on Playlet, it means they care about privacy enough that they probably don't want Playlet talking to Innertube. So, these are the reasons why this feature is probably going to be removed. The argument is that if we want titles to show for watch history, then we can implement this in Invidious, then both front ends would have the same capability consistently.
To be clear, I'm removing features in the cases where it makes sense or where it might be necessary. Nothing is written in stone.
What's next
I've sunk enough time into this project that I want to see it through. It will take a while, and in the meantime I will try to limit the time I spend on current version of Playlet, unless something is simple and quick to fix, or something very critical that requires immediate attention.
The stats seem stable, people streaming about 20k hours of videos per day, even though there's still trouble with certain videos, and even live videos.
Also keeping an eye on the server for running url decipher with javascript, which seems to be stable

(PS: the 4xx errors are mostly the backend rejecting telemetry events, since I currently don't have the time to monitor for errors as I dedicate more time to the rewrite)
Beta Was this translation helpful? Give feedback.
All reactions