Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HLS support #249

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft

Add HLS support #249

wants to merge 5 commits into from

Conversation

JackBailey
Copy link
Contributor

@JackBailey JackBailey commented Mar 6, 2024

To help mitigate bandwidth limitations and overall provide a better video viewing experience, this PR adds transcoding video + audio to m3u8, and adds the /api/video/stream endpoint to return it.

I've also updated the video-players used on the site to handle this - Previously the VideoModal used the native video element, it now uses ReactPlayer, like the Watch page.

There's a chance it may fix discord embeds, will check soon

Todo before ready to be merged:

  • Default to direct streaming unless admin has changed default mode to transcode via toggle on settings page
  • Setting for enabling or disabling transcoding totally, disable admin option for default video play mode
  • Setting on video players for playback mode?
  • New video uploaded and playback started before transcode done
    • Show video processing page
    • Show original video instead
    • Have an option of this behaviour?
  • Properly test playback on Discord and different devices
  • Option for quality of playback and a default setting? - I like having my clips high res + bitrate if I were to turn it into a video, but for little clips to share with friends it doesn't need much quality
    • Original (still HLS)
    • Low (720p30)
    • Medium (1080p60)
    • Convert beforehand or at start of request? - on-the-go (see below) is probably the only feasible option
      • Look into transcoding each segment of the video on-the-go, for proper transcoding, higher performance requirements but may reduce overall disk usage especially if having multiple quality options
    • Check if ReactPlayer has options for a YouTube-like quality selector beforehand

@ShaneIsrael
Copy link
Owner

My only concern with this is defaulting the videos to the m3u8 conversion. If you add or upload a video, the video player would fail to load the video if the conversion is still happening. The nice thing about direct file stream is that the video is ready immediately, this is especially important for systems that do not have much processing power and may otherwise take a while to convert to m3u8.

I think what I would need to have added for this PR to go through are a couple of things.

  1. The video player should default to direct streaming of the original file unless the administrator has changed the default streaming mode from "direct" to "transcode".
  2. For the above to work, there should be a new setting in the frontend ui that allows the admin to set the default streaming mode. "direct" or "transcode".
  3. Another setting needs to also be added to "enable / disable" video transcoding. There are some users who are not going to want their videos transcoded because it would impact their systems processing too much and they may prefer to only direct stream files.
  4. When visiting a video that isn't yet available because it is still transcoding, i.e the m3u8 file is not available and "direct" stream is not the default mode, there page should show some form of "video is processing" component in place of the video player. Or, potentially the video should load the direct stream version first while the video is still being transcoded.

Some of these settings could probably be added as .env variables, and may actually be more appropriate there. Of course I'm open to suggestions on these points. What I want to make sure of is that adding this feature, doesn't impact those who are relying on direct stream because they are on a low power system or maybe they have the bandwidth and would prefer not to use of their cpu transcoding.

@ShaneIsrael
Copy link
Owner

One last thought, how is this going to handle existing files? Just default to direct stream is there isn't an m3u8 file for older videos? Or a cron job to convert older videos?

@JackBailey
Copy link
Contributor Author

JackBailey commented Mar 6, 2024

Yeah I was thinking of potentially having some options for this behaviour too, new features aren't exactly great if they hinder the experience of other users. All your suggestions seem great, I'll look into adding them.

Conversion is handled alongside poster generation so old videos should be upgraded with a scan.
In the scenario that an old video is attempted to be viewed before a scan is run, I'll just show the processing page or default to the original file.

For conversion, it's just copying the existing (containers?) to a m3u8 format so it should be pretty quick (0.2 seconds on an i5-8400 for a 10 second, 1440p60 50mbps clip), but still I understand about some users not wanting this behaviour or wanting to sacrifice the performance for it (and it'd probably still take a lot longer on a 10GB+ video anyway)

@JackBailey
Copy link
Contributor Author

JackBailey commented Mar 6, 2024

