flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
164.2k stars 27.09k forks source link

Support for HLS on desktop browsers for video_player_web #53011

Open nstrelow opened 4 years ago

nstrelow commented 4 years ago

Use case

I have a HLS stream and I want to built an app which works on both mobile and web.

Currently there is no browser support for HLS on desktop browsers. (Except legacy Edge 🙈) https://caniuse.com/#feat=http-live-streaming

Proposal

Is there a possibility to include HLS support as part of the package?

In Javascript https://github.com/video-dev/hls.js/ is used a lot to add the compatibility.

yjbanov commented 4 years ago

/cc @ditman

ditman commented 4 years ago

HLS is being replaced by Dynamic Adaptive Streaming over HTTP (aka MPEG-DASH)

Should we add a technology that is being phased out to a new framework?

(Also requested here: https://github.com/flutter/flutter/issues/46778)

ditman commented 4 years ago

(Maybe this is more appropriate for a hls_video_player plugin? There seems to be one?)

ditman commented 4 years ago

Let me take a look at the video player plugin, we may be able to let the web decide what to do, depending on the info passed to the player (formats and stuff).

hls.js looks fairly straightforward to use, we'd just need a JS Interop layer in Dart to use the library.

nstrelow commented 4 years ago

Ah I wasn't aware that HLS was phased out. A lot of livestreams seem to use it though. It's very interesting that all those webplayers rely on hls.js or their own implementation, since desktop chrome/firefox have no support.

A plugin onto of video_player is probably also good option. Let me know if I can help in any way. If including it into video_player is not an option, I could look into creating a plugin. Already played around with hls.js JS Interop in video_player_web, creating just a bare workaround.

ditman commented 4 years ago

@nstrelow I'm not sure hls.js should be "mandatory" in the web plugin for two reasons:

We probably should either:

  1. Add an extension point to the current _web plugin so it can accept different players, and then provide a player that is backed by HLS.js, or
  2. Since the video_player plugin is now federated, a new package: hls_video_player_web or similar, could be created. And it'd be a version of the video player that plays HLS. Note that hls_video_player_web doesn't need to be inside flutter/plugins to be usable by others, and we can link from the official video_player_web README or similar to that implementation "if you need HLS".

Your workarounds in video_player_web are probably a very good start for option 2, without having to wait for option 1. Those workarounds, in fact, would be very useful to inform the requirements for what would be needed to be done for option 1 as well, if we decide to do that.

_(Another outcome may be that we end up saying: now @nstrelow owns the official version of video_player for the web platform :P)_

nstrelow commented 4 years ago

@ditman I agree, HLS is probably not a big use case and should not clutter the official package. Not 100% sure how 1. works. Similarly to how video_player uses video_player_web depending on platform?

Do you have some pointers on how to best work with JS Interop? I had problems, specifically:

  1. Correctly defining the hls.on function for JS Interop (IIRC throws expected 1 arg, even though it needs 3)
  2. Including/Loading the hls.js without using a CDN in index.html

Thanks a lot for the quick responses 😁

ditman commented 4 years ago

@nstrelow I was only speculating when I mentioned option "1", but what I was thinking of, was some change in the API of video_player_web to let you inject a player (web only), so imagine something like:

if (kIsWeb) {
  VideoPlayerPlatform.instance.setVideoPlayer(MyHlsVideoPlayerComponent());
}

Of course, there's probably a ton of stuff to do to get that done, I haven't really looked at the code to see how easy/complex would that change be :)

Correctly defining the hls.on function for JS Interop

For JS Interop, you may want to take a look at Dart's js_facade_gen script. It tries to grab a .d.ts file (like this one) and attempts to convert it into a valid Dart JS Facade (I used it for the google_sign_in plugin and it was great; then tried to use it for maps and... not so great :P).

I haven't seen your JS Interop "on" function, but it looks like it should be some sort of void on(String event, Function handler); inside your Hls class? The handler is maybe too broad, so you'd need to typedef something more specific (check the .d.ts above or the API docs to find out what!)

Including/Loading the hls.js without using a CDN in index.html

For 2, it might be doable to place the hls.js file as an asset of the flutter app, and include it from assets/the_right_path/hls.js, but I haven't tried that yet. In any case, you can do whatever postprocessing you want on your build/web before publishing to ensure you place the hls.js wherever you need it. For now, I wouldn't bother too much with that. If you get this working with hls.js working from a CDN it'd be a huge win already.

ditman commented 4 years ago

Hey @nstrelow did you manage to do any progress on this? Do you need help?

nstrelow commented 4 years ago

Hey thanks for checking back. I put some more hours in, but wasn't able to produce something working with the JS interop. The js_facade_gen is pretty nice, but not 100% perfect. Ended up copying the definition of the functions needed for Hls support.

I'll update this with a repo with my (probably not helpful) code.

nstrelow commented 4 years ago

Here are my code snippets. "Hls supported" is printed twice in my browser console. Nothing is further logged, so either attachMedia or on is not working correctly.

Hls event handling is done by https://github.com/primus/eventemitter3, not sure if this matters.

I was able to get it working by defining my own hls setup function in javascript (browser) and then calling that function with videoElement. Literally putting code in Githubissues.

  • Githubissues is a development platform for aggregating issues.