2025-02-19, 02:23 PM
(This post was last modified: 2025-02-19, 02:26 PM by burnout. Edited 1 time in total.)
Hello,
some time ago I started to play with vapoursynth enhancement like REALESRGAN and RIFE. I wrote a quick'n'dirty solution which takes the jellyfin-mpv-shim project together with vapoursynth to create a rtsp stream, to bring it back to jellyfin server as a live rtsp tv channel.
Why use mpv for that? Well cus ffmpeg cant use vapoursynth as filter directly (and the ffmpeg/vapoursynth devs are in some kind of fight, cus someone called someone else an idiot and some more childish... - so no progress will ever happen on the integration of vapoursynth into ffmpeg as filter, I guess), but mpv can.
So I am able to watch upscaled and interpolated content from within jellyfin - as "LiveTV". But, yeah, its not perfectly integrated. So I try to write a wrapper script to do it better.
The idea behind this:
A wrapper script which replaces ffmpeg binary for jellyfin. Then start a ffmpeg process to decode content and pipe it to mpv. Apply vapoursynth filter, encode it and pipe it to a second ffmpeg process. Save content as hls stream.
Here is what I have til now:
Actual it works like it should. But jellyfin is interrupting the transcode after a while (non-deterministic), and resuming the transcode process but with some delay. So I get jumps in the video. I have disabled throtteling.
jellyfin log:
first ffmpeg log:
second ffmpeg log:
As you see the stop times of the hls transcode is different from the time jellyfin is resuming the transcode.
So, on the first place, why the transcode is stopped, even when throtteling is disabled?
How does jellyfin internaly determine how far the transcode process was, and how does it determine at which time it should "resume" it?
I thought this would be done from the output of the ffmpeg process. But apparently this is not the case.
some time ago I started to play with vapoursynth enhancement like REALESRGAN and RIFE. I wrote a quick'n'dirty solution which takes the jellyfin-mpv-shim project together with vapoursynth to create a rtsp stream, to bring it back to jellyfin server as a live rtsp tv channel.
Why use mpv for that? Well cus ffmpeg cant use vapoursynth as filter directly (and the ffmpeg/vapoursynth devs are in some kind of fight, cus someone called someone else an idiot and some more childish... - so no progress will ever happen on the integration of vapoursynth into ffmpeg as filter, I guess), but mpv can.
So I am able to watch upscaled and interpolated content from within jellyfin - as "LiveTV". But, yeah, its not perfectly integrated. So I try to write a wrapper script to do it better.
The idea behind this:
A wrapper script which replaces ffmpeg binary for jellyfin. Then start a ffmpeg process to decode content and pipe it to mpv. Apply vapoursynth filter, encode it and pipe it to a second ffmpeg process. Save content as hls stream.
Here is what I have til now:
#!/bin/bash
#create random pipes - just a workaround for dev reasons
PIPE_NAME=$(mktemp -u tmp_pipe_XXXXXX)
PIPE_PATH="/tmp/$PIPE_NAME"
PIPE_NAME2=$(mktemp -u tmp_pipe_XXXXXX)
PIPE_PATH2="/tmp/$PIPE_NAME2"
mkfifo "$PIPE_PATH"
mkfifo "$PIPE_PATH2"
args=("$@")
date=$(date)
echo "-------------- $date --------------" >> /usr/lib/jellyfin-ffmpeg/ffmpeg_args.txt
echo "${args[@]}" >> /usr/lib/jellyfin-ffmpeg/ffmpeg_args.txt
new_args=() #output args
i_value=() #input args
hls_segment_found=false
for ((i=0; i<${#args[@]}; i++)); do
case ${args[i]} in
"-f")
if [[ ${args[i+1]} == "hls" ]]; then
new_args+=("${args[i]}" "${args[i+1]}")
((i++)
fi
;;
"-max_delay" | "-hls_time" | "-hls_fmp4_init_filename" | "-start_number" | "-hls_segment_filename" | "-hls_list_size" | "-y" | "-hls_base_url" | "-hls_segment_type" | "-hls_playlist_type")
new_args+=("${args[i]}" "${args[i+1]}")
((i++))
;;
"-i")
i_value+=("${args[i]}" "${args[i+1]}")
((i++))
;;
"-ss")
i_value+=("${args[i]}" "${args[i+1]}" "-noaccurate_seek")
((i++))
;;
esac
if [[ ${args[i]} == *"m3u8"* ]]; then
hls_segment_found=true
fi
done
if $hls_segment_found; then
echo "${i_value[@]}" > /usr/lib/jellyfin-ffmpeg/created.txt
echo "${new_args[@]}" >> /usr/lib/jellyfin-ffmpeg/created.txt
#input ffmpeg proc pipe to mpv
/usr/lib/jellyfin-ffmpeg/ffmpeg_bin -re "${i_value[@]}" -c copy -f mpegts pipe:1 > $PIPE_PATH2 2> /var/cache/jellyfin/transcodes/ffmpeg_cmd1_stderr &
#mpv proc to append vapoursynth filter and encode video
CUDA_VISIBLE_DEVICES=2,0,1 /usr/local/bin/mpv --hr-seek-framedrop=no --no-sub $PIPE_PATH2 --hwdec=yes \
--ovc=h264_nvenc --ovcopts-add="preset=p7" --ovcopts-add="rc=vbr" --ovcopts-add="cq=22" \
--of=matroska --oac=aac --oacopts=b=768k --o=$PIPE_PATH \
--vf=vapoursynth="/root/test.vpy" > /var/cache/jellyfin/transcodes/mpv_stdout 2> /var/cache/jellyfin/transcodes/mpv_stderr &
#ffmpeg proc to create m3u8 hls
exec /usr/lib/jellyfin-ffmpeg/ffmpeg_bin -threads 16 -i $PIPE_PATH -c:v copy -c:a copy "${new_args[@]}"
else
CUDA_VISIBLE_DEVICES=2,0,1
exec /usr/lib/jellyfin-ffmpeg/ffmpeg_bin "${args[@]}"
fi
Actual it works like it should. But jellyfin is interrupting the transcode after a while (non-deterministic), and resuming the transcode process but with some delay. So I get jumps in the video. I have disabled throtteling.
jellyfin log:
[2025-02-19 11:02:32.224 +00:00] [INF] "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:\"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename \"c134c707d9557c7f05b503ff188a7e38-1.mp4\" -start_number 0 -hls_segment_filename \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8\""
[2025-02-19 11:02:32.587 +00:00] [INF] Playback stopped reported by app "Jellyfin Web" "10.10.5" playing "Verrückt nach Mira". Stopped at "2477029" ms
[2025-02-19 11:07:58.215 +00:00] [INF] FFmpeg exited with code 0
[2025-02-19 11:08:04.831 +00:00] [INF] Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2025-02-19 11:08:04.832 +00:00] [INF] "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -ss 00:05:27.700 -noaccurate_seek -fflags +genpts -f matroska -i file:\"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename \"c134c707d9557c7f05b503ff188a7e38-1.mp4\" -start_number 54 -hls_segment_filename \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8\""
[2025-02-19 11:23:48.289 +00:00] [INF] FFmpeg exited with code 0
[2025-02-19 11:23:52.182 +00:00] [INF] Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2025-02-19 11:23:52.183 +00:00] [INF] "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -ss 00:21:08.300 -noaccurate_seek -fflags +genpts -f matroska -i file:\"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename \"c134c707d9557c7f05b503ff188a7e38-1.mp4\" -start_number 211 -hls_segment_filename \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8\""
[2025-02-19 11:39:37.650 +00:00] [INF] FFmpeg exited with code 0
[2025-02-19 11:39:45.191 +00:00] [INF] Current HLS implementation doesn't support non-keyframe breaks but one is requested, ignoring that request
[2025-02-19 11:39:45.192 +00:00] [INF] "/usr/lib/jellyfin-ffmpeg/ffmpeg" "-analyzeduration 200M -probesize 1G -ss 00:36:54.780 -noaccurate_seek -fflags +genpts -f matroska -i file:\"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv\" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af \"volume=2\" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename \"c134c707d9557c7f05b503ff188a7e38-1.mp4\" -start_number 369 -hls_segment_filename \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4\" -hls_playlist_type vod -hls_list_size 0 -y \"/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8\""
[2025-02-19 11:43:28.368 +00:00] [INF] FFmpeg exited with code 0
[2025-02-19 11:43:53.257 +00:00] [INF] Deleting partial stream file(s) "/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8"
[2025-02-19 11:43:53.259 +00:00] [INF] Playback stopped reported by app "Jellyfin Web" "10.10.5" playing "Schatten der Rentnerschaft". Stopped at "2431881" ms
first ffmpeg log:
{"Protocol":0,"Id":"ba328dbe81b9eefa3479b8318bd89549","Path":"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv","EncoderPath":null,"EncoderProtocol":null,"Type":0,"Container":"mkv","Size":1661603518,"Name":"tvs-psych-dd51-dl-7p-azhd-avc-212","IsRemote":false,"ETag":"5d346bb6462a1ff319faa9296909e2ee","RunTimeTicks":24367040000,"ReadAtNativeFramerate":false,"IgnoreDts":false,"IgnoreIndex":false,"GenPtsInput":false,"SupportsTranscoding":true,"SupportsDirectStream":true,"SupportsDirectPlay":true,"IsInfiniteStream":false,"UseMostCompatibleTranscodingProfile":false,"RequiresOpening":false,"OpenToken":null,"RequiresClosing":false,"LiveStreamId":null,"BufferMs":null,"RequiresLooping":false,"SupportsProbing":true,"VideoType":0,"IsoType":null,"Video3DFormat":null,"MediaStreams":[{"Codec":"h264","CodecTag":null,"Language":null,"ColorRange":null,"ColorSpace":"bt709","ColorTransfer":"bt709","ColorPrimaries":"bt709","DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":1,"VideoRangeType":1,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":null,"LocalizedForced":null,"LocalizedExternal":null,"LocalizedHearingImpaired":null,"DisplayTitle":"720p H264 SDR","NalLengthSize":"4","IsInterlaced":false,"IsAVC":true,"ChannelLayout":null,"BitRate":5455249,"BitDepth":8,"RefFrames":1,"PacketLength":null,"Channels":null,"SampleRate":null,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Height":720,"Width":1280,"AverageFrameRate":25,"RealFrameRate":25,"ReferenceFrameRate":25,"Profile":"High","Type":1,"AspectRatio":"16:9","Index":0,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":"yuv420p","Level":31,"IsAnamorphic":false},{"Codec":"ac3","CodecTag":null,"Language":"ger","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":0,"VideoRangeType":0,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":"Standard","LocalizedForced":null,"LocalizedExternal":"Extern","LocalizedHearingImpaired":null,"DisplayTitle":"Ger - Dolby Digital - 5.1 - Standard","NalLengthSize":null,"IsInterlaced":false,"IsAVC":false,"ChannelLayout":"5.1","BitRate":448000,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":6,"SampleRate":48000,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"ReferenceFrameRate":null,"Profile":null,"Type":0,"AspectRatio":null,"Index":1,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null},{"Codec":"ac3","CodecTag":null,"Language":"eng","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":0,"VideoRangeType":0,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":"Standard","LocalizedForced":null,"LocalizedExternal":"Extern","LocalizedHearingImpaired":null,"DisplayTitle":"English - Dolby Digital - 5.1","NalLengthSize":null,"IsInterlaced":false,"IsAVC":false,"ChannelLayout":"5.1","BitRate":448000,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":6,"SampleRate":48000,"IsDefault":false,"IsForced":false,"IsHearingImpaired":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"ReferenceFrameRate":null,"Profile":null,"Type":0,"AspectRatio":null,"Index":2,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null}],"MediaAttachments":[],"Formats":[],"Bitrate":6351249,"FallbackMaxStreamingBitrate":null,"Timestamp":null,"RequiredHttpHeaders":{},"TranscodingUrl":null,"TranscodingSubProtocol":0,"TranscodingContainer":null,"AnalyzeDurationMs":null,"DefaultAudioStreamIndex":null,"DefaultSubtitleStreamIndex":null,"HasSegments":false}
/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename "c134c707d9557c7f05b503ff188a7e38-1.mp4" -start_number 0 -hls_segment_filename "/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4" -hls_playlist_type vod -hls_list_size 0 -y "/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8"
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-
ffmpeg version 7.0.2-Jellyfin Copyright © 2000-2024 the FFmpeg developers
built with gcc 11 (Ubuntu 11.4.0-1ubuntu1~22.04)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-ptx-compression --disable-static --disable-libxcb --disable-sdl2 --disable-xlib --enable-lto=auto --enable-gpl --enable-version3 --enable-shared --enable-gmp --enable-gnutls --enable-chromaprint --enable-opencl --enable-libdrm --enable-libxml2 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libfontconfig --enable-libharfbuzz --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libopenmpt --enable-libdav1d --enable-libsvtav1 --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --enable-libfdk-aac --arch=amd64 --enable-libshaderc --enable-libplacebo --enable-vulkan --enable-vaapi --enable-amf --enable-libvpl --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc
libavutil 59. 8.100 / 59. 8.100
libavcodec 61. 3.100 / 61. 3.100
libavformat 61. 1.100 / 61. 1.100
libavdevice 61. 1.100 / 61. 1.100
libavfilter 10. 1.100 / 10. 1.100
libswscale 8. 1.100 / 8. 1.100
libswresample 5. 1.100 / 5. 1.100
libpostproc 58. 1.100 / 58. 1.100
Input #0, matroska,webm, from '/tmp/tmp_pipe_4pPJTi':
Metadata:
ENCODER : Lavf61.9.102
Duration: N/A, start: -0.021000, bitrate: N/A
Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp
Stream #0:1: Video: h264 (Main), yuv420p(tv, bt709/unknown/unknown, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 1k tbn
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
[hls @ 0x5f33d6cf0d00] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38-1.mp4' for writing
Output #0, hls, to '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8':
Metadata:
encoder : Lavf61.1.100
Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709/unknown/unknown, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 50 fps, 50 tbr, 16k tbn
Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp
Press [q] to stop, [?] for help
size=N/A time=00:00:01.40 bitrate=N/A speed=2.81x
size=N/A time=00:00:02.00 bitrate=N/A speed= 2x
size=N/A time=00:00:02.73 bitrate=N/A speed=1.82x
size=N/A time=00:00:03.22 bitrate=N/A speed=1.61x
size=N/A time=00:00:03.73 bitrate=N/A speed=1.49x
size=N/A time=00:00:04.41 bitrate=N/A speed=1.47x
size=N/A time=00:00:04.88 bitrate=N/A speed= 1.4x
size=N/A time=00:00:05.46 bitrate=N/A speed=1.36x
...
size=N/A time=00:05:09.48 bitrate=N/A speed=1.02x
[hls @ 0x5f33d6cf0d00] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e3850.mp4' for writing
size=N/A time=00:05:09.97 bitrate=N/A speed=1.02x
size=N/A time=00:05:10.44 bitrate=N/A speed=1.02x
size=N/A time=00:05:11.06 bitrate=N/A speed=1.02x
size=N/A time=00:05:11.48 bitrate=N/A speed=1.02x
size=N/A time=00:05:11.97 bitrate=N/A speed=1.02x
size=N/A time=00:05:12.49 bitrate=N/A speed=1.02x
[hls @ 0x5f33d6cf0d00] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e3851.mp4' for writing
size=N/A time=00:05:12.98 bitrate=N/A speed=1.02x
size=N/A time=00:05:13.49 bitrate=N/A speed=1.02x
size=N/A time=00:05:13.96 bitrate=N/A speed=1.02x
size=N/A time=00:05:14.49 bitrate=N/A speed=1.02x
size=N/A time=00:05:14.90 bitrate=N/A speed=1.02x
size=N/A time=00:05:15.47 bitrate=N/A speed=1.02x
size=N/A time=00:05:16.01 bitrate=N/A speed=1.02x
size=N/A time=00:05:16.39 bitrate=N/A speed=1.02x
size=N/A time=00:05:17.09 bitrate=N/A speed=1.02x
size=N/A time=00:05:17.46 bitrate=N/A speed=1.02x
size=N/A time=00:05:18.01 bitrate=N/A speed=1.02x
size=N/A time=00:05:18.52 bitrate=N/A speed=1.02x
[hls @ 0x5f33d6cf0d00] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e3852.mp4' for writing
size=N/A time=00:05:19.08 bitrate=N/A speed=1.02x
size=N/A time=00:05:19.44 bitrate=N/A speed=1.02x
size=N/A time=00:05:19.89 bitrate=N/A speed=1.02x
size=N/A time=00:05:20.61 bitrate=N/A speed=1.02x
size=N/A time=00:05:21.00 bitrate=N/A speed=1.02x
size=N/A time=00:05:21.51 bitrate=N/A speed=1.02x
size=N/A time=00:05:21.89 bitrate=N/A speed=1.02x
size=N/A time=00:05:22.41 bitrate=N/A speed=1.02x
size=N/A time=00:05:22.94 bitrate=N/A speed=1.02x
size=N/A time=00:05:23.22 bitrate=N/A speed=1.01x
size=N/A time=00:05:23.22 bitrate=N/A speed=1.01x
size=N/A time=00:05:23.64 bitrate=N/A speed=1.01x
[hls @ 0x5f33d6cf0d00] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e3853.mp4' for writing
[out#0/hls @ 0x5f33d6dd2a40] video:777000KiB audio:11463KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
size=N/A time=00:05:23.96 bitrate=N/A speed=1.01x
second ffmpeg log:
{"Protocol":0,"Id":"ba328dbe81b9eefa3479b8318bd89549","Path":"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv","EncoderPath":null,"EncoderProtocol":null,"Type":0,"Container":"mkv","Size":1661603518,"Name":"tvs-psych-dd51-dl-7p-azhd-avc-212","IsRemote":false,"ETag":"5d346bb6462a1ff319faa9296909e2ee","RunTimeTicks":24367040000,"ReadAtNativeFramerate":false,"IgnoreDts":false,"IgnoreIndex":false,"GenPtsInput":false,"SupportsTranscoding":true,"SupportsDirectStream":true,"SupportsDirectPlay":true,"IsInfiniteStream":false,"UseMostCompatibleTranscodingProfile":false,"RequiresOpening":false,"OpenToken":null,"RequiresClosing":false,"LiveStreamId":null,"BufferMs":null,"RequiresLooping":false,"SupportsProbing":true,"VideoType":0,"IsoType":null,"Video3DFormat":null,"MediaStreams":[{"Codec":"h264","CodecTag":null,"Language":null,"ColorRange":null,"ColorSpace":"bt709","ColorTransfer":"bt709","ColorPrimaries":"bt709","DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":1,"VideoRangeType":1,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":null,"LocalizedForced":null,"LocalizedExternal":null,"LocalizedHearingImpaired":null,"DisplayTitle":"720p H264 SDR","NalLengthSize":"4","IsInterlaced":false,"IsAVC":true,"ChannelLayout":null,"BitRate":5455249,"BitDepth":8,"RefFrames":1,"PacketLength":null,"Channels":null,"SampleRate":null,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Height":720,"Width":1280,"AverageFrameRate":25,"RealFrameRate":25,"ReferenceFrameRate":25,"Profile":"High","Type":1,"AspectRatio":"16:9","Index":0,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":"yuv420p","Level":31,"IsAnamorphic":false},{"Codec":"ac3","CodecTag":null,"Language":"ger","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":0,"VideoRangeType":0,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":"Standard","LocalizedForced":null,"LocalizedExternal":"Extern","LocalizedHearingImpaired":null,"DisplayTitle":"Ger - Dolby Digital - 5.1 - Standard","NalLengthSize":null,"IsInterlaced":false,"IsAVC":false,"ChannelLayout":"5.1","BitRate":448000,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":6,"SampleRate":48000,"IsDefault":true,"IsForced":false,"IsHearingImpaired":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"ReferenceFrameRate":null,"Profile":null,"Type":0,"AspectRatio":null,"Index":1,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null},{"Codec":"ac3","CodecTag":null,"Language":"eng","ColorRange":null,"ColorSpace":null,"ColorTransfer":null,"ColorPrimaries":null,"DvVersionMajor":null,"DvVersionMinor":null,"DvProfile":null,"DvLevel":null,"RpuPresentFlag":null,"ElPresentFlag":null,"BlPresentFlag":null,"DvBlSignalCompatibilityId":null,"Rotation":null,"Comment":null,"TimeBase":"1/1000","CodecTimeBase":null,"Title":null,"VideoRange":0,"VideoRangeType":0,"VideoDoViTitle":null,"AudioSpatialFormat":0,"LocalizedUndefined":null,"LocalizedDefault":"Standard","LocalizedForced":null,"LocalizedExternal":"Extern","LocalizedHearingImpaired":null,"DisplayTitle":"English - Dolby Digital - 5.1","NalLengthSize":null,"IsInterlaced":false,"IsAVC":false,"ChannelLayout":"5.1","BitRate":448000,"BitDepth":null,"RefFrames":null,"PacketLength":null,"Channels":6,"SampleRate":48000,"IsDefault":false,"IsForced":false,"IsHearingImpaired":false,"Height":null,"Width":null,"AverageFrameRate":null,"RealFrameRate":null,"ReferenceFrameRate":null,"Profile":null,"Type":0,"AspectRatio":null,"Index":2,"Score":null,"IsExternal":false,"DeliveryMethod":null,"DeliveryUrl":null,"IsExternalUrl":null,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Path":null,"PixelFormat":null,"Level":0,"IsAnamorphic":null}],"MediaAttachments":[],"Formats":[],"Bitrate":6351249,"FallbackMaxStreamingBitrate":null,"Timestamp":null,"RequiredHttpHeaders":{},"TranscodingUrl":null,"TranscodingSubProtocol":0,"TranscodingContainer":null,"AnalyzeDurationMs":null,"DefaultAudioStreamIndex":null,"DefaultSubtitleStreamIndex":null,"HasSegments":false}
/usr/lib/jellyfin-ffmpeg/ffmpeg -analyzeduration 200M -probesize 1G -ss 00:05:27.700 -noaccurate_seek -fflags +genpts -f matroska -i file:"/ganz_unten/user/ttt-nextcloud/ttt/files/Meine_Bibliothek/Filme/Psych/S02/tvs-psych-dd51-dl-7p-azhd-avc-212.mkv" -map_metadata -1 -map_chapters -1 -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 copy -bsf:v h264_mp4toannexb -start_at_zero -codec:a:0 libfdk_aac -ac 2 -ab 256000 -af "volume=2" -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 6 -hls_segment_type fmp4 -hls_fmp4_init_filename "c134c707d9557c7f05b503ff188a7e38-1.mp4" -start_number 54 -hls_segment_filename "/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38%d.mp4" -hls_playlist_type vod -hls_list_size 0 -y "/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8"
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-
ffmpeg version 7.0.2-Jellyfin Copyright © 2000-2024 the FFmpeg developers
built with gcc 11 (Ubuntu 11.4.0-1ubuntu1~22.04)
configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --extra-version=Jellyfin --disable-doc --disable-ffplay --disable-ptx-compression --disable-static --disable-libxcb --disable-sdl2 --disable-xlib --enable-lto=auto --enable-gpl --enable-version3 --enable-shared --enable-gmp --enable-gnutls --enable-chromaprint --enable-opencl --enable-libdrm --enable-libxml2 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libfontconfig --enable-libharfbuzz --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libopenmpt --enable-libdav1d --enable-libsvtav1 --enable-libwebp --enable-libvpx --enable-libx264 --enable-libx265 --enable-libzvbi --enable-libzimg --enable-libfdk-aac --arch=amd64 --enable-libshaderc --enable-libplacebo --enable-vulkan --enable-vaapi --enable-amf --enable-libvpl --enable-ffnvcodec --enable-cuda --enable-cuda-llvm --enable-cuvid --enable-nvdec --enable-nvenc
libavutil 59. 8.100 / 59. 8.100
libavcodec 61. 3.100 / 61. 3.100
libavformat 61. 1.100 / 61. 1.100
libavdevice 61. 1.100 / 61. 1.100
libavfilter 10. 1.100 / 10. 1.100
libswscale 8. 1.100 / 8. 1.100
libswresample 5. 1.100 / 5. 1.100
libpostproc 58. 1.100 / 58. 1.100
Input #0, matroska,webm, from '/tmp/tmp_pipe_1ltMmT':
Metadata:
ENCODER : Lavf61.9.102
Duration: N/A, start: -0.021000, bitrate: N/A
Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp
Stream #0:1: Video: h264 (Main), yuv420p(tv, bt709/unknown/unknown, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 1k tbn
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
[hls @ 0x644253cbf680] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38-1.mp4' for writing
Output #0, hls, to '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38.m3u8':
Metadata:
encoder : Lavf61.1.100
Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709/unknown/unknown, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 50 fps, 50 tbr, 16k tbn
Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp
Press [q] to stop, [?] for help
size=N/A time=00:00:01.40 bitrate=N/A speed=2.81x
size=N/A time=00:00:01.89 bitrate=N/A speed= 1.9x
size=N/A time=00:00:02.53 bitrate=N/A speed=1.69x
size=N/A time=00:00:03.13 bitrate=N/A speed=1.57x
size=N/A time=00:00:03.64 bitrate=N/A speed=1.46x
size=N/A time=00:00:04.24 bitrate=N/A speed=1.41x
...
[hls @ 0x644253cbf680] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38208.mp4' for writing
size=N/A time=00:15:34.29 bitrate=N/A speed= 1x
size=N/A time=00:15:34.89 bitrate=N/A speed= 1x
size=N/A time=00:15:35.48 bitrate=N/A speed=1.01x
size=N/A time=00:15:35.93 bitrate=N/A speed=1.01x
size=N/A time=00:15:36.25 bitrate=N/A speed= 1x
size=N/A time=00:15:36.61 bitrate=N/A speed= 1x
size=N/A time=00:15:37.25 bitrate=N/A speed= 1x
size=N/A time=00:15:37.77 bitrate=N/A speed= 1x
size=N/A time=00:15:38.21 bitrate=N/A speed= 1x
size=N/A time=00:15:38.77 bitrate=N/A speed= 1x
[hls @ 0x644253cbf680] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38209.mp4' for writing
size=N/A time=00:15:39.05 bitrate=N/A speed= 1x
size=N/A time=00:15:39.77 bitrate=N/A speed= 1x
size=N/A time=00:15:40.26 bitrate=N/A speed= 1x
size=N/A time=00:15:40.60 bitrate=N/A speed= 1x
size=N/A time=00:15:40.84 bitrate=N/A speed= 1x
size=N/A time=00:15:40.84 bitrate=N/A speed= 1x
size=N/A time=00:15:40.84 bitrate=N/A speed= 1x
[hls @ 0x644253cbf680] Opening '/var/cache/jellyfin/transcodes/c134c707d9557c7f05b503ff188a7e38210.mp4' for writing
[out#0/hls @ 0x644253f41bc0] video:2324591KiB audio:33146KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
size=N/A time=00:15:41.64 bitrate=N/A speed= 1x
As you see the stop times of the hls transcode is different from the time jellyfin is resuming the transcode.
So, on the first place, why the transcode is stopped, even when throtteling is disabled?
How does jellyfin internaly determine how far the transcode process was, and how does it determine at which time it should "resume" it?
I thought this would be done from the output of the ffmpeg process. But apparently this is not the case.