Works with discord embeds (Didn't work for 10 sec or so, and then it worked so potentially discord needs to scan it first before it's fully available), tested with a 10 second, 65MB file, on an account without any nitro.

Edit: Looks like it was still using the original video, trying again with it actually using m3u8

@ShaneIsrael
Copy link
Owner

Yeah I was thinking of potentially having some options for this behaviour too, new features aren't exactly great if they hinder the experience of other users. All your suggestions seem great, I'll look into adding them.

Conversion is handled alongside poster generation so old videos should be upgraded with a scan. In the scenario that an old video is attempted to be viewed before a scan is run, I'll just show the processing page or default to the original file.

For conversion, it's just copying the existing (containers?) to a m3u8 format so it should be pretty quick (0.2 seconds on an i5-8400 for a 10 second, 1440p60 50mbps clip), but still I understand about some users not wanting this behaviour or wanting to sacrifice the performance for it (and it'd probably still take a lot longer on a 10GB+ video anyway)

Yeah I would assume on most systems and videos it should be fine. But you never know how large a video somebody might have or what their circumstances could be. So I'd like to be pretty careful with that. I also think having both options provides a backup in the event that the transcode is not working right or a bug gets introduced. There's at least a fallback option.

Either way, I'm super looking forward to this. Thank you very much for the work put in, sorry if I seem to be making this difficult haha.

@ShaneIsrael
Copy link
Owner

Works with discord embeds (Didn't work for 10 sec or so, and then it worked so potentially discord needs to scan it first before it's fully available), tested with a 10 second, 65MB file, on an account without any nitro.

Interesting, because I believe discord embeds have always worked for me without issue. Here is a screenshot of me testing it right now, maybe try yourself linking one of the videos on https://v.fireshare.net

I think the issue is for people who are not encoding their videos in h264, and maybe using h265 which I imagine discord doesn't support.

image_2024-03-06_09-42-04

@JackBailey
Copy link
Contributor Author

No problem, I completely get it. I've been using fireshare on and off (linked to how inconsistently I get into games) for about 1.5 years now, so I'm happy to contribute something to it :)

@JackBailey
Copy link
Contributor Author

JackBailey commented Mar 6, 2024

Interesting, because I believe discord embeds have always worked for me without issue. Here is a screenshot of me testing it right now, maybe try yourself linking one of the videos on https://v.fireshare.net

I think the issue is for people who are not encoding their videos in h264, and maybe using h265 which I imagine discord doesn't support.

I've had issues with it before,I believe it was if the video was larger than nitro would usually let you upload the video directly, but apparently not. Will see if this improves the experience at all anyway

@ShaneIsrael
Copy link
Owner

Interesting, because I believe discord embeds have always worked for me without issue. Here is a screenshot of me testing it right now, maybe try yourself linking one of the videos on https://v.fireshare.net
I think the issue is for people who are not encoding their videos in h264, and maybe using h265 which I imagine discord doesn't support.

I've had issues with it before,I believe it was if the video was larger than nitro would usually let you upload the video directly, but apparently not. Will see if this improves the experience at all anyway

Yep I am all for improved experiences. I know I've seen some people complain about discord embeds not working which has been difficult for me to nail down because they've always just worked for me. If this helps with that then great!

@JackBailey
Copy link
Contributor Author

I've added a TODO list to my original message, please let me know what you think of it and any additions I've made to the list

@ShaneIsrael
Copy link
Owner

Default to direct streaming unless admin has changed default mode to transcode via toggle on settings page

This is the default behavior I would prefer. 👍 (potentially 3 options if and only if you wanted to add it. The third option could be "auto" or something along those lines which might enable the user the ability to select on the video player?) That could always be something looked into after the fact at a later date.

* [ ]  Setting for enabling or disabling transcoding totally, disable admin option for default video play mode

Yep, this would probably be an env variable that is "true" by default. ENABLE_HLS_TRANSCODING=true if false, disable the admin options in the settings UI. A tooltip if its disabled to notify the admin that they need to enable the env variable to allow for transcoding.

* [ ]  Setting on video players for playback mode?

I'll leave this up to your own discretion. If its simple enough to add and you feel like it then I think allowing the end user the option to choose if they want to watch as direct stream vs transcode would be nice. But I think this option should only be enabled if an admin setting enables it via that 3rd option I mentioned above. "Direct Stream, Transcode, User Decides" etc or something like that. User Decides probably isn't the best name for it but its early morning and I'm still drinking my coffee haha.

* [ ]  New video uploaded and playback started before transcode done
  
  * [ ]  Show video processing page
  * [ ]  Show original video instead
  * [ ]  Have an option of this behaviour?

A default behavior that the admin can set in the settings is probably ideal but I don't expect that to be required for this PR. Without the option, I think "direct stream" should be the default until the transcode file is available, then default to whatever the admin has set.

* [ ]  Properly test playback on Discord and different devices

👍

* [ ]  Option for quality of playback and a default setting? - I like having my clips high res + bitrate if I were to turn it into a video, but for little clips to share with friends it doesn't need much quality
  
  * [ ]  Original (still HLS)
  * [ ]  Low (720p30)
  * [ ]  Medium (1080p60)
  * [ ]  Convert beforehand or at start of request? - on-the-go (see below) is probably the only feasible option

Hmm. I think there should be a default settings, something to high res + bitrate because like you I also prefer quality. I do think 3 options should be available, but maybe that should be a setting the admin can set because it might be rough on the system having it transcode a video into 3 different files.

So what do you think about these for options?

  1. Default - Original (still HLS)
  2. High - high quality, high res + bitrate
  3. Medium
  4. Low
  5. ALL

Where option 5 all would tell the transcode utility to create a file for each quality profile. The user could then select the quality profile if available on the video player?

GPU transcoding would greatly help here. I'm not sure how complicated it would be to pass in your nvidia/amd gpu to the container to be used by ffmpeg. I was at one point experimenting with nvidia nvenc encoder with ffmpeg but didn't make too much progress on it. Thoughts?

    * [ ]  Look into transcoding each segment of the video on-the-go, for proper transcoding, higher performance requirements but may reduce overall disk usage especially if having multiple quality options

Feel free to experiment with this, but definitely not required. Would probably need gpu transcoding to properly handle this.

  * [ ]  Check if ReactPlayer has options for a YouTube-like quality selector beforehand

Definitely think this would be cool especially if we have 4 different quality files created for each video.

@JackBailey
Copy link
Contributor Author

JackBailey commented Apr 3, 2024

Hi, I'm still looking to add this. I've played around with transcoding in realtime for different qualities, I'm not sure if I'll be able to add it due to time and knowledge limits. If you or someone else would like to work on it later, a decent start has been made on it. Alternatively the different quality versions of the videos could be created beforehand, but this would obviously use more space and processing power when uploading the videos.

I'll do the other things in my list, hopefully within the month 👍

@ShaneIsrael
Copy link
Owner

Hi, I'm still looking to add this. I've played around with transcoding in realtime for different qualities, I'm not sure if I'll be able to add it due to time and knowledge limits. If you or someone else would like to work on it later, a decent start has been made on it. Alternatively the different quality versions of the videos could be created beforehand, but this would obviously use more space and processing power when uploading the videos.

I'll do the other things in my list, hopefully within the month 👍

Sure no problem! The project isn't going anywhere, there's no expectation or time limits for open source contributions :)

@7eventy7
Copy link

7eventy7 commented Nov 5, 2024

Any movement on this pull? I'd love to help however I can.

@JackBailey
Copy link
Contributor Author

JackBailey commented Nov 5, 2024

Not really no, I'm not really using fireshare at the moment so it skipped my mind.

I had an initial look at adding a setting for enabling HLS but didn't get very far with it, I've just pushed my WIP code for it -
6aa4135, can't remember how functional it was. You're welcome to look further into it @7eventy7, but its unlikely I'll do much more work on it myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants