diff --git a/ffmpeg b/ffmpeg new file mode 100755 index 0000000..430a70b --- /dev/null +++ b/ffmpeg @@ -0,0 +1,50 @@ +#!/bin/bash + +LOGFILE="/home/sandro/m3u/livetv_log.txt" +ARGS=("$@") +IS_LIVE=false +MODIFIED="NEIN" + +for arg in "${ARGS[@]}"; do + if [[ "$arg" == rtsp://* ]] || [[ "$arg" == http://* && "$arg" == *m3u8* ]]; then + IS_LIVE=true + break + fi +done + +if [ "$IS_LIVE" = true ]; then + # Wir bauen die ARGS komplett neu, um die Positionierung zu garantieren + NEW_ARGS=() + FOUND_AUDIO=false + + for i in "${!ARGS[@]}"; do + # Wenn wir das Ziel-File erreichen (letztes Argument), + # fügen wir unsere Spezial-Parameter davor ein. + if [ $i -eq $((${#ARGS[@]} - 1)) ]; then + # Wenn bisher kein Audio-Codec gefunden wurde, erzwingen wir Video + Audio Mapping + if [ "$FOUND_AUDIO" = false ]; then + # -map 0:v:0 -> Nimm das erste Video-Signal + # -map 0:a:0? -> Nimm das erste Audio-Signal (falls vorhanden) + NEW_ARGS+=("-map" "0:v:0" "-map" "0:a:0?" "-codec:a:0" "libfdk_aac" "-b:a" "128k") + MODIFIED="JA (Full Map + fdk_aac)" + fi + fi + + # Aktuelles Argument hinzufügen + NEW_ARGS+=("${ARGS[$i]}") + + # Prüfen, ob Jellyfin schon Audio-Parameter liefert (falls ja, ersetzen wir sie) + if [[ "${ARGS[$i]}" == "-codec:a:0" || "${ARGS[$i]}" == "-c:a" ]]; then + # Der Codec ist immer das NÄCHSTE Element im Array + # Das wird im nächsten Schleifendurchlauf durch den Check oben überschrieben oder wir machen es hier: + # Da das Skript komplexer wird, belassen wir es beim "Erzwingen"-Ansatz, + # da dein Log zeigt, dass Jellyfin es eh vergisst. + FOUND_AUDIO=true + fi + done + ARGS=("${NEW_ARGS[@]}") +fi + +echo "[$(date '+%Y-%m-%d %H:%M:%S')] Live: $IS_LIVE | Mod: $MODIFIED | Cmd: ${ARGS[*]}" >> "$LOGFILE" + +exec /usr/lib/jellyfin-ffmpeg/ffmpeg.original "${ARGS[@]}" diff --git a/livetv_log.txt b/livetv_log.txt new file mode 100644 index 0000000..75bfe41 --- /dev/null +++ b/livetv_log.txt @@ -0,0 +1,33 @@ +[2026-03-17 09:03:31] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:/mnt/cf_media2/Animeserien/Yu-Gi-Oh (1998)/S01/Yu.Gi.Oh.S01E44.German.EAC3.SD.WebDL.x264-Pudding-sama.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 -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 8b55d8044f61fea0ff47672f060aeb50-1.mp4 -start_number 0 -hls_segment_filename /var/cache/jellyfin/transcodes/8b55d8044f61fea0ff47672f060aeb50%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/8b55d8044f61fea0ff47672f060aeb50.m3u8 +[2026-03-17 09:03:54] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:/mnt/cf_media2/Animeserien/Yu-Gi-Oh (1998)/S01/Yu.Gi.Oh.S01E44.German.EAC3.SD.WebDL.x264-Pudding-sama.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 -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 65aff3a6ce50d5c06f8dbe9b4b57dd67-1.mp4 -start_number 0 -hls_segment_filename /var/cache/jellyfin/transcodes/65aff3a6ce50d5c06f8dbe9b4b57dd67%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/65aff3a6ce50d5c06f8dbe9b4b57dd67.m3u8 +[2026-03-17 09:04:11] Live-TV: true | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -analyzeduration 3000000 -probesize 1G -rtsp_transport tcp+udp -rtsp_flags prefer_tcp -fflags +genpts -f rtsp -i rtsp://localhost:8554/live/1_0 -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 copy -start_at_zero -flags -global_header -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url hls/8eb2b0fd917ba1477a37d571b0cb99cd/ -hls_segment_filename /var/cache/jellyfin/transcodes/8eb2b0fd917ba1477a37d571b0cb99cd%d.ts -hls_playlist_type event -hls_list_size 0 -y /var/cache/jellyfin/transcodes/8eb2b0fd917ba1477a37d571b0cb99cd.m3u8 +[2026-03-17 09:07:02] Live-TV: true | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -analyzeduration 3000000 -probesize 1G -rtsp_transport tcp+udp -rtsp_flags prefer_tcp -fflags +genpts -f rtsp -i rtsp://localhost:8554/live/1_0 -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 copy -start_at_zero -flags -global_header -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url hls/7a69cebda8ead565116af1ec9412ffff/ -hls_segment_filename /var/cache/jellyfin/transcodes/7a69cebda8ead565116af1ec9412ffff%d.ts -hls_playlist_type event -hls_list_size 0 -y /var/cache/jellyfin/transcodes/7a69cebda8ead565116af1ec9412ffff.m3u8 +[2026-03-17 09:07:37] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -version +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -decoders +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -encoders +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -filters +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=scale_cuda +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=tonemap_cuda +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=tonemap_opencl +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=overlay_opencl +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=overlay_vaapi +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=overlay_vulkan +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=transpose_opencl +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=overlay_opencl +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h filter=overlay_cuda +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h bsf=hevc_metadata +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h bsf=hevc_metadata +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h bsf=av1_metadata +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h bsf=av1_metadata +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -h bsf=dovi_rpu +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -hwaccels +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -version +[2026-03-17 09:07:38] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -hide_banner -f lavfi -i nullsrc=s=1x1:d=10000 -f null - +[2026-03-17 09:07:39] Live-TV: false | Modifiziert: NEIN | Command: /usr/lib/jellyfin-ffmpeg/ffmpeg.original -loglevel quiet -hwaccel_flags +low_priority -hide_banner -f lavfi -i nullsrc=s=1x1:d=100 -f null - +[2026-03-17 09:08:25] Live: true | Mod: JA (Audio-Mapping erzwungen) | Cmd: -analyzeduration 3000000 -probesize 1G -rtsp_transport tcp+udp -rtsp_flags prefer_tcp -fflags +genpts -f rtsp -i rtsp://localhost:8554/live/1_0 -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 copy -start_at_zero -flags -global_header -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url hls/c00878d04cff12fc24b39269a84bb271/ -hls_segment_filename /var/cache/jellyfin/transcodes/c00878d04cff12fc24b39269a84bb271%d.ts -hls_playlist_type event -hls_list_size 0 -y -map 0:a:0? -codec:a:0 libfdk_aac -b:a 128k /var/cache/jellyfin/transcodes/c00878d04cff12fc24b39269a84bb271.m3u8 +[2026-03-17 09:08:40] Live: true | Mod: JA (Audio-Mapping erzwungen) | Cmd: -analyzeduration 3000000 -probesize 1G -rtsp_transport tcp+udp -rtsp_flags prefer_tcp -fflags +genpts -f rtsp -i rtsp://localhost:8554/live/1_0 -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 copy -start_at_zero -flags -global_header -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url hls/acb1ac49cd1ad2b458ce02e386cd70e0/ -hls_segment_filename /var/cache/jellyfin/transcodes/acb1ac49cd1ad2b458ce02e386cd70e0%d.ts -hls_playlist_type event -hls_list_size 0 -y -map 0:a:0? -codec:a:0 libfdk_aac -b:a 128k /var/cache/jellyfin/transcodes/acb1ac49cd1ad2b458ce02e386cd70e0.m3u8 +[2026-03-17 09:08:58] Live: false | Mod: NEIN | Cmd: -analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:/mnt/cf_media2/Serien/Wer stiehlt mir die Show/Wer.stiehlt.mir.die.Show.S11E01.German.1080p.WEBHD.x264-FoST/wer_stiehlt_mir_die_show_S11E01_german_1080p.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 copy -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 ffff2306e16f9f94cedce3e3da1616b9-1.mp4 -start_number 0 -hls_segment_filename /var/cache/jellyfin/transcodes/ffff2306e16f9f94cedce3e3da1616b9%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/ffff2306e16f9f94cedce3e3da1616b9.m3u8 +[2026-03-17 09:08:59] Live: false | Mod: NEIN | Cmd: -analyzeduration 200M -probesize 1G -ss 01:01:48.500 -noaccurate_seek -fflags +genpts -f matroska -i file:/mnt/cf_media2/Serien/Wer stiehlt mir die Show/Wer.stiehlt.mir.die.Show.S11E01.German.1080p.WEBHD.x264-FoST/wer_stiehlt_mir_die_show_S11E01_german_1080p.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 copy -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 ffff2306e16f9f94cedce3e3da1616b9-1.mp4 -start_number 618 -hls_segment_filename /var/cache/jellyfin/transcodes/ffff2306e16f9f94cedce3e3da1616b9%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/ffff2306e16f9f94cedce3e3da1616b9.m3u8 +[2026-03-17 09:10:24] Live: true | Mod: JA (Full Map + fdk_aac) | Cmd: -analyzeduration 3000000 -probesize 1G -rtsp_transport tcp+udp -rtsp_flags prefer_tcp -fflags +genpts -f rtsp -i rtsp://localhost:8554/live/1_0 -map_metadata -1 -map_chapters -1 -threads 0 -sn -codec:v:0 copy -start_at_zero -flags -global_header -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time 3 -hls_segment_type mpegts -start_number 0 -hls_base_url hls/d35382e7f1301d15ab1d04c9bfd7d9dc/ -hls_segment_filename /var/cache/jellyfin/transcodes/d35382e7f1301d15ab1d04c9bfd7d9dc%d.ts -hls_playlist_type event -hls_list_size 0 -y -map 0:v:0 -map 0:a:0? -codec:a:0 libfdk_aac -b:a 128k /var/cache/jellyfin/transcodes/d35382e7f1301d15ab1d04c9bfd7d9dc.m3u8 +[2026-03-17 09:10:38] Live: false | Mod: NEIN | Cmd: -analyzeduration 200M -probesize 1G -fflags +genpts -f matroska -i file:/mnt/cf_media2/Serien/Wer stiehlt mir die Show/Wer.stiehlt.mir.die.Show.S11E01.German.1080p.WEBHD.x264-FoST/wer_stiehlt_mir_die_show_S11E01_german_1080p.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 copy -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 81805f3486446efb0dabf9fafd74a9cb-1.mp4 -start_number 0 -hls_segment_filename /var/cache/jellyfin/transcodes/81805f3486446efb0dabf9fafd74a9cb%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/81805f3486446efb0dabf9fafd74a9cb.m3u8 +[2026-03-17 09:10:38] Live: false | Mod: NEIN | Cmd: -analyzeduration 200M -probesize 1G -ss 01:02:00.500 -noaccurate_seek -fflags +genpts -f matroska -i file:/mnt/cf_media2/Serien/Wer stiehlt mir die Show/Wer.stiehlt.mir.die.Show.S11E01.German.1080p.WEBHD.x264-FoST/wer_stiehlt_mir_die_show_S11E01_german_1080p.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 copy -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 81805f3486446efb0dabf9fafd74a9cb-1.mp4 -start_number 620 -hls_segment_filename /var/cache/jellyfin/transcodes/81805f3486446efb0dabf9fafd74a9cb%d.mp4 -hls_playlist_type vod -hls_list_size 0 -hls_segment_options movflags=+frag_discont -y /var/cache/jellyfin/transcodes/81805f3486446efb0dabf9fafd74a9cb.m3u8