jaredpetersen / raspilive

📷 Stream video from the Raspberry Pi Camera Module to the web
MIT License
145 stars 33 forks source link

support lhls option #47

Open willynlabs opened 3 years ago

willynlabs commented 3 years ago

First, thanks for providing this. It has been very useful to help me bootstrap my prototype.

I quickly implemented something, and got it working this morning, but the latency is 10-15 seconds. I tried the tuning you suggested (t=.5, l=24, s=100), but it is still lagging at about this rate.

I came across the -lhls option, which seems to be available as an experimental feature in ffmpeg 4.1, and I am wondering if you have looked at this option.

I am a little confused by the option as I tried to explain here:

https://stackoverflow.com/questions/65459568/confused-about-lhls-in-ffmpeg

I have looked at your server.js code, and I would like to take a stab at implementing this, but only after I clear up the confusion about it. There is also a comment about the 'dash' output not working with a file in this thread:

https://stackoverflow.com/questions/56700705/how-to-enable-lhls-in-ffmpeg-4-1

Which may mean this won't work in any case, or at least not yet.

I was just wondering if you had looked at this experimental option and if it is something you think is worth exploring.

I am available to contribute as well.

Thanks.

jaredpetersen commented 3 years ago

@willynlabs Glad that you have found this project useful!

I haven't been following the recent updates to FFmpeg so I wasn't aware of this new flag. FFmpeg is a monster tool so even finding out good flags to use is a task in itself 😄

Unfortunately, since LHLS is both an experimental flag and the RFC has not been approved I'm very reluctant to add it into the main branch of raspi-live.

That being said, this LHLS feature sounds like a good thing that should be added by default to the HLS streaming option for raspi-live once the RFC and the FFmpeg feature is in better standing. We'd basically just throw it into this list. We'd also want to confirm that raspi-live still works with older versions of FFmpeg that do not have this flag (and if it doesn't, update the README / package version accordingly).

I encourage you to experiment with the feature though on your own cloned repository so that you can try to recognize those performance gains. You'd just add the option to that section of code I linked, uninstall the main raspi-live application if you've already installed it (npm unintall raspi-live -g), and install your modified version (npm install -g).

Both HLS and MPEG-DASH are inherently latent video streaming technologies because they chunk up the video into downloadable segments. I don't think you're ever going to get truly realtime streaming with either technology. RTMP is a possible contender to reduce that latency but it has its own can of worms.

Thanks for bringing this to my attention! I'll keep this open so that we can remember to keep checking in.

willynlabs commented 3 years ago

@jaredpetersen thanks for the response.

I probably sent this question prematurely. I did a deep dive on the -lhls support in FFmpeg, and discovered that it was based on an early spec put forth by the folks behind hls.js (more on that later). I learned from another thread that this has now been replaced by the Apple spec, which uses a different output token in the m3u8 file(s).

The old flag was actually implemented in the dash encoder and required additional options to output the m3u8 files in parallel with the dash files. There was a pretty big 'gotcha' with that because you could not use the file protocol, but had to use an url protocol (with the -method option) instead.

I prototyped all of this by invoking FFmpeg from the command line directly, but found it really did not produce that much less latency than just tuning the original parameters.

I wound up using hls.js and the dash encoder with the -hls_playlist option, and got my latency down to about 1-2sec. hls.js does a good job of keeping the video updated on a 'live' stream, and it is even a bit better than the 'native' hls support on Safari.

(My application involves a camera mounted on a pan-tilt assembly, and I want to control in remotely for construction inspection. Target latency is 1-2 sec so it feels responsive.)

I am thinking about how to make the various command options in raspi live more extensible, and I did notice your issue related to 'refactoring' and the option of removing the cli module. Seems like that might be the way to go.