Thefrank / jellyfin-server-freebsd

jellyfin-server component for freebsd
185 stars 16 forks source link

ffmpeg path not set in encoding.xml on 14.0-RELEASE #69

Open frenata opened 7 months ago

frenata commented 7 months ago

Learnings

This is clearly related to #35 and the many similar issues filed previously, but I'm not using TrueNAS/etc, just plain FreeBSD.

My setup is pretty straightforward, installing jellyfin via a jail (managed by bastille). The template worked well, I'm not doing anything much beyond that and got audio working.

After narrowing in on the issue of ffmpeg not being found per the logs, I speculated that jellyfin's removal of the ability to set the path in the UI was biting me. Downgrading your package to 10.8.10 and setting the path to ffmpeg via the UI to /usr/local/bin/ffmpeg got everything working.

Further, on my still live 10.8.13 jail, I was able to edit /var/db/jellyfin/config/encoding.xml to similarly set the path and everything was working for that installation too.

Actions

I'm not sure where jellyfin expects ffmpeg to exist and it was certainly in the PATH regardless, but it seems like explicitly setting the path via encoding.xml is a must. My own installation is now fine but it'd be great to help others avoid this issue in the future.

I peeked at the repo itself and am unsure where such a change could be made. I'm presuming an addition to the jellyfin.diff? I'd happily contribute something given a nudge in the right direction.

Thefrank commented 7 months ago

35 does seem related if not exactly the issue at hand here. I assume you are upgrading from an older version to a newer one?

As for jellyfin's handling of ffmpeg's location:

https://github.com/jellyfin/jellyfin/blob/e93d03d8cbff2122d7296f477604146f64758a73/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs#L113-L118 https://github.com/jellyfin/jellyfin/blob/e93d03d8cbff2122d7296f477604146f64758a73/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs#L249-L255

My guess: encoding.xml had an incorrect but not NULL or Empty value for EncoderAppPath and jellyfin decided to give up after checking that.

Possible solution for future users if this has not been resolved: shutdown jellyfin. remove <EncoderAppPath> block from the encoding.xml. restart jellyfin with EITHER --ffmpeg set to the location of the binary OR ensure that ffmpeg is on $PATH

Upstream someone else had a similar issue and came to a similar conclusion: https://github.com/jellyfin/jellyfin/issues/10776

If you want to make changes here, I generally accept PRs :)

frenata commented 7 months ago

I assume you are upgrading from an older version to a newer one?

Nope, it was a fresh install, which is why I thought it was particularly notable, compared to all the prior issues.

My guess: encoding.xml had an incorrect but not NULL or Empty value for EncoderAppPath and jellyfin decided to give up after checking that.

EncoderAppPath was simply not present at all in encoding.xml! There was only the display value: <EncoderAppPathDisplay /> My own installation was completely fixed by adding <EncoderAppPath>/usr/local/bin/ffmpeg</EncoderAppPath>

upstream

Yeah, that one helped me look in the right place. I'm new to FreeBSD ports, but I'll see what I can do.

Thefrank commented 7 months ago

Very strange. I can not reproduce this with iocage.

iocage create -n jellytest vnet="on" dhcp="on" allow_mlock="1" defaultrouter=192.168.0.1/24 -r 13.2-RELEASE
iocage start jellytest
iocage exec jellytest "pkg install jellyfin"
iocage exec jellytest "service jellyfin enable"
iocage exec jellytest "service jellyfin start"

Log: Log.txt

encoding.xml does not contain the encoder path even after a second run.

<?xml version="1.0" encoding="utf-8"?>
<EncodingOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <EncodingThreadCount>-1</EncodingThreadCount>
  <EnableFallbackFont>false</EnableFallbackFont>
  <DownMixAudioBoost>2</DownMixAudioBoost>
  <MaxMuxingQueueSize>2048</MaxMuxingQueueSize>
  <EnableThrottling>false</EnableThrottling>
  <ThrottleDelaySeconds>180</ThrottleDelaySeconds>
  <EncoderAppPathDisplay>ffmpeg</EncoderAppPathDisplay>
  <VaapiDevice>/dev/dri/renderD128</VaapiDevice>
  <EnableTonemapping>false</EnableTonemapping>
  <EnableVppTonemapping>false</EnableVppTonemapping>
  <TonemappingAlgorithm>bt2390</TonemappingAlgorithm>
  <TonemappingMode>auto</TonemappingMode>
  <TonemappingRange>auto</TonemappingRange>
  <TonemappingDesat>0</TonemappingDesat>
  <TonemappingPeak>100</TonemappingPeak>
  <TonemappingParam>0</TonemappingParam>
  <VppTonemappingBrightness>16</VppTonemappingBrightness>
  <VppTonemappingContrast>1</VppTonemappingContrast>                                                    
  <H264Crf>23</H264Crf>                                                                                 
  <H265Crf>28</H265Crf>                                                                                 
  <DeinterlaceDoubleRate>false</DeinterlaceDoubleRate>                                                  
  <DeinterlaceMethod>yadif</DeinterlaceMethod>                                                          
  <EnableDecodingColorDepth10Hevc>true</EnableDecodingColorDepth10Hevc>                                 
  <EnableDecodingColorDepth10Vp9>true</EnableDecodingColorDepth10Vp9>                                   
  <EnableEnhancedNvdecDecoder>true</EnableEnhancedNvdecDecoder>                                         
  <PreferSystemNativeHwDecoder>true</PreferSystemNativeHwDecoder>                                       
  <EnableIntelLowPowerH264HwEncoder>false</EnableIntelLowPowerH264HwEncoder>                            
  <EnableIntelLowPowerHevcHwEncoder>false</EnableIntelLowPowerHevcHwEncoder>                            
  <EnableHardwareEncoding>true</EnableHardwareEncoding>                                                 
  <AllowHevcEncoding>false</AllowHevcEncoding>                                                          
  <EnableSubtitleExtraction>true</EnableSubtitleExtraction>
  <HardwareDecodingCodecs>
    <string>h264</string>
    <string>vc1</string>
  </HardwareDecodingCodecs>
  <AllowOnDemandMetadataBasedKeyframeExtractionForExtensions>
    <string>mkv</string>
  </AllowOnDemandMetadataBasedKeyframeExtractionForExtensions>
</EncodingOptions>
frenata commented 7 months ago

Okay, just to rule out differences between bastille and iocage, here's my replication:

pkg install py39-iocage
iocage activate system
iocage fetch
iocage create -n jellytest vnet=on dhcp=on allow_mlock=1 defaultrouter=10.2.0.0/24 -r 14.0-RELEASE
iocage start jellytest
iocage exec jellytest pkg install jellyfin
iocage exec jellytest service jellyfin enable
iocage exec jellytest service jellyfin start
# at this point I went through the jellyfin setup via the web interface and connected a small folder of shows
# confirmed error message of "This client isn't compatible with the media and the server isn't sending a compatible media format."
# confirmed expected error messages in /var/db/jellyfin/log as well
iocage exec jellytest service jellyfin restart
# after server restart and try playing media again, no difference

Contents of encoding.xml:

<?xml version="1.0" encoding="utf-8"?>
<EncodingOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <EncodingThreadCount>-1</EncodingThreadCount>
  <EnableFallbackFont>false</EnableFallbackFont>
  <DownMixAudioBoost>2</DownMixAudioBoost>
  <MaxMuxingQueueSize>2048</MaxMuxingQueueSize>
  <EnableThrottling>false</EnableThrottling>
  <ThrottleDelaySeconds>180</ThrottleDelaySeconds>
  <EncoderAppPathDisplay />
  <VaapiDevice>/dev/dri/renderD128</VaapiDevice>
  <EnableTonemapping>false</EnableTonemapping>
  <EnableVppTonemapping>false</EnableVppTonemapping>
  <TonemappingAlgorithm>bt2390</TonemappingAlgorithm>
  <TonemappingMode>auto</TonemappingMode>
  <TonemappingRange>auto</TonemappingRange>
  <TonemappingDesat>0</TonemappingDesat>
  <TonemappingPeak>100</TonemappingPeak>
  <TonemappingParam>0</TonemappingParam>
  <VppTonemappingBrightness>16</VppTonemappingBrightness>
  <VppTonemappingContrast>1</VppTonemappingContrast>
  <H264Crf>23</H264Crf>
  <H265Crf>28</H265Crf>
  <DeinterlaceDoubleRate>false</DeinterlaceDoubleRate>
  <DeinterlaceMethod>yadif</DeinterlaceMethod>
  <EnableDecodingColorDepth10Hevc>true</EnableDecodingColorDepth10Hevc>
  <EnableDecodingColorDepth10Vp9>true</EnableDecodingColorDepth10Vp9>
  <EnableEnhancedNvdecDecoder>true</EnableEnhancedNvdecDecoder>
  <PreferSystemNativeHwDecoder>true</PreferSystemNativeHwDecoder>
  <EnableIntelLowPowerH264HwEncoder>false</EnableIntelLowPowerH264HwEncoder>
  <EnableIntelLowPowerHevcHwEncoder>false</EnableIntelLowPowerHevcHwEncoder>
  <EnableHardwareEncoding>true</EnableHardwareEncoding>
  <AllowHevcEncoding>false</AllowHevcEncoding>
  <EnableSubtitleExtraction>true</EnableSubtitleExtraction>
  <HardwareDecodingCodecs>
    <string>h264</string>
    <string>vc1</string>
  </HardwareDecodingCodecs>
  <AllowOnDemandMetadataBasedKeyframeExtractionForExtensions>
    <string>mkv</string>
  </AllowOnDemandMetadataBasedKeyframeExtractionForExtensions>
