FYI, Channels offers hardware transcoding on the Pi 4.
@jerome_oflaherty_icloud_com After investigating the options I basically implemented your suggestion as DIY: https://github.com/ForsakenNGS/raspi-plex-transcode
It already works with h264_v4l2m2m, but that did not improve performance as much as I would have hoped. Maybe h264_omx works better, but I did not manage to get that working yet.
Also the helper script allows to adjust the buffer size and segment length used by the transcoder. Basically you could change every parameter you want by adjusting the provided script. I will test around in the next few days to find the best possible settings with the available ffmpeg source of plex.
Everyone with the time and knowledge is obviously invited to contribute 
Please DONāT do that!
Use the latest version.
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
As plex is using a branched version x.xx.xx?? of there own doingā¦
Fantastic work @jen83 - I must give this a go at the weekend - I will need to try it on a separate instance first - I would not be the most popular in my house if Plex was broken for a few hours
Unfortunally using the stock version of ffmpeg wonāt work. Plex relies on features that are not present in the mainline ffmpeg version. There are the following options:
- Use the original āPlex Transcoderā binary with a wrapper script to change settings (I skipped that)
- Compile the original āPlex Transcoderā source code with a custom configuration and change the settings via wrapper to take advantage of the additional features/encoders (this is what I am doing now)
- Cherry-Pick improvements from the mainline ffmpeg-branch and patch them into the plex version
- Completely merge the current ffmpeg version of plex with the latest version of the mainline ffmpeg-branch
Obviously the last option would be the best, but I personally am not familiar enough with the ffmpeg source code and the plex changes in order to properly merge the changes. (I tried
)
PS: The source code I obtained from the license file of my plex instance is somewhrere between ffmpeg version 4.3 and 4.4
v4l2m2m has better performance than omx, and is better maintained.
Make sure youāre running the latest rpi kernel and firmware (sudo rpi-update)
Using 64-bit RPI OS will also give you a bit of a speed boost.
I just changed the simple bash script to a much more advanced python script that can be configured via a yaml configuration file. Everything is commited and documented in my repo.
Thanks, Iāll give that a try. To be honest it was running quite horribly with the state my system is/was on. I am updating right now and will give it a try.
@fancybits The performance certainly got a lot better, but the quality is still horrible unfortunally.
Maybe someone with more ffmpeg experience can provide known good settings for h264_v4l2m2m? I will certainly keep trying to improve things, but thats it for today folks 
The quality would depend on the options being passed in. Whatās the full ffmpeg line being invoked?
Well, I didnāt mange to stop. Who needs sleep anyway xD
I figured out the issues:
- The
crfandmaxrateoptions donāt do s**t forh264_v4l2m2m,-b:vis where the magic happens. - My script didnāt introduce new options in the proper position, which resulted in the
-b:voption to be ignored completely.
I canāt beleive this is really happening, I have a smooth good quality stream transcoding on my pi4b!
Edit: The commandline now looks like this:
ffmpeg -codec:0 h264 -codec:1 eac3_eae -eae_prefix:1 qid9rxjjlnnrrssdbxeqisa7_ -ss 820 -noaccurate_seek -analyzeduration 20000000 -probesize 20000000 -i '/path/to/my/videofile.mkv' -map 0:0
-codec:0 h264_v4l2m2m -filter_complex '[0:1] aresample=async=1:ocl='"'"'stereo'"'"':rematrix_maxval=0.000000dB:osr=48000[0]' -map '[0]' -metadata:s:1 language=eng
-codec:1 aac -b:1 256k -f dash -seg_duration 5 -dash_segment_type mp4
-b:v 5M -crf:0 10 -maxrate:0 50M -bufsize:0 10M
-init_seg_name 'init-stream$RepresentationID$.m4s' -media_seg_name 'chunk-stream$RepresentationID$-$Number%05d$.m4s'
-window_size 5 -delete_removed false -skip_to_segment 165 -time_delta 0.0625
-manifest_name 'http://127.0.0.1:32400/video/:/transcode/session/sessionid/somthing-something/manifest?X-Plex-Http-Pipeline=infinite'
-avoid_negative_ts disabled -map_metadata -1 -map_chapters -1 dash -start_at_zero -copyts -y -nostats -loglevel quiet -loglevel_plex error
-progressurl http://127.0.0.1:32400/video/:/transcode/session/sessionid/somthing-something/progress
Yep, looks like you figured it out!
You could also use v4l2m2m for decoding (i.e. change the first part -codec:0 h264_v4l2m2m), which may help with performance even more.
And it might be helpful to pull in the latest patches from ffmpeg which improve perf, such as avcodec/v4l2_m2m_dec: dequeue frame if input isn't ready Ā· FFmpeg/FFmpeg@30322eb Ā· GitHub
Thatās more amazing progress in a few hours than what we had in years in this thread.
Is there any way for a pure user like me with basically zero programming knowledge to use what you guys have been doing? Iām running Plex on my Raspberry 4 using Ubuntu.
@LorenzL Yes. I am planning to simplify this script so it can be installed (and uninstalled) with just a few commands. Right now first priority is to get most cases working. I only tested a very limited set of conditions so far (web-player with just 2-3 different source types). With the android app on one of my tablets e.g. Iām facing an issue that I didnāt manage to solve yet. Iād guess in about 1-2 weeks the project should be ready to be tested by non-developers.
@fancybits Iām currently facing an issue with one of my android devices as described here: https://github.com/ForsakenNGS/raspi-plex-transcode/issues/1 If you have any idea that would be appreciated. All solutions I found so far from the error message are already present in the commandline. (e.g. -flags +global_header and -map_metadata:g -1 -map_metadata:c -1 -map_chapters)
This sounds great - will definitely try it over the weekend - quick question how many say 1080p transcodes can a RPI4 now support?
Basically at the moment for me with software transcoding it was 1 at most (and mostly I would lower the settings to 720p to get 1 transcode on the RPI4) - so I guess anything more than 1 is fantastic improvement
One or at most two. Right now with software-decoding and hardware-encoding Iām at ~60-75% cpu load with a single transcode.
For more simultaneous transcodes this project/approach might be more interesting: GitHub - UnicornTranscoder/UnicornTranscoder: Remote transcoder for Plex
I might look into implementing multiple transcode nodes within my script later, but that is a rather low priority right now.
That would be awesome to be able to try this in docker, but I have not been able make it work so far. Maybe someone smarter than me could be able to get around this.
What I tried: https://gist.github.com/remi-dupre/3572cf061f9575424c80ca7817115f67
This gives the error ERROR: mmal not found during the configure step.
I just finished the more user-friendly scripts, but as stated in my initial reply I would not recommend ānormal usersā to give it a go yet.
Iād say the issue is that raspberry-pi specific headers are missing. A few ideas for that:
- Add the rpi repository
deb-src http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpito the/etc/apt/sources.listand thenapt update && apt install libraspberrypi-dev - Start out with resin/rpi-raspbian then install plex followed by my wrapper.
That would be awesome to be able to try this in docker
I managed to get it working in a docker container. The current state is available at:
https://hub.docker.com/repository/docker/jensn/docker-plex-raspi
So finally got to try your work @jen83 and its very very encouraging.
A couple of pointers / comments:
- I couldnāt get the compile to work (it would be super helpful if you had more technical details - though I do appreciate that you are trying to hide the technical details - I believe something isnāt quiet right with the dependencies on my RPI4 and I was having various problems compiling ffmpeg - including the issue with the mmal library (which I believe is crucial) not being found.
- The configuration files and the scripts make some assumptions e.g. hard coded paths to particular folders eā¦g I do not have a āpiā account so I had to modify some of the configuration files (no big deal really).
- Because of 1. above I switch to use the docker image and while I could get a 1080p transcode - it was using 2 of the CPUās e.g. nearly 200% in top and the quality wasnāt great so not sure if I had the right settings. This was a live 1080p stream being transcoded. There are a couple of settings in the configuration file that have **REMOVE** which I imagine means I should really remove the value rather than leave it?
- Maybe some more information in the log files - I would imagine if we could get a āunit testā of a set of sample inputs (various codecs & resolutions etc) running with your transcoding process + ffmpeg + your configuration running independently of Plex and experiment with the various options we could get to a solid configuration + scripts that would work for most people.
But overall I am very impressed and I hope as a community we can move forward with this solution on our Raspberry PIās.
Thanks
@jerome_oflaherty_icloud_com Thanks for the feedback.
Itās certainly possible that I missed dependencies that I already installed before documenting the steps within the script. Iāll check on the specificly named mmal library and fix that accordingly.
I changed the ffmpeg/ffprobe paths to allow relative paths, which allows for better āstockā configuration files.
Yes, if there is e.g. '-x264opts:0': '**REMOVE**' it will remove the argument -x264opts:0 and itās according value completely. since h264_v4l2m2m will ignore crf, maxrate and (obviously) x264opts those are obsolete and only make the argument list harder to read/analyse.
Thatās certainly not a bad idea. Iāll keep that in mind. To be honest my hope is still official support from plex, but with this weekendās adjustments at least my currently watched series all work fine
(had some audio/buffering issues on android thatās fixed with a eac3 ā aac conversion instead of eac3 ā libopus)
With my experience so far I donāt think more than one 1080p stream is realistic with the pi, but to be honest that is fine by me. When more is required there are a few alternative approaches that may solve it:
- Smart pre-transcoding of series/movies that are likely to be watched next (e.g. new content / next episode(s) of a recently watched series) - this is already suggested here if I remember correctly
- External transcoding-nodes which can do the transcode for the pi. I already experimented with that approach, but didnāt manage to get it working yet. The idea is to have a compatible ffmpeg build available on another PC and start the transcoding job via SSH there. (Source files are mounted via NFS at the identical path to make it simple and the traffic forwarded via SSH port forwarding) This could for example do a wake-on-lan when a transcode is requested and put the machine back to sleep afterwards to keep power consumption low and/or only be used if the source material is very demanding (e.g. 4k / HDR)