Add some new video scripts and improve existing ones

This commit is contained in:
Michael Campagnaro 2023-07-14 17:29:36 -04:00
parent 515a9f479a
commit f636229f5c
11 changed files with 251 additions and 26 deletions

View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Use this to get a report on the video audio volume. You can use this info
# manually normalize or increase/decrease a video's volume using the
# change-video-volume script, supplying it the volume delta you want. Typically
# you use the delta from the analysis report this script provides, e.g. if the
# max_volume is -5 db then you would call change-video-volume with a value of
# 5. I find that the two pass normalize-video-audio script works better than
# this approach...but it will take longer to run!
#
# Inspired by https://superuser.com/a/323127 and https://superuser.com/a/1312885
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
MAGENTA=""
CYAN=""
BOLD=""
NORMAL=""
fi
if [[ $1 == "" ]]; then
printf "${BOLD}${RED}Usage: analyze-video-volume <video filename>${NORMAL}\n"
exit 1
fi
filename="$1"
printf "\n${YELLOW}${BOLD}Analyzing audio in $filename${NORMAL}\n"
# -vn, -sn, and -dn tells ffmpeg to ignore non-audio streams during the analysis. This speeds things up.
cmd="ffmpeg -i \"$filename\" -af volumedetect -vn -sn -dn -f null /dev/null"
printf "\n${BOLD}Running: $cmd\n\n${NORMAL}"
eval $cmd
printf "\n${GREEN}${BOLD}Done analyzing audio in $filename\n${NORMAL}"
printf "\n${YELLOW}${BOLD}Look at the reported max_volume value. If != 0 then call the change-video-volume script, passing it the filename, an output name and the delta to bring the volume to 0.\ne.g. if the max_volume is -5 db, then you would pass 5.${NORMAL}\n\n"

View File

@ -7,8 +7,7 @@ if not "%1"=="am_admin" (
exit /b exit /b
) )
rem USE AT OWN RISK AS IS WITHOUT WARRANTY OF ANY KIND !!!!! rem NOTE: Defender may see this file as malware, so you might need to exclude this before things can be disabled.
rem NOTE: Defender may see this file as malware, so you will likely need to exclude this before things can be disabled.
rem rem
rem Modified version of rem Modified version of
rem https://raw.githubusercontent.com/mattreecebentley/win10_disable_defender/main/win10_enable_defender.bat rem https://raw.githubusercontent.com/mattreecebentley/win10_disable_defender/main/win10_enable_defender.bat
@ -104,4 +103,4 @@ echo Defender has already been disabled by this script.
:eof :eof
echo. echo.
pause pause

View File

@ -105,4 +105,4 @@ echo Defender has already been enabled by this script.
:eof :eof
echo. echo.
pause pause

View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Re-encodes the audio, modify the volume based on the supplied db delta. The
# video is copied as-is. If you want to bring the max_volume to 0 db then call
# analyze-video-volume prior to this and pass a delta based on the reported
# max_volume.
#
# Inspired by https://superuser.com/a/323127 and https://superuser.com/a/1312885
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
MAGENTA=""
CYAN=""
BOLD=""
NORMAL=""
fi
if [[ $1 == "" ]]; then
printf "${BOLD}${RED}Usage: change-video-volume <filename> <output name> <volume delta in db>${NORMAL}\n"
exit 1
fi
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
output_name="$2"
delta_db="$3"
if [[ $output_name == "" ]]; then
output="${filename}_normalized_audio.$extension"
else
output="${output_name}.$extension"
fi
printf "\n${YELLOW}${BOLD}Modifying audio volume in $filename.$extension | output: $output | delta: $delta_db${NORMAL}\n"
# Since we're re-encoding the audio we have to specify a codec to use.
cmd="ffmpeg -i \"$filename.$extension\" -af \"volume=${delta_db}dB\" -c:v copy -c:a aac -map 0 \"$output\""
printf "\n${BOLD}Running: $cmd\n\n${NORMAL}"
eval $cmd
printf "\n${GREEN}${BOLD}Done modifying volume in $filename.$extension | output: $output | delta: $delta_db${NORMAL}\n"

View File

@ -0,0 +1,63 @@
#!/usr/bin/env bash
# Adds subtitles to a video. You can pass multiple srt files in one go. This
# preserves all existing streams, so if you've already added subtitle tracks to
# the video then these new ones will be appended. I haven't extensively tested
# appending yet (not sure if the mapping arg is correct), so I recommend adding
# all of your tracks in one go.
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
MAGENTA=""
CYAN=""
BOLD=""
NORMAL=""
fi
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
output_name="$2"
output="${output_name}.$extension"
shift 2
subtitles=("$@")
if [[ $filename == "" || $output_name == "" || ${#subtitles[@]} -eq 0 ]]; then
printf "${BOLD}${RED}Usage: embed-subtitles <video filename> <output name> <subtitle filenames>${NORMAL}\n"
exit 1
fi
printf "\n${YELLOW}${BOLD}Adding subtitles to $filename.$extension | output: $output${NORMAL}\n"
mapping="-map 0"
tracks=""
map_index=1
for track in "$@"; do
tracks+="-i \"$track\" "
mapping+=" -map $map_index"
map_index=$((map_index+1))
done
cmd="ffmpeg -i \"$filename.$extension\" $tracks $mapping -c copy -c:s mov_text \"$output\""
printf "\n${BOLD}Running: $cmd\n\n${NORMAL}"
eval $cmd
printf "\n${GREEN}${BOLD}Done adding subtitles to $filename.$extension | output: $output\n${NORMAL}"

View File

@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Re-encodes the video to get a more accurate timeline. If you want fast video joining at the expense of accuracy then use join-video-fast.
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
ncolors=$(tput colors) ncolors=$(tput colors)
fi fi
@ -35,7 +37,7 @@ output="${output_name}.mp4"
printf "\n${YELLOW}${BOLD}Joining contents of '$filename'| output: $output${NORMAL}\n" printf "\n${YELLOW}${BOLD}Joining contents of '$filename'| output: $output${NORMAL}\n"
ffmpeg -f concat -safe 0 -i "$filename" -c copy "$output" ffmpeg -f concat -safe 0 -accurate_seek -i "$filename.$extension" -c:v libx264 -c:a copy "$output"
printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n"

View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
# A fast way to join video clips that might result in some weird playback cursor timings,
# e.g. video player might show negative seconds at the start of the vid or the
# playback time might oscillate a bit. Use join-video for accurate joining at
# the cost of a much slower processing time.
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BLUE="$(tput setaf 4)"
MAGENTA="$(tput setaf 5)"
CYAN="$(tput setaf 6)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
MAGENTA=""
CYAN=""
BOLD=""
NORMAL=""
fi
filename=$(basename -- "$1")
output_name="$2"
if [[ $filename == "" || $output_name == "" ]]; then
printf "${BOLD}${RED}Usage: create a text file that lists the input video paths on separate lines using the format: file '/path/to/video'. Then call:\n\n$0 <list name> <output name>${NORMAL}\n"
exit 1
fi
output="${output_name}.mp4"
printf "\n${YELLOW}${BOLD}Joining contents of '$filename'| output: $output${NORMAL}\n"
ffmpeg -f concat -safe 0 -i "$filename" -c copy "$output"
printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n"

View File

@ -52,9 +52,6 @@ output_name_without_ext="$2"
model="$3" model="$3"
threads=$4 threads=$4
# 4 seems to be the sweet spot for most models, except medium might be faster with 8.
default_thread_count=4
if [[ $input_wav == "" || $output_name_without_ext == "" || $model == "" ]]; then if [[ $input_wav == "" || $output_name_without_ext == "" || $model == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <input.wav> <output name without extension> <model name> <optional: thread count>${NORMAL}\n" printf "${BOLD}${RED}Usage: $0 <input.wav> <output name without extension> <model name> <optional: thread count>${NORMAL}\n"
exit 1 exit 1
@ -65,19 +62,27 @@ if [[ ! -f "$input_wav" ]]; then
exit 1 exit 1
fi fi
if [[ $threads == "" ]]; then
threads=$default_thread_count
fi
output_name="$output_name_without_ext.${model}" output_name="$output_name_without_ext.${model}"
# 1 core 31 threads has very fast pcm_to_mel conversion and then just one core doing most of the work. You get more accurate results this way. # 1 core 31 threads has very fast pcm_to_mel conversion and then just one core doing most of the work. You get more accurate results this way.
# 2 core 16 is about half the time but it can have errors where the two pieces come together. This only gets more likely as the core count is increased. # 2 core 16 is about half the time but it can have errors where the two pieces come together. This only gets more likely as the core count is increased.
# 8 threads, 4 cores is good too for tiny,small and 2 threads, 4 cores for medium. # 8 threads, 4 cores is good too for tiny,small and 2 threads, 4 cores for medium.
threads=31 #keep a thread for me
# 4 seems to be the sweet spot for most models, except medium might be faster with 8.
# But on my 5950x, running 1 core with 31 threads is quite fast.
#default_thread_count=4
cores=1 cores=1
default_thread_count=31
if [[ $threads == "" ]]; then
threads=$default_thread_count
# This is only useful when not setting the core count and defaulting to 4 threads.
#if [[ $model == "medium" || $model == "large" ]]; then
# threads=8
#fi
fi
printf "\n${YELLOW}${BOLD}Transcribing $input_wav | model: $model | cores: $cores | threads: $threads | output: $output_name ${NORMAL}\n" printf "\n${YELLOW}${BOLD}Transcribing $input_wav | model: $model | cores: $cores | threads: $threads | output: $output_name ${NORMAL}\n"

View File

@ -47,13 +47,7 @@ extract-16bit-wav-from-video "$input_video" "$wav_name"
if [[ $? == 1 ]]; then exit 1; fi if [[ $? == 1 ]]; then exit 1; fi
for model in "$@"; do for model in "$@"; do
# Tweak thread count based on model size. transcribe-audio "$wav_name" "$output_name_without_ext" "${model}"
thread_count=4
if [[ $model == "medium" ]]; then
thread_count=8
fi
transcribe-audio "$wav_name" "$output_name_without_ext" "${model}" $thread_count
if [[ $? == 1 ]]; then if [[ $? == 1 ]]; then
printf "${RED}${BOLD}Saving the audio file \"$wav_name\" in case you want to reuse it for debugging.\n${NORMAL}" printf "${RED}${BOLD}Saving the audio file \"$wav_name\" in case you want to reuse it for debugging.\n${NORMAL}"

View File

@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Re-encodes the video to get a more accurate timeline. If you want fast trimming at the expense of accuracy then use trim-video-fast.
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
ncolors=$(tput colors) ncolors=$(tput colors)
fi fi
@ -29,7 +31,7 @@ start_time="$3"
end_time="$4" end_time="$4"
if [[ $filename == "" || $output_name == "" || $start_time == "" || $end_time == "" ]]; then if [[ $filename == "" || $output_name == "" || $start_time == "" || $end_time == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n" printf "${BOLD}${RED}Usage: trim-video <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n"
exit 1 exit 1
fi fi
@ -42,7 +44,7 @@ printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | st
# You might have issues if the file has multiple video streams or embedded subtitles. The -map 0 arg is typically given # You might have issues if the file has multiple video streams or embedded subtitles. The -map 0 arg is typically given
# when copying a video stream, but I'm not sure if it's appropriate to use here. # when copying a video stream, but I'm not sure if it's appropriate to use here.
ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c copy "$output" ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -i "$filename.$extension" -c:v libx264 -c:a copy "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Reencodes the video with a more accurate length. # A fast video trim that might result in some weird playback cursor timings,
# e.g. video player might show negative seconds at the start of the vid or the
# playback time might oscillate a bit. Use trim-video for accurate trimming at
# the cost of a much slower processing time.
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
ncolors=$(tput colors) ncolors=$(tput colors)
@ -31,7 +34,7 @@ start_time="$3"
end_time="$4" end_time="$4"
if [[ $filename == "" || $output_name == "" || $start_time == "" || $end_time == "" ]]; then if [[ $filename == "" || $output_name == "" || $start_time == "" || $end_time == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n" printf "${BOLD}${RED}Usage: trim-video-fast <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n"
exit 1 exit 1
fi fi
@ -44,7 +47,7 @@ printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | st
# You might have issues if the file has multiple video streams or embedded subtitles. The -map 0 arg is typically given # You might have issues if the file has multiple video streams or embedded subtitles. The -map 0 arg is typically given
# when copying a video stream, but I'm not sure if it's appropriate to use here. # when copying a video stream, but I'm not sure if it's appropriate to use here.
ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -i "$filename.$extension" -c:v libx264 -c:a copy "$output" ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c copy "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"