</EncodingOptions>

Note how EncoderAppPathDisplay is empty and EncoderAppPath is absent!

Next, I edited encoding.xml:

9c9
<   <EncoderAppPath>/usr/local/bin/ffmpeg</EncoderAppPath>
---
>   <EncoderAppPathDisplay />
41c41
< </EncodingOptions>
---
> </EncodingOptions>
\ No newline at end of file

After restarting via iocage exec jellytest "service jellyfin restart" playback now works correct, and encoding.xml now differs from the original as such:

9,10c9
<   <EncoderAppPath>/usr/local/bin/ffmpeg</EncoderAppPath>
<   <EncoderAppPathDisplay>/usr/local/bin/ffmpeg</EncoderAppPathDisplay>
---
>   <EncoderAppPathDisplay />

Edit: since I don't see any important differences between your replication and mine I'm going to follow up with a test on a 13.2 iocage jail.

frenata commented 7 months ago

Confirmed! The exact same sequence of commands/actions on 13.2-RELEASE jail works, with EncoderAppPathDispay having a value simply of ffmpeg. Playback works entirely as expected.

I guess this means that somehow something changed from 13.2-RELEASE to 14-RELEASE that prevents jellyfin from correctly finding the ffmpeg path? As a newcomer to FreeBSD I'm stumped as to what that might be. The pkg lists to be installed as a result of pkg install jellyfin were identical.

Thefrank commented 7 months ago

~how is PATH set in /etc/login.conf for the "default" class?~

~edit: and "daemon"~ These should not matter anyways

does making a sym link for ffmpeg into /usr/bin resolve the issue on 14?

frenata commented 7 months ago

does making a sym link for ffmpeg into /usr/bin resolve the issue on 14?

Confirmed playback works as expected on a fresh install on 14 with ffmpeg symlinked into /usr/bin!

To get metadata capture working properly I had to symlink ffprobe as well.

Thefrank commented 7 months ago

This makes it seem like $PATH is set/export correctly in 14 but wrong in 13.2. daemon uses a longer path that includes /usr/local/ items... unless invoked from service or rc which override that.

frenata commented 7 months ago

Here's the results of procstat -e <the PID of the jellyfin process inside each jail>. It confirms that there are PATH differences.

jellytest14 (iocage on 14.0) environment: LANG=C.UTF-8 PATH=/sbin:/bin:/usr/sbin:/usr/bin CLR_OPENSSL_VERSION_OVERRIDE=30 PWD=/ HOME=/ MM_CHARSET=UTF-8 RC_PID=34961 BLOCKSIZE=K

jellytest13 (iocage on 13.2) environment: VENDOR=amd LOGNAME=jellyfin PAGER=less LANG=C.UTF-8 OSTYPE=FreeBSD MACHTYPE=x86_64 PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin://bin EDITOR=vi HOST=jellytest13 CLR_OPENSSL_VERSION_OVERRIDE=30 PWD=/ GROUP=jellyfin USER=jellyfin HOME=/ HOSTTYPE=FreeBSD MM_CHARSET=UTF-8 BLOCKSIZE=K RC_PID=67141 SHLVL=1

A little surprisingly to me, setting exec_clean doesn't seem to affect this one way or another. In both cases, consoleing in and echo $PATH produces a correct looking PATH: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin

Editing the jellyfin rc script inside jellytest14 to add: jellyfin_env="PATH=$PATH:/usr/local/bin" correctly updates thejellyfin` environment once restarted, so this is possibly the first real persistent fix that could be made. It's a bit irritating to not understand why the PATH difference exists between the 13.2 and 14.0 jails!

I appreciate you talking through this with me, even as it seems increasingly unlikely that this has anything to do with jellyfin-server-freebsd itself! Hopefully if nothing else this helps someone else understand the necessary fixes in the future.

Thefrank commented 7 months ago

So the FreeBSD 14 environment is technically set correct for both PATH and HOME and FreeBSD 13 is not. Both service and rc should clobber the default path provided by daemon. AFAIK it should not clobber ALL of the env which is appears to be doing (e.g., missing UID/GID, host, os). 13 has SHLVL set despite that user not having a loginshell. Maybe I am missing something in my understanding on now all of this glues together? Is this because 14 uses a different default shell? Nuances of shells is a bit out of my expertise. It does not appear that service(8) was changed significantly between 13.2 and 14.0, it only added the -E option.

While this issue does not appear to be jellyfin related it needs to be worked around.

Thoughts @mvanbaak? What would be the better way of doing this in ports? There is already a jellyfin_extraargs and that will accept things like --ffmpeg /PATH/TO/FFMPEG. A note in the install message might help guide people on this. I can also add an item to troubleshooting that covers this too. I am not opposed to adding jellyfin_env but messing up env variables is pretty easy if the user is not paying attention or makes a typo in the syntax. This is more of a non-issue if it is set ahead of time.

mvanbaak commented 7 months ago

@Thefrank I'm about to send the following patch to the FreeBSD ports tree. The same 'fix' of exporting the path with the /usr/local parts is already present in some other ports, and a freebsd ports committer told me this would be ok

[edit] See FreeBSD PR: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277161

From fd3bebecb0180acff0c2bcccc2251adf7d4229d3 Mon Sep 17 00:00:00 2001
From: Michiel van Baak Jansen <michiel@vanbaak.eu>
Date: Fri, 16 Feb 2024 14:32:20 +0100
Subject: [PATCH] multimedia/jellyfin: export PATH so jellyfin can find ffmpeg

---
 multimedia/jellyfin/Makefile          | 1 +
 multimedia/jellyfin/files/jellyfin.in | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/multimedia/jellyfin/Makefile b/multimedia/jellyfin/Makefile
index e5a4ab026d72..1dd696d2f431 100644
--- a/multimedia/jellyfin/Makefile
+++ b/multimedia/jellyfin/Makefile
@@ -1,5 +1,6 @@
 PORTNAME=      jellyfin
 DISTVERSION=   10.8.13
+PORTREVISION=  1
 CATEGORIES=    multimedia
 MASTER_SITES=  https://github.com/Thefrank/jellyfin-server-freebsd/releases/download/v${DISTVERSION}/
 DISTFILES=     jellyfin-combined_${DISTVERSION}_freebsd-${ARCH}.tar.gz \
diff --git a/multimedia/jellyfin/files/jellyfin.in b/multimedia/jellyfin/files/jellyfin.in
index 2bebe5580663..1ab390011c20 100755
--- a/multimedia/jellyfin/files/jellyfin.in
+++ b/multimedia/jellyfin/files/jellyfin.in
@@ -41,6 +41,8 @@ command="/usr/sbin/daemon"

 start_precmd=${name}_precmd
 jellyfin_precmd() {
+    export PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
+
     if [ ! -d ${jellyfin_exec_dir} ]; then
         install -d -o ${jellyfin_user} -g ${jellyfin_group} ${jellyfin_exec_dir}
     fi
--
2.43.2
Thefrank commented 7 months ago

@mvanbaak nitpick: Would %%LOCALBASE%% (or %%PREFIX%%) work for /usr/local? For 0.01% of people that don't have /usr/local for that?

I like macros but you are the maintainer

ageekhere commented 7 months ago

I just updated the plugin and now have this issue. I stopped jellyfin then added /usr/local/bin/ffmpeg to var/db/jellyfin/config/encoding.xml saved and then started jellyfin

However i still get the FFmpeg path not set error.

frenata commented 7 months ago

I just updated the plugin and now have this issue. I stopped jellyfin then added /usr/local/bin/ffmpeg to var/db/jellyfin/config/encoding.xml saved and then started jellyfin

Note that there are several other issues where people discuss update/upgrade problems, so it's possible you may need to read through those discussions rather than this one -- which is very much "the fresh install doesn't work as intended" focused.

mvanbaak commented 7 months ago

See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277161

Thefrank commented 7 months ago

@mvanbaak I guess the question now: Is this a dotNET issue or a FreeBSD 14 issue? I can do ABI specific builds if that will resolve it.

ageekhere commented 7 months ago

Note that there are several other issues where people discuss update/upgrade problems, so it's possible you may need to read through those discussions rather than this one -- which is very much "the fresh install doesn't work as intended" focused.

I get the error when i play a video

[2024-02-24 07:55:15.476 +11:00] [ERR] [103] Jellyfin.Server.Middleware.ExceptionMiddleware: Error processing request. URL "GET" "/videos/e4fbb508-4c50-9b20-953a-fc49c6cc0a21/hls1/main/0.ts".
System.ArgumentException: FFmpeg path not set.
ageekhere commented 7 months ago

I ended up just uninstalling the plugin and reinstalling it again. Now it is fixed