Advertisement
EurenikZ

Batch Video Cutter & Encoder - Multi

Jul 18th, 2025 (edited)
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 6.70 KB | None | 0 0
  1. :: Dieses Skript verarbeitet alle .mp4-Dateien im aktuellen Verzeichnis, entfernt die angegebenen Sekunden vom Anfang und Ende und komprimiert sie optional per FFmpeg mit einem wählbaren CRF-Wert. Nur Videos mit ausreichender Länge (Videolänge + 3 > Schnittbereich) werden bearbeitet. Der ursprüngliche Zeitstempel der Datei bleibt erhalten, und die Ausgabedateien erhalten angepasste Namen (_cut.mp4 oder _crfXX.mp4).
  2. :: In dieser Version wird für jedes Video einzeln die Schnitt-Zeit angegeben.
  3. :: "ffmpeg-release-essentials.zip" hier herunterladen, entpacken und aus dem Ordner "bin" die ffmpeg.exe und ffprobe.exe in das Verzeichnis kopieren: https://www.gyan.dev/ffmpeg/builds/
  4. :: Version 1.0 - 18.07.2025
  5.  
  6. @echo off
  7. setlocal enabledelayedexpansion
  8.  
  9. :: Benutzerabfrage: Codec-Auswahl
  10. echo Waehle Codec:
  11. echo 1 - H.265 (libx265) - Gute Kompression, schnellere Kodierung, breite Unterstuetzung
  12. echo 2 - AV1 (libaom-av1) - Beste Kompression, aber sehr langsam, fuer neuere Geräte
  13. set /p CODECWAHL=Eingabe (1 oder 2):
  14.  
  15. if not "%CODECWAHL%"=="1" if not "%CODECWAHL%"=="2" (
  16.     echo Ungueltige Eingabe. Standard: H.265 wird verwendet.
  17.     set CODECWAHL=1
  18. )
  19.  
  20. :: CRF-Abfrage je nach Codec
  21. if "%CODECWAHL%"=="1" (
  22.     echo H.265 CRF-Wert ^(18=hoch, 25=normal, 30=niedrig, 35=sehr niedrig^) - Leer lassen = nur schneiden
  23. ) else (
  24.     echo AV1 CRF-Wert ^(24=hoch, 32=normal, 38=niedrig, 46=sehr niedrig^) - Leer lassen = nur schneiden
  25. )
  26. set /p CRF_WERT=Welcher CRF-Wert soll verwendet werden?
  27.  
  28. :: CRF-Wert prüfen falls angegeben
  29. if not "%CRF_WERT%"=="" (
  30.     for /f "delims=0123456789" %%A in ("%CRF_WERT%") do (
  31.         echo Ungueltige Eingabe bei CRF-Wert & pause & exit /b
  32.     )
  33. )
  34.  
  35. echo.
  36. echo Folgende MP4-Videos wurden gefunden:
  37. echo.
  38.  
  39. :: Zähler für Videos
  40. set VIDEO_COUNT=0
  41.  
  42. :: Alle MP4-Dateien auflisten und zählen, aber _crf-Dateien ignorieren
  43. set VIDEO_COUNT=0
  44. for %%F in (*.mp4) do (
  45.     echo %%F | findstr /i "_crf" >nul
  46.     if errorlevel 1 (
  47.         set /a VIDEO_COUNT+=1
  48.         echo !VIDEO_COUNT!: %%F
  49.     )
  50. )
  51.  
  52. if !VIDEO_COUNT! EQU 0 (
  53.     echo Keine MP4-Dateien gefunden.
  54.     pause
  55.     exit /b
  56. )
  57.  
  58. echo.
  59. echo Gib fuer jedes Video die Schnitt-Zeiten ein:
  60. echo.
  61.  
  62. :: Arrays für die Schnitt-Werte initialisieren
  63. set VIDEO_INDEX=0
  64.  
  65. :: Schleife durch alle Videos für Eingaben
  66. set VIDEO_INDEX=0
  67. for %%F in (*.mp4) do (
  68.     echo %%F | findstr /i "_crf" >nul
  69.     if errorlevel 1 (
  70.         set /a VIDEO_INDEX+=1
  71.         echo Video !VIDEO_INDEX!: %%F
  72.  
  73.         set /p "CUT_START_!VIDEO_INDEX!=Wie viele Sekunden vom ANFANG entfernen? "
  74.         if "!CUT_START_!VIDEO_INDEX!!"=="" set "CUT_START_!VIDEO_INDEX!=0"
  75.  
  76.         set /p "CUT_END_!VIDEO_INDEX!=Wie viele Sekunden vom ENDE entfernen? "
  77.         if "!CUT_END_!VIDEO_INDEX!!"=="" set "CUT_END_!VIDEO_INDEX!=0"
  78.  
  79.         :: Eingaben prüfen
  80.         call set "TMPSTART=%%CUT_START_!VIDEO_INDEX!%%"
  81.         if not "!TMPSTART!"=="" (
  82.             for /f "delims=0123456789" %%A in ("!TMPSTART!") do (
  83.                 echo Ungueltige Eingabe bei Startzeit fuer %%F & pause & exit /b
  84.             )
  85.         )
  86.  
  87.         call set "TMPEND=%%CUT_END_!VIDEO_INDEX!%%"
  88.         if not "!TMPEND!"=="" (
  89.             for /f "delims=0123456789" %%A in ("!TMPEND!") do (
  90.                 echo Ungueltige Eingabe bei Endzeit fuer %%F & pause & exit /b
  91.             )
  92.         )
  93.  
  94.         echo.
  95.     )
  96. )
  97.  
  98. echo Alle Eingaben erfasst. Beginne mit der Verarbeitung...
  99. echo.
  100.  
  101. :: Verarbeitung aller Videos
  102. set VIDEO_INDEX=0
  103. for %%F in (*.mp4) do (
  104.     echo %%F | findstr /i "_crf" >nul
  105.     if errorlevel 1 (
  106.         set /a VIDEO_INDEX+=1
  107.         echo Bearbeite Video !VIDEO_INDEX!/!VIDEO_COUNT!: %%F
  108.        
  109.         :: Aktuelle Schnitt-Werte laden
  110.         call set "CUT_START=%%CUT_START_!VIDEO_INDEX!%%"
  111.         call set "CUT_END=%%CUT_END_!VIDEO_INDEX!%%"
  112.        
  113.         :: Leere Werte auf 0 setzen
  114.         if "!CUT_START!"=="" set "CUT_START=0"
  115.         if "!CUT_END!"=="" set "CUT_END=0"
  116.        
  117.         set /a CUTS_TOTAL=!CUT_START!+!CUT_END!
  118.  
  119.         for /f "usebackq delims=" %%T in (`powershell -NoLogo -NoProfile -Command "(Get-Item '%%F').LastWriteTime.ToString('yyyy:MM:dd HH:mm:ss')"`) do (
  120.             set "TIMESTAMP=%%T"
  121.         )
  122.  
  123.         for /f "usebackq delims=" %%D in (`ffprobe -v error -select_streams v:0 -show_entries format^=duration -of default^=nokey^=1:noprint_wrappers^=1 "%%F"`) do (
  124.             set "DURATION=%%D"
  125.         )
  126.  
  127.         for /f "tokens=1 delims=." %%T in ("!DURATION!") do set /a INTDURATION=%%T
  128.  
  129.         set /a VIDEO_PLUS_3=!INTDURATION!+3
  130.  
  131.         if !VIDEO_PLUS_3! GTR !CUTS_TOTAL! (
  132.             set /a REMAINING=!INTDURATION!-!CUTS_TOTAL!
  133.             if !REMAINING! GEQ 1 (
  134.                 set "OUTFILE=%%~nF"
  135.  
  136.                 if "%CRF_WERT%"=="" (
  137.                     set "OUTFILE=!OUTFILE!_cut.mp4"
  138.                     if !CUTS_TOTAL! GTR 0 (
  139.                         ffmpeg -y -i "%%F" -ss !CUT_START! -t !REMAINING! -c copy "!OUTFILE!"
  140.                     ) else (
  141.                         :: Nur kopieren wenn kein Schnitt nötig
  142.                         copy "%%F" "!OUTFILE!"
  143.                     )
  144.                 ) else (
  145.                     if "%CODECWAHL%"=="1" (
  146.                         set "OUTFILE=!OUTFILE!_crf!CRF_WERT!.mp4"
  147.                         if !CUTS_TOTAL! GTR 0 (
  148.                             ffmpeg -y -ss !CUT_START! -i "%%F" -t !REMAINING! -c:v libx265 -crf !CRF_WERT! -preset slow -movflags +faststart -c:a aac -b:a 160k "!OUTFILE!"
  149.                         ) else (
  150.                             :: Nur neu kodieren ohne Schnitt
  151.                             ffmpeg -y -i "%%F" -c:v libx265 -crf !CRF_WERT! -preset slow -movflags +faststart -c:a aac -b:a 160k "!OUTFILE!"
  152.                         )
  153.                     ) else (
  154.                         :: AV1 - CPU-Used dynamisch bestimmen
  155.                         if !CRF_WERT! LEQ 20 (
  156.                             set "CPU_USED=2"
  157.                         ) else if !CRF_WERT! LEQ 28 (
  158.                             set "CPU_USED=4"
  159.                         ) else if !CRF_WERT! LEQ 35 (
  160.                             set "CPU_USED=6"
  161.                         ) else (
  162.                             set "CPU_USED=8"
  163.                         )
  164.                         set "OUTFILE=!OUTFILE!_AV1_crf!CRF_WERT!.mp4"
  165.                         if !CUTS_TOTAL! GTR 0 (
  166.                             ffmpeg -y -ss !CUT_START! -i "%%F" -t !REMAINING! -c:v libaom-av1 -crf !CRF_WERT! -cpu-used !CPU_USED! -movflags +faststart -c:a aac -b:a 160k "!OUTFILE!"
  167.                         ) else (
  168.                             :: Nur neu kodieren ohne Schnitt
  169.                             ffmpeg -y -i "%%F" -c:v libaom-av1 -crf !CRF_WERT! -cpu-used !CPU_USED! -movflags +faststart -c:a aac -b:a 160k "!OUTFILE!"
  170.                         )
  171.                     )
  172.                 )
  173.  
  174.                 :: Dateizeit zurücksetzen
  175.                 powershell -NoLogo -NoProfile -Command "(Get-Item '!OUTFILE!').LastWriteTimeUtc = [datetime]::ParseExact('!TIMESTAMP!', 'yyyy:MM:dd HH:mm:ss', $null)"
  176.                 echo ? Fertig: !OUTFILE! - !REMAINING!s uebrig
  177.  
  178.                 :: NTFS-Zeit via ExifTool in Metadaten schreiben
  179.                 exiftool.exe -overwrite_original ^
  180.                     "-DateTimeOriginal=!TIMESTAMP!" ^
  181.                     "-CreateDate=!TIMESTAMP!" ^
  182.                     "-ModifyDate=!TIMESTAMP!" ^
  183.                     "-TrackCreateDate=!TIMESTAMP!" ^
  184.                     "-TrackModifyDate=!TIMESTAMP!" ^
  185.                     "-MediaCreateDate=!TIMESTAMP!" ^
  186.                     "-MediaModifyDate=!TIMESTAMP!" ^
  187.                     "-FileCreateDate=!TIMESTAMP!" ^
  188.                     "-FileModifyDate=!TIMESTAMP!" ^
  189.                     "!OUTFILE!"
  190.  
  191.             ) else (
  192.                 echo ? Uebersprungen: %%F - nur !REMAINING!s wuerden uebrig bleiben
  193.             )
  194.         ) else (
  195.             echo ? Uebersprungen: %%F - !VIDEO_PLUS_3! nicht > !CUTS_TOTAL!
  196.         )
  197.     )
  198. )
  199.  
  200. echo.
  201. echo Alle Videos wurden verarbeitet.
  202. pause
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement