Skip to content

Instantly share code, notes, and snippets.

@Midtan
Last active July 17, 2024 00:01
Show Gist options
  • Save Midtan/3e1424bd9e2e9c2d3fb9d0f57d49a06b to your computer and use it in GitHub Desktop.
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.
@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
#!/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