UnicornTranscoder / UnicornFFMPEG

Fake Plex Transcoder to get the arguments for FFMPEG
MIT License
97 stars 14 forks source link

Abillity to modify plex client ffmpeg arguments #11

Open FCLC opened 3 years ago

FCLC commented 3 years ago

Hi team,

Unless I've missed something from the documentation- I don't see a way to modify/append arguments captured from UnicornFFMPEG before they're sent to the transcoder. the reason I ask is that this could be a vector to add in support for different HWAccels that are platform dependent, say AMF encoding, openCL etc.

If I've missed something let me know!

-FCLC

Maxou44 commented 3 years ago

In this case, we recommend to patch the ffmpeg args on the UnicornTranscoder side (just before running it)

Hardware transcode will be hard to add, more info available on this issue: https://github.com/UnicornTranscoder/UnicornTranscoder/issues/24

FCLC commented 3 years ago

Hi @Maxou44

if my understanding is correct this is the current flow, and the new flow is below.

flow as designed by unicorn transcoder

plex client that cannot direct play FILE request transcode from server

UnicornLB intercepts request and sends to host system of UnicornTranscoder

Unicorn Transcoder repeats request from the initial client and sends to plex server.

Plex Server calls Plex Transcoder; the transcoder has been replaced by UnicornFFMPEG

Unicorn FFmpeg sends the arguments to Unicorn Loadbalancer

UnicornLoadBalancer sends request to UnicornTranscoder which then requests arguments from UnicornLoadBalancer

Unicorn Transcoder then serves the requested stream

Changes and new flow

/ before going live: create list that contains transcode capabilities of each relevant server (HEVC, h264, 4k 1080p, 24 30-60-120fps? /

Plex client that cannot direct play FILE request transcode from server

UnicornLB intercepts request and sends to host system of UnicornTranscoder

Unicorn Transcoder repeats request from the initial client and sends to plex server.

Plex Server calls Plex Transcoder; the transcoder has been replaced by UnicornFFMPEG

change from standard

Unicorn FFMPEG Sends arguments to custom script.

Custom script thens send the file to the apropriate system

Unicorn FFmpeg sends the arguments to Unicorn Loadbalancer

Custom scrips detects file requirments, and allocates resources based on most appropriate available server

UnicornLoadBalancer sends request to UnicornTranscoder which then requests arguments from UnicornLoadBalancer

Unicorn Transcoder then serves the requested stream

Specific change in source of UnicornTranscoder

change area: change args in section //get args line 36-92 is relevant section

FCLC commented 3 years ago

Also, for what it's worth I'm a C and VHDL dev, haven't done a ton of Node in the past.

But I assume that you could do something like a case statement of presets? so we would look for any instance of

-c:v libx264 -b:v {requested bitrate} -maxrate {if requested} -bufsize 1M

to

-c:v {relevant HW accel from host platform in codec requested [hevc, h264, VP9 av1 etc.]} -b:v {requested bitrate} -maxrate {if requested} -bufsize 1M

FCLC commented 3 years ago

Continuing to dig into how to make this work- I see that on lines 43-46 we're already doing a codec substitution on the string that will be sent to ffmpeg due to a problem with the aac_lc audio codec

// Hack to replace aac_lc by aac because FFMPEG don't recognise the codec aac_lc
if (arg === 'aac_lc')
                            return 'aac';

Unless I'm misreading this, could we not search for specific string such as

'ffmpeg' to 'ffmpeg 'vaapi' -hwaccel_output_format vaapi'

and then

'-c:v libx264' to '-c:v hevc_vaapi'

FCLC commented 3 years ago

Hi @Maxou44, just realized I'd forgotten to tag you in the response, mind sharing your thoughts on the above when you have a moment?

Maxou44 commented 3 years ago

We don't generate the ffmpeg args, we just patch args sent by Plex Media Server. It's possible to support HW transcoding but:

It's not simple to support and I don't have a lot of hardware to test

FCLC commented 3 years ago

Hey mate! apologies for the delay in replying- working on another portion of my project. (BTW Francais?)

We don't generate the ffmpeg args, we just patch args sent by Plex Media Server.

The approach I'm thinking of using as a proof of concept is the use the same argument patching as mentioned above.

Digging into the src for the load balancer, I wonder if it might be possible to add a config parameter for what acceleration/features are available for each transcode node. This should be something we can parse as an option/field just like max number of sessions and other "per node" configuration options. Thoughts?