HNHacker News
TopNewBestAskShowJobs

rahim_alwer

67 karma · joined July 6, 2019

submissionscomments
rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
This is such an elegant summary of why WCs are painful. I wish I had summarized it so well. I'm on the Video.js team and I wrote about my journey on this front as well [1].

[1]: https://www.mux.com/blog/6-years-building-video-players-9-bi...

rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
Hey there, I'm on the Video.js team! Sounds like your context provider approach is already in the right ballpark!

Some background: our store[1] which was inspired by Zustand[2] is created and passed down via context too. This is the central state management piece of our library and where we imagine most devs will build on for extending and customizing to their needs.

Updates are handled via simple store actions like `store.play()`, `store.setVolume(10)`, etc. Those actions are generally called in response to DOM events.

On the events side of things, rather than registering event listeners directly, in v10 you'd subscribe to the store instead. Something like `store.subscribe(callback)`, or in React you'd use our `usePlayer`[3] hook. The store is the single source of truth, so rather than listening to the underlying media element directly, you're observing state changes.

---

So far with v10 we haven't been thinking about "plugins" in the traditional sense either. If I had to guess at what it would look like, it'd be three things:

1. Custom store slices[4] so plugins can extend the store with their own state and actions

2. A middleware layer that plugs into the store's action pipeline so a plugin could intercept or react to actions before or after they're applied, similiar to Zustand middleware, or even in some ways like Video.js v8 middleware[5]

3. UI components that plugins can ship which use our core primitives for accessing the store, subscribing to state, etc.

I believe that'd cover the vast majority of what plugins needed in v8. We haven't nailed down the exact API yet but that's the direction we're leaning towards. We're still actively working on both the library and our docs so I don't have somewhere I can link to for these just yet (sadly)! We're likely targeting sooner, but GA (end of June) is the deadline.

I should also add... one thing we prototyped early on that may return: tracking end-to-end requests through the store. A DOM event triggers a store action like play, which calls `video.play()`, which then waits for the media event response (play, error, etc.). It worked really well and lines up nicely with the middleware direction.

[1]: https://github.com/videojs/v10/tree/main/packages/store

[2]: https://github.com/pmndrs/zustand

[3]: https://videojs.org/docs/framework/react/reference/use-playe...

[4]: https://zustand.docs.pmnd.rs/learn/guides/slices-pattern#sli...

[5]: https://legacy.videojs.org/guides/middleware/

rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
I have that ticketed up for you [1], and I'll look into it tomorrow. Thank you!

[1]: https://github.com/videojs/v10/issues/1120

rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
Hey there, on the Video.js team. What browser and version did you run into this on?
rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
It’s largely because (1) the React runtime is not bundled so it’s technically not apples to apples, (2) the Web Component includes CSS as well since we’re using Shadow DOM.

Basically few kB for CSS and few kB for a thin “framework” layer for managing attr to prop mapping, simple lifecycle, context, and so on.

rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
We are designing with the goal of supporting more frameworks like Svelte and Vue specifically, even as far as React Native! We just don’t know when exactly yet but a large part of our approach in v10 is to make sure we can deliver the best possible experience to each frontend framework. It’s important for us that the integrations don’t feel like wrappers but truly idiomatic.

In the meantime, we’re hoping our custom elements will act as a good stopgap. Most frameworks including Svelte support them well, and we’re pouring love into the APIs so they feel good to use regardless of which framework.

If you’re interested in peeking under the hood, architecturally we’re taking a similar approach to TanStack and separating out a shared core from the beginning, but with one added step of splitting out the DOM as well to aid in supporting RN one day.

rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
Thank you!
rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
Awesome to hear!
rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
I'm on the Video.js team, just wanted to say thank you! Means a lot and we'd be eager to hear your experience trying it out. Feel free to drop a GitHub issue or discussion post if you ever get a chance :)
rahim_alwer··on Show HN: I took back Video.js after 16 years and we rewrote it to be 88% smaller
Thank you! I’m on the Video.js team, and we’d love for you to try the library out and share your feedback. We’re especially eager to hear from developers who used or tried v8 in the past.

We’re taking a new approach to the library with a lot of new concepts, so your feedback would help us a ton during Beta as we figure out what’s working well and what isn’t.

rahim_alwer··on Show HN: Modern media captions parsing and rendering library (vtt/srt/ssa)
Hey everyone!

The motivation for this started with some initial exploration of how native captions are inconcistent and extremely limited with respect to positioning + styling across browsers. In addtion, existing captions work was glued inside player libs and all open-source parsers were ancient (e.g., mozilla/vtt)!

I wanted to modernize it all with newer web APIs such as `fetch` and `ReadableStream` and extend support out to multiple captions formats. I also noticed that a lot of popular players on the web in recent years started adding caption customization options. Turns out accessible captions can be legally enforced!

Do note that accessible captions not only includes sync/timing, but also an adequate set of controls to customize the style of the captions, ensuring they're readable for everyone. You can see an example of this on YouTube when you go to the settings, captions, and click customize.

It just seemed silly that probably every single company is internally building this type of lib which is insanely hard to get right. I built this to serve our accessiblity goals at Vidstack[1] where we're working on enabling you to build a production-ready player quickly.

It took me about two weeks to build this and honestly there's still a lot of areas that need work but it's a great start. I hope you find it useful. You'll find a lot more helpful information in the repo.

I'll also leave you with this YouTube video where Dan Sparacio beautifully explains the complexities of building accessible media captions on the web at Paramount [2]. This is one of my favourite Demuxed talks. In there case, acessible enough to meet FCC guidelines. _Highly_ recommend checking it out to learn more!

[1]: https://github.com/vidstack/player

[2]: https://www.youtube.com/watch?v=Z0HqYQqdErE

rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
You're 100% right and I realized a little after writing it. Added `$root` to the library :)
rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
Thanks for all the feedback, love it!

> I don't entirely understand what it means to dispose of observables, is that just an internal optimization for cleanups basically? Exposing an API for this feels a bit risky, like it feels easy to misuse.

It's a cleanup function that ensures that the observable can be garbage collected by clearing references to it in the dependency sets. It also marks the observable as disposed so that it's no longer reactive and ensures no new references can be made. I think brundolf gave a really good use-case for this API but you're right people can and will definitely misuse it... ¯\_(ツ)_/¯

> I personally prefer to opt into batching only sparingly and for performance reasons.

I'll definitely look at providing an API to provide a custom scheduler. I have to be careful not to bump up size in doing so _might_ be tricky.

> A function for creating roots seems missing, I think that's important.

I don't think it's needed here because it can be created with an `$effect`. It returns a `stop` function that can be called with `true` to dispose of all inner computations. I think I should provide a `$root` function that's just sugar for the mentioned.

> "isComputed" feels like a weird function to have

Ye I agree. I'll remove it and expose `isObservable` and `isReadonly` functions.

> I've made something similar myself, also inspired by Solid and Sinuous...

`oby` is super cool. It's so feature packed that it's going to take some time to dig through all of it. I love finding libraries like these, thanks for sharing it.

rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
Thanks damsta!
rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
Thanks for sharing that, I just put together one [0] but hard to extract meaningful data without running at least an average across X (~1k?) attempts. Nonetheless, it seems to perform extremely well based on surface metrics.

[0]: https://codesandbox.io/s/maverick-js-observables-bench-cellx...

rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
Thanks and love the feedback. I know the dev space is full of cliche and overused terms. It's tough to not use them even when you're aware. I don't see it as a hard rule to avoid them and I think in some cases it's okay.

For example, if the core goal of the library is to achieve <2kB and you've predetermined a tight API scope (most likely based on existing references) then IMO it's okay to call it tiny/lightweight. It works out with libraries that are a providing a set of primitives to solve a generalized problem. I'm sure some people appreciate like I do when a library clearly indicates a core goal that was achieved (i.e. size) right in the top-level description.

rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
I started with that but then I thought about what if a callback or some other function is stored as an observable (i.e., like `useCallback`). Also, as fabiospampinato mentioned it's a cleaner seperation of get/set which makes it much easier to differentiate at a quick glace. You can't easily mess it up. I'm still debating whether to achieve what you're after. Maybe I have something mentally twisted and it's easier than I think.
rahim_alwer··on Show HN: A tiny and fast reactive observables library via functions
Hey everyone! I put together a functional reactivity library that uses observable functions as it's primitive for tracking state and changes. It's super tiny (850B), fast, only re-computes the dirty parts of a computation tree, batches updates via a scheduler on to the microtask queue, and works in both browsers and Node. Love any feedback :)
rahim_alwer··on Show HN: Media Player Library – Supports Html5, Hls, Dash, YouTube and More
Built this library out of frustration from trying to use Videojs and Plyr for one my projects.

For anyone curious the reasons are listed here -> https://github.com/vime-js/vime#motivation.

If you're looking for multi-provider support, plugins, custom controls and other goodies then this might be for you. It's not perfect but it feels stable enough to share. If you guys end up using it then please share your experiences so I can learn how to improve the library.

Cheers!