top | item 18939145

Show HN: HTML5 Video Player in TypeScript

151 points| matvp | 7 years ago |github.com

53 comments

order
[+] Ambroos|7 years ago|reply
Some extra background: I worked on a predecessor of this with Matthias about two years back. We had to build a web video player with a lot of advanced capabilities, and found that no open source or commercial player framework would give us what we needed as developers to deliver something really good. I've since moved abroad and haven't been involved with this directly.

A lot of the ideas we came up with made it into this project, and what Matthias did differently in this iteration (like adding Typescript and improving how you write extensions) look really good. You can consider this to be an alternative to video.js, for example, but with easier ways to build advanced extensions without having to fall back to pretty oldschool ways of doing JS.

Matthias' default UI for example is built in React, but there's nothing stopping you from not using his UI extension and building your own that works however you want. Because of the heavy use of Webpack bundle splitting, if you don't use the built-in UI React won't even be loaded, and that approach is core to how this is designed.

[+] matvp|7 years ago|reply
You're more than welcome to contribute! Good ol' days!
[+] mig4ng|7 years ago|reply
Amazing job, I have a few suggestions on how to improve its UX:

- Clicking the video should pause/play;

- Clicking the volume button on mobile when the volume bar is hidden should not mute the video, instead it should just show the volume bar;

- Interacting with the volume UI on mobile should reset the time until the UI hides, the UI hides while I'm ajusting the volume.

These are a few points I think should be improved, I'd love to hear others opinions on whether or not these make sense :)

Keep the great work!

[+] matvp|7 years ago|reply
Thanks for the suggestions!

1. Absolutely, it's on my radar.

2 & 3. According to me, the volume button seems off in mobile. I think I'll remove it completely on mobile devices, people are used to lowering the volume with the physical buttons (assumption). What do you think?

[+] btbuildem|7 years ago|reply
How is this preferable to using the <video> tag?
[+] Ambroos|7 years ago|reply
If all you want to do is play a simple unencrypted video without ads, a <video> tag is indeed all you need. As soon as you start working with adaptive streaming (DASH/HLS), need ads, need a more advanced UI or need better metrics, you'll need some sort of base video player 'framework' to deal with those things. This provides that, similar to video-js, but in a more modern way.
[+] colde|7 years ago|reply
The <video> tag for instance doesn't support MPEG-DASH and HLS (outside of Edge and Safari). So if you want to do DRM or live streaming, that isn't supported. Thats why this project bundles shaka-player and hls.js
[+] junetic|7 years ago|reply
Video newbie question here. Is it just me or is the html5 video player is really slow? Does using a framework like this help with performance/buffering/streaming? Like skipping video is a common use-case where performance is really key..
[+] melcor|7 years ago|reply
Looks pretty good, at first glance I miss the functionality to pause/un-pause by clicking on the video. I believe this is a pretty common functionality that you should consider implementing.
[+] matvp|7 years ago|reply
Hey, thanks! You're totally right, I have some time during the weekend to implement this.
[+] hawski|7 years ago|reply
One thing that I would love to have on mobile is an adaptive (?) video seeking. So you touch the "video cursor" and then move: the x axis is for seeking, but y axis is for sensitivity. Moving a finger along the bar (y = 0) is as things are currently - go to the right edge to seek till the end of the video. However moving it along the top edge of the video (y = 720) would only seek in terms of 5 seconds for example.

The scale between y=0 and y=720 wouldn't have to be linear.

[+] callalex|7 years ago|reply
You would get this for free if people would stop reinventing the wheel and let the platform handle the video playback interface.
[+] donut2d|7 years ago|reply
If I'm understanding you correctly, that's how iOS's native video player works.
[+] kohanz|7 years ago|reply
Nice work! As someone that uses https://github.com/sampotts/plyr in one of my projects (and react-plyr), what are the main differences between the two players & designs?
[+] Ambroos|7 years ago|reply
Plyr is really good and has an impressive UI and accessibility. But there is no way extend the player with new complex functionality or a tighter integration with Shaka/hls.js/other ad providers/...

I think Plyr can be seen as a better and unified UI on top of a <video> element, while this is an extensible player 'framework'.

[+] matvp|7 years ago|reply
I can't speak for plyr as I am not familiar with their project. What I like about indigo is the way modules are structured, the initial file (indigo-player.js) loads the needed code in order to provide playback, it's basically a mono repo. I've spent a fair amount of time on state management too, meaning you have a well defined & standardized API no matter whether you play DASH/HLS or use FreeWheel / Google IMA ads.

Edit: the state interface can be found here: https://github.com/matvp91/indigo-player/blob/master/src/ext...

[+] flixic|7 years ago|reply
Really nice UI. Simple, neutral and sharp.

In addition to other feedback in this thread, I'd also want the Volume icon to change: show muted state / volume level state without showing the slider. YouTube does this well.

[+] matvp|7 years ago|reply
Thanks for the feedback, this small feature was already part of my roadmap. :) Will hit production soon!
[+] matvp|7 years ago|reply
I've added different volume icons based on the current volume, shall hit production anytime!
[+] VikingCoder|7 years ago|reply
Your example doesn't actually have an element with id "player" in it, even though you getElementById('player'). Is that a broken example, or am I missing something?
[+] matvp|7 years ago|reply
I'm sorry, it was wrong on the Github page, fixed.
[+] colde|7 years ago|reply
Why not use something like video.js which already has a number of pluggable backend and third party plugins supported. Just for the lack of TypeScript?
[+] Ambroos|7 years ago|reply
The way plugins/backends work in this is fundamentally different. Video.js at it's core does very little and doesn't provide a very strict API. The result tends to be that every ad provider you add on does things slightly differently. If you want to build advanced metrics on top of a video.js instance that can use two different ad providers, it's likely you'll have to manually fix up the ad events to make them track correctly. This project includes base API definitions for all important ad events that other extensions can hook into with set guarantees on how they'll behave.

Another thing is how extensions are dealt with here. In video.js, if you need DASH support, you'll add videojs-contrib-dash and dash.js. Together that's at least 500kB of JS extra. Even in Safari where you won't need any of those, you'll have to do some hacking to avoid loading that JS for no reason. In Indigo here, dynamic bundle loading is core to the extension setup. When reading a config there's a lightweight check to determine what library to use for playback (if one is needed at all), and it'll only be loaded when it's necessary. In Safari, where you generally don't need any libraries, nothing will be loaded. In Chrome, you'll load Shaka when you want to play DASH, and hls.js when you want to player HLS. Indigo makes that very easy (and a default), video.js makes it hard.

These are advanced problems though. You're not likely to hit these issues with video.js if all you do is play a simple stream without DRM and with one single ad provider. But the solutions to those issues that are a core part of this project actually provide benefits in all situations and make development easier, so it's a net win for everyone in the end.

[+] vernie|7 years ago|reply
When will we move on from Big Buck Bunny?