Last active
July 17, 2024 00:01
-
-
Save Midtan/3e1424bd9e2e9c2d3fb9d0f57d49a06b to your computer and use it in GitHub Desktop.
Very simple script to shortcut some toolchain on windows. Handles audio tracks, audio merging, re-encoding, resizing, hardcoding included ass subtitles. Also includes a bash version that hasn't been extensively tested at all. Might've even been generated through ChatGPT. Honestly can't remember. Use at own risk.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
setlocal enabledelayedexpansion | |
REM Check if a file is provided | |
if "%~1"=="" ( | |
echo No file provided. Drag and drop a video file on this script. | |
exit /b 1 | |
) | |
set "VIDEO_FILE=%~1" | |
set "OUTPUT_FILE=%~n1.mp4" | |
REM Initialize ffmpeg arguments | |
set "ffmpeg_args=-i "%VIDEO_FILE%"" | |
set "map_args=" | |
set "filter_complex_args=" | |
set "subtitle_args=" | |
set "last_vfilter_track=0:v" | |
set "audio_codec=copy" | |
set "encode_settings=-crf 20 -preset veryslow" | |
REM Check for audio tracks | |
for /f %%i in ('ffmpeg -i "%VIDEO_FILE%" 2^>^&1 ^| find "Stream" ^| find /c "Audio:"') do set /a AUDIO_TRACKS=%%i | |
REM Handle audio tracks | |
if !AUDIO_TRACKS! GTR 1 ( | |
echo The video has multiple audio tracks. Choose an option: | |
echo [1] Include all tracks [default] | |
echo [2] Select specific tracks | |
echo [3] Merge all tracks | |
set /p "AUDIO_CHOICE=Enter your choice: " | |
if "!AUDIO_CHOICE!"=="2" ( | |
REM Specific track | |
set /a counteraudio=0 | |
for /f "tokens=*" %%a in ('ffmpeg -i "!VIDEO_FILE!" 2^>^&1 ^| findstr /i "Stream" ^| findstr /i "Audio:"') do ( | |
echo [!counteraudio!] %%a | |
set /a counteraudio+=1 | |
) | |
set /p "AUDIO_TRACK_INPUTS=Enter the track numbers separated by spaces (e.g., 0 2 4) to include them (0 is default): " | |
for %%i in (!AUDIO_TRACK_INPUTS!) do ( | |
set "map_args=!map_args! -map 0:a:%%i" | |
) | |
) else if "!AUDIO_CHOICE!"=="3" ( | |
REM Merge tracks | |
set "filter_complex_args=[0:a]amerge=inputs=!AUDIO_TRACKS![a];" | |
set "map_args=!map_args! -map [a]" | |
set "audio_codec=aac" | |
) else ( | |
set "map_args=!map_args! -map 0:a" | |
) | |
REM somehow the last else is getting executed so maybe this works | |
goto :subtitles | |
) else ( | |
echo No more than one audio track found | |
set "map_args=!map_args! -map 0:a" | |
) | |
:subtitles | |
REM Check for subtitle tracks | |
for /f %%i in ('ffmpeg -i "%VIDEO_FILE%" 2^>^&1 ^| find "Stream" ^| find /c "Subtitle:"') do set /a SUBTITLE_TRACKS=%%i | |
REM Handle subtitle tracks | |
if !SUBTITLE_TRACKS! GTR 0 ( | |
set /p "SUB_CHOICE=The video has subtitles. Include them? (Y/n): " | |
if not defined SUB_CHOICE set "SUB_CHOICE=y" | |
if /i "!SUB_CHOICE!"=="y" ( | |
set /a countersubs=0 | |
for /f "tokens=*" %%a in ('ffmpeg -i "%VIDEO_FILE%" 2^>^&1 ^| findstr /i "Stream" ^| findstr /i "Subtitle:"') do ( | |
echo [!countersubs!] %%a | |
set /a countersubs+=1 | |
) | |
if !SUBTITLE_TRACKS! GTR 1 ( | |
set /p "SUB_TRACK_NUM=Enter the subtitle track number (0, 1, etc.) (0 is default): " | |
if not defined SUB_TRACK_NUM set "SUB_TRACK_NUM=0" | |
) else ( | |
set "SUB_TRACK_NUM=0" | |
) | |
REM Escaping colons and backslashes | |
set "filePath=%VIDEO_FILE:\=\\%" | |
set "filePath=!filePath::=\:!" | |
set "filter_complex_args=!filter_complex_args![!last_vfilter_track!]subtitles='!filePath!'\:si=!SUB_TRACK_NUM![vsub];" | |
set "last_vfilter_track=vsub" | |
) | |
) | |
REM Ask for re-encoding | |
if /i not "!SUB_CHOICE!"=="y" ( | |
set /p "REENCODE_CHOICE=Do you want to re-encode the video? (y/N): " | |
) else ( | |
set "REENCODE_CHOICE=y" | |
) | |
if /i "!REENCODE_CHOICE!"=="y" ( | |
set /p "VERTICAL_RES=Enter target vertical resolution (default or 0 for 'as is'): " | |
if not defined VERTICAL_RES set "VERTICAL_RES=0" | |
if !VERTICAL_RES! GTR 0 ( | |
set "filter_complex_args=!filter_complex_args![!last_vfilter_track!]scale=-1:!VERTICAL_RES![vscale];" | |
set "last_vfilter_track=vscale" | |
) | |
) | |
REM Final ffmpeg command | |
set "map_args=!map_args! -map [!last_vfilter_track!]" | |
set "ffmpeg_cmd=ffmpeg !ffmpeg_args! !map_args! !subtitle_args!" | |
if not "!filter_complex_args!"=="" ( | |
set "ffmpeg_cmd=!ffmpeg_cmd! -filter_complex "!filter_complex_args:~0,-1!"" | |
) | |
if /i "!REENCODE_CHOICE!"=="y" ( | |
set "ffmpeg_cmd=!ffmpeg_cmd! -c:v libx264 %encode_settings% -c:a !audio_codec! "!OUTPUT_FILE!"" | |
) else ( | |
set "ffmpeg_cmd=!ffmpeg_cmd! -c:v copy -c:a !audio_codec! "!OUTPUT_FILE!"" | |
) | |
REM Execute the command | |
echo !ffmpeg_cmd! | |
!ffmpeg_cmd! | |
echo Video processing completed. Output file: %OUTPUT_FILE% | |
pause |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Check if a file is provided | |
if [ $# -eq 0 ]; then | |
echo "No file provided. Drag and drop a video file on this script." | |
exit 1 | |
fi | |
VIDEO_FILE="$1" | |
OUTPUT_FILE="${VIDEO_FILE%.*}.mp4" | |
# Initialize ffmpeg arguments | |
ffmpeg_args="-i \"$VIDEO_FILE\"" | |
map_args="" | |
filter_complex_args=() | |
subtitle_args="" | |
last_vfilter_track="0:v" | |
audio_codec="copy" | |
encode_settings="-crf 20 -preset veryslow" | |
# Extract audio tracks | |
AUDIO_TRACKS=$(ffmpeg -i "$VIDEO_FILE" 2>&1 | grep "Stream.*Audio:" | wc -l) | |
# Handle audio tracks | |
if [ "$AUDIO_TRACKS" -gt 1 ]; then | |
AUDIO_CHOICE=1 | |
echo "The video has multiple ($AUDIO_TRACKS) audio tracks. Choose an option:" | |
echo " [1] Include all tracks (default)" | |
echo " [2] Select specific tracks" | |
echo " [3] Merge all tracks" | |
read -p "Enter your choice: " AUDIO_CHOICE | |
case $AUDIO_CHOICE in | |
1) # All tracks | |
map_args="$map_args -map 0:a" | |
;; | |
2) # Specific track | |
ffmpeg -i "$VIDEO_FILE" 2>&1 | grep "Stream.*Audio:" | awk '{print NR-1, $0}' | |
read -p "Enter the track numbers separated by spaces (e.g., 0 2 4) to include them (0 is default): " AUDIO_TRACK_INPUTS | |
IFS=' ' read -r -a AUDIO_TRACK_ARRAY <<< "$AUDIO_TRACK_INPUTS" | |
for i in "${AUDIO_TRACK_ARRAY[@]}" | |
do | |
map_args="$map_args -map 0:a:$i" | |
done | |
;; | |
3) # Merge tracks | |
filter_complex_args+=("[0:a]amerge=inputs=$AUDIO_TRACKS[a]") | |
map_args="$map_args -map '[a]'" | |
audio_codec="aac" | |
;; | |
esac | |
else | |
map_args="$map_args -map 0:a" | |
fi | |
# Check for subtitle tracks | |
SUBTITLE_TRACKS=$(ffmpeg -i "$VIDEO_FILE" 2>&1 | grep "Stream.*Subtitle:" | wc -l) | |
# Handle subtitle tracks | |
if [ "$SUBTITLE_TRACKS" -gt 0 ]; then | |
read -p "The video has subtitles. Include them? (Y/n): " SUB_CHOICE | |
if [ -z "$SUB_CHOICE" ] || [ "$SUB_CHOICE" == "y" ]; then | |
SUB_CHOICE="y" | |
ffmpeg -i "$VIDEO_FILE" 2>&1 | grep "Stream.*Subtitle:" | awk '{print NR-1, $0}' | |
if [ "$SUBTITLE_TRACKS" -gt 1 ]; then | |
read -p "Enter the subtitle track number (0, 1, etc.) (0 is default): " SUB_TRACK_NUM | |
if [ -z "$SUB_TRACK_NUM" ]; then | |
SUB_TRACK_NUM=0 | |
fi | |
filter_complex_args+=("[$last_vfilter_track]subtitles='$VIDEO_FILE':si=$SUB_TRACK_NUM[vsub]") | |
last_vfilter_track="vsub" | |
else | |
filter_complex_args+=("[$last_vfilter_track]subtitles='$VIDEO_FILE':si=0[vsub]") | |
last_vfilter_track="vsub" | |
fi | |
fi | |
fi | |
# Ask for re-encoding | |
REENCODE_CHOICE="y" | |
if [ "$SUB_CHOICE" != "y" ]; then | |
read -p "Do you want to re-encode the video? (y/N): " REENCODE_CHOICE | |
fi | |
if [ ! -z "$REENCODE_CHOICE" ] && [ "$REENCODE_CHOICE" == "y" ]; then | |
read -p "Enter target vertical resolution (default or 0 for 'as is'): " VERTICAL_RES | |
if [ ! -z "$VERTICAL_RES" ] && [ "$VERTICAL_RES" -gt 0 ]; then | |
filter_complex_args+=("[$last_vfilter_track]scale=-1:$VERTICAL_RES[vscale]") | |
last_vfilter_track="vscale" | |
fi | |
fi | |
# Final ffmpeg command | |
map_args="$map_args -map '[$last_vfilter_track]'" | |
ffmpeg_cmd="ffmpeg $ffmpeg_args $map_args $subtitle_args" | |
if [ ${#filter_complex_args[@]} -gt 0 ]; then | |
filter_complex_args_string=$(printf ";%s" "${filter_complex_args[@]}") | |
filter_complex_args_string=${filter_complex_args_string:1} | |
ffmpeg_cmd="$ffmpeg_cmd -filter_complex \"$filter_complex_args_string\"" | |
fi | |
if [ "$REENCODE_CHOICE" == "y" ]; then | |
ffmpeg_cmd="$ffmpeg_cmd -c:v libx264 $encode_settings -c:a $audio_codec \"$OUTPUT_FILE\"" | |
else | |
ffmpeg_cmd="$ffmpeg_cmd -c:v copy -c:a $audio_codec \"$OUTPUT_FILE\"" | |
fi | |
# Execute the command | |
echo $ffmpeg_cmd | |
eval $ffmpeg_cmd | |
read -p "Video processing completed. Output file: $OUTPUT_FILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment