Compare commits

..

17 Commits

Author SHA1 Message Date
6555d9d355 Simplify the convert video to mp4 scripts 2023-08-07 18:17:28 -04:00
27a08fb402 Rename volume adjustment scripts 2023-08-07 18:08:00 -04:00
bb26b8ceff Rename audio transcribe script 2023-08-07 17:47:56 -04:00
ba9a776867 Support a time range in the transcribe video scripts 2023-08-07 17:27:44 -04:00
90c312e954 Also check for first.jai files when building 2023-08-05 17:51:16 -04:00
e759f8c3cd Add some missing -y -stats -loglevel params to various ffmpeg commands 2023-08-05 17:51:16 -04:00
fb2773ca19 Improve audio extraction 2023-08-05 17:51:16 -04:00
62fa34ca20 Update aliases 2023-08-02 15:11:38 -04:00
d7977096a7 Add trim-audio and add-audio-to-video scripts 2023-08-02 15:11:25 -04:00
e3812590a2 Disable recent files on windows 2023-07-25 18:17:37 -04:00
7ac31b295f Add a script to create a gif from a video 2023-07-21 19:28:41 -04:00
3ea85786ce Update windows readme 2023-07-19 13:36:50 -04:00
9b5159e705 Update aliases and vimrc 2023-07-14 17:29:59 -04:00
f636229f5c Add some new video scripts and improve existing ones 2023-07-14 17:29:36 -04:00
515a9f479a Improve video audio normalization scripts 2023-06-22 16:07:00 -04:00
12a11b2435 Update some scripts 2023-06-21 20:03:21 -04:00
e602fc281c Revert disabling netrw in vim - was having odd things happening in vim and it might be related to this or it might be due to the dotfiles change...dunno man 2023-06-14 02:02:43 -04:00
36 changed files with 1015 additions and 377 deletions

View File

@@ -353,32 +353,52 @@ make_vid_dir_and_cd_into() {
function my_transcribe_video() { function my_transcribe_video() {
file="$1" file="$1"
output="$2" output="$2"
include_small=$3
start_time="$4"
end_time="$5"
if [[ $file == "" ]]; then if [[ $file == "" ]]; then
printf "Usage: <input video> <optional output name>\n" error "Usage: <input video> <optional output name> <optional include small model (1 or 0)> <optional start time> <optional end time>"
return return
fi fi
if [[ $output == "" ]]; then if [[ $output == "" ]]; then
output="${1%.*}" # just use the input name without the extension. output="${1%.*}" # just use the input name without the extension.
fi fi
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
# Tiny is fast and semi-accurate, so whatever. # Tiny is fast and semi-accurate, so whatever.
# Base is pretty good overall. It has good punctuation inserting and # Base is pretty good overall. It has good punctuation inserting and
# catches most words. Small and medium can do better word detection at # catches most words. Small and medium can do better word detection at
# times, but suffer from bad punctuation. Medium is particularly bad and # times, but suffer from bad punctuation. Medium is particularly bad and
# not adding commas and periods. # not adding commas and periods.
transcribe-video "$file" "$output" tiny base if [[ $include_small -eq 1 ]]; then
transcribe-video "$file" "$output" $start_time $end_time tiny base small
else
transcribe-video "$file" "$output" $start_time $end_time tiny base
fi
} }
function my_transcribe_video_all_models() { function my_transcribe_video_all_models() {
file="$1" file="$1"
output="$2" output="$2"
start_time="$3"
end_time="$4"
if [[ $file == "" ]]; then if [[ $file == "" ]]; then
printf "Usage: <input video> <optional output name>\n" error "Usage: <input video> <optional output name> <optional start time> <optional end time>"
return return
fi fi
if [[ $output == "" ]]; then if [[ $output == "" ]]; then
output="${1%.*}" # just use the input name without the extension. output="${1%.*}" # just use the input name without the extension.
fi fi
transcribe-video "$file" "$output" tiny base small medium
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$file" "$output" $start_time $end_time tiny base small medium
} }
@@ -544,6 +564,14 @@ download_youtube_uploads_list() {
printf "${BOLD}Finished downloading the upload list\n${NORMAL}" printf "${BOLD}Finished downloading the upload list\n${NORMAL}"
} }
function download_youtube_audio() {
if [[ $1 == "" ]]; then
error "Usage: <url>"
return
fi
yt-dlp.exe -f "140" "$1"
}
# Download Twitch chat transcript # Download Twitch chat transcript
actually_download_twitch_chat() { actually_download_twitch_chat() {
local url="$1" local url="$1"
@@ -903,7 +931,19 @@ download_mp4() {
} }
# Download from m3u8 stream to mp4. # Download from m3u8 stream to mp4.
download_from_m3u8() { # You can supply a local file or a URL to the m3u8 file. If the request requires cookies then the easiest way to do it is to
# run the ffmpeg command yourself using this as the example format:
#
# ffmpeg -protocol_whitelist file,https,crypto,tls,tcp -headers $'Cookie: CloudFront-Policy=ayJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly92aWRlby5zdGVsbGFydGlja2V0cy5jb20vb3JnYW5pemF0aW9ucy8yYWQ0YTBhYi1iZWM3LTQ4NjMtYTBmMS0zNjI0N2NjODNkMjMvdHJhbnNjb2RlZC85MWFmYjI4MS0wNy0yMC0yM19LcmF6YW1fUHJlc2VudHMqIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjkwNDk4ODAwfSwiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjY0LjEzNy4xNDkuMTkzLzMyIn19LCJTdHJlYW1Ub2tlbklkIjoiOTJlMTg2ZjUtZWZiMS00ZDAzLWE0NGQtZTg3YzQ3NzFiODI2IiwiU3RyZWFtVG9rZW5WaWV3ZXJJZCI6Ijg3NzFlMTBhLTcxNjUtNDcxOS1iMjFiLTkwNjljZDgzNzdhYyIsIlN0cmVhbVRva2VuVmlld2VyVHlwZSI6IkN1c3RvbWVyIiwiU3RyZWFtVG9rZW5SZXNvdXJjZUlkIjoiZDY3Mzc4NWMtNDEzNy00MDRhLTkzZjctNjQxN2Q4MmY2NmUxIiwiU3RyZWFtVG9rZW5SZXNvdXJjZVR5cGUiOiJWaWRlb09uRGVtYW5kIn1dfQ__; CloudFront-Signature=H0RwSHRX9y4PIqbAmxtEoGEPbO5da%7EW764sbHBXcPwnSSuq5PcjPM2UuP1YKL%7E92WcRTEiJ9FMDVbxNtPDZea2lCk9txvpHdmn7BBy6JNwKd-%7ED9RKq3SSqB00O8P1VkztKtkALYgn8lq3ihk7Nss0wYE9WxgvNNU30umcP-wSHFtuiGsbArivbWvu639Ku5bkfwm8azXI9hvz5D7OtwSyo3z%7E8trw3rALDwCgHZiqQrEQtfN4NYAWZ%7EuzdcGRgdUVmMQotBHG0WpPDItqBR9RLVel%7EWB0mQOO3Dax9DnGHlBaBs5mdR28NqOj8XCY4pAhguJQlERcANIK2WXm56dA__; CloudFront-Key-Pair-Id=APK3IWIJLRLBNXI2PR4Q\r\n' -i https://video.stellartickets.com/organizations/2ad4a0ac-bec7-4863-a0f1-36247cc83d23/transcoded/91afb281-07-20-23_Krazam_Presents_index_1080p_20230721T024151_1.m3u8 -acodec copy -vcodec copy krazam.mp4
#
# You can get the cookie header value from the browser's dev tools network
# page. I tried adding support to this function so that you can just pass the
# cookie value as an arg but it would not work and I don't want to waste more
# time on it.
#
# If you need to debug the http request then add "-v trace" to the command above.
#
download_mp4_from_m3u8() {
local m3u8_path="$1" local m3u8_path="$1"
local filename="$2" local filename="$2"
@@ -923,6 +963,27 @@ download_from_m3u8() {
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n" printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
} }
# Same notes from above regarding cookies/headers.
download_aac_from_m3u8() {
local m3u8_path="$1"
local filename="$2"
if [[ $m3u8_path == "" || $filename == "" ]]; then
error "Usage: <m3u8 path> <filename>"
return
fi
printf "${BOLD}Downloading: ${YELLOW}$filename${NORMAL}\n"
ffmpeg.exe -protocol_whitelist file,https,crypto,tls,tcp -i $m3u8_path -acodec copy "${filename}.aac"
if [[ $? -ne 0 ]]; then
error "Error: failed to download."
return
fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
}
#------------------------------------------------- #-------------------------------------------------
# YouTube Vid DL # YouTube Vid DL
@@ -949,7 +1010,7 @@ alias yt-playlist-list='download_youtube_playlist_list '
alias yt-playlist-1080='download_youtube_playlist "137+140"' alias yt-playlist-1080='download_youtube_playlist "137+140"'
alias yt-playlist-720='download_youtube_playlist "136+140"' alias yt-playlist-720='download_youtube_playlist "136+140"'
alias yt-playlist-tiny='download_youtube_playlist "160+140"' alias yt-playlist-tiny='download_youtube_playlist "160+140"'
alias yt-audio='yt-dlp.exe -f "140"' alias yt-audio='download_youtube_audio'
#------------------------------------------------- #-------------------------------------------------
# Twitch Vid DL # Twitch Vid DL
@@ -1047,7 +1108,8 @@ alias twitter='download_twitter_vid "" '
# Misc # Misc
#------------------------------------------------- #-------------------------------------------------
alias download-mp4='download_mp4' alias download-mp4='download_mp4'
alias download-from-m3u8='download_from_m3u8' alias download-from-m3u8='download_mp4_from_m3u8'
alias download-audio-from-m3u8='download_aac_from_m3u8'
#################################################################################################### ####################################################################################################
# Video Compression # Video Compression

28
.vimrc
View File

@@ -374,8 +374,6 @@ set complete-=i " Don't scan all included files since it's rea
set termguicolors set termguicolors
syntax on " Enable highlighting for syntax syntax on " Enable highlighting for syntax
let g:netrw_dirhistmax = 0 " Disable netrw
set wildmenu set wildmenu
set wildmode=longest,list,full set wildmode=longest,list,full
set wildignore+=*/log/*,*.so,*.swp,*.zip,*/rdoc/* set wildignore+=*/log/*,*.so,*.swp,*.zip,*/rdoc/*
@@ -658,7 +656,7 @@ vnoremap p "_dP
" Switch between C++ source and header files. " Switch between C++ source and header files.
noremap <leader>v :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR> noremap <leader>v :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>
"noremap <leader>vv :e %:p:s,.h$,.X123X,:s,.c$,.h,:s,.X123X$,.c,<CR> noremap <leader>vv :e %:p:s,.h$,.X123X,:s,.c$,.h,:s,.X123X$,.c,<CR>
"noremap <leader>vvv :e %:p:s,.h$,.X123X,:s,.cc$,.h,:s,.X123X$,.cc,<CR> "noremap <leader>vvv :e %:p:s,.h$,.X123X,:s,.cc$,.h,:s,.X123X$,.cc,<CR>
" Replace all instances of the highlighted text with whatever you enter. " Replace all instances of the highlighted text with whatever you enter.
@@ -1215,6 +1213,7 @@ fu! Build(optimized=0, silent=0)
let l:is_jai = 0 let l:is_jai = 0
let l:has_jai_build_file = 0 let l:has_jai_build_file = 0
let l:has_jai_first_file = 1
let l:ext = tolower(expand('%:e')) let l:ext = tolower(expand('%:e'))
let l:current_dir = expand('%:p:h') let l:current_dir = expand('%:p:h')
@@ -1227,16 +1226,24 @@ fu! Build(optimized=0, silent=0)
" Check for a build file in the current directory or one directory back " Check for a build file in the current directory or one directory back
" (e.g. we're in modules/ or src/, code/, etc) " (e.g. we're in modules/ or src/, code/, etc)
if filereadable(l:current_dir . "/build.jai") || filereadable(l:one_dir_back . "/build.jai") if filereadable(l:current_dir . "/build.jai") || filereadable(l:one_dir_back . "/build.jai") || filereadable(l:current_dir . "/first.jai") || filereadable(l:one_dir_back . "/first.jai")
let l:has_jai_build_file = 1 let l:has_jai_build_file = 1
if filereadable(l:current_dir . "/build.jai") == 1 if filereadable(l:current_dir . "/build.jai") == 1
let l:cmd = "jai ". l:current_dir . "/build.jai" let l:cmd = "jai ". l:current_dir . "/build.jai"
elseif filereadable(l:current_dir . "/first.jai") == 1
let l:cmd = "jai ". l:current_dir . "/first.jai"
let l:has_jai_first_file = 1
else else
" It's one directory back. We don't want to include '../' in " It's one directory back. We don't want to include '../' in
" the cmd because then our reported paths in the program get " the cmd because then our reported paths in the program get
" botched, e.g. path shown in an assert error. " botched, e.g. path shown in an assert error.
let l:cmd = "jai " . l:one_dir_back . "/build.jai" if filereadable(l:one_dir_back . "/build.jai") == 1
let l:cmd = "jai " . l:one_dir_back . "/build.jai"
else
let l:cmd = "jai " . l:one_dir_back . "/first.jai"
let l:has_jai_first_file = 1
endif
endif endif
else else
let l:cmd = "jai % " let l:cmd = "jai % "
@@ -1253,18 +1260,23 @@ fu! Build(optimized=0, silent=0)
let l:set_metaprogram_args = 0 let l:set_metaprogram_args = 0
if l:has_jai_build_file if l:has_jai_build_file
let l:filename = "build.jai"
if l:has_jai_first_file
let l:filename = "first.jai"
endif
if a:optimized == 1 if a:optimized == 1
echo "Compiling release build.jai" echo "Compiling release " . l:filename
" @note We pass 'release' as a user metaprogram arg for the " @note We pass 'release' as a user metaprogram arg for the
" build file to parse in case it cares about that. -release is " build file to parse in case it cares about that. -release is
" a compiler arg that we also include because some build " a compiler arg that we also include because some build
" scripts won't be looking at the user metaprogram args. " scripts won't be looking at the user metaprogram args.
" We also don't bother adding an import directory for local modules " We also don't bother adding an import directory for local modules
" because the build file should manage that sort of thing for us. " because the build file should manage that sort of thing for us.
let l:cmd .= " -release - release" let l:cmd .= " -release - -release"
let l:set_metaprogram_args = 1 let l:set_metaprogram_args = 1
else else
echo "Compiling debug build.jai" echo "Compiling debug " . l:filename
endif endif
else else
if a:optimized == 1 if a:optimized == 1

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Re-encodes the video with a new primary audio channel.
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
vid_filename=$(basename -- "$1")
audio_filename=$(basename -- "$2")
output_name="$3"
if [[ $vid_filename == "" || $audio_filename == "" || $output_name == "" ]]; then
printf "${BOLD}${RED}Usage: add-audio-to-video <video filename> <audio filename> <output name>${NORMAL}\n"
exit 1
fi
vid_extension="${vid_filename##*.}"
vid_filename="${vid_filename%.*}"
audio_extension="${audio_filename##*.}"
audio_filename="${audio_filename%.*}"
output="${output_name}.$vid_extension"
audio_encoding_opts="-c:a copy"
if [[ $audio_extension == "wav" ]]; then
# Re-encode the audio.
audio_encoding_opts="-c:a aac -b:a 192k"
fi
printf "\n${YELLOW}${BOLD}Adding audio '$audio_filename.$audio_extension' to '$vid_filename.$vid_extension' | output: $output${NORMAL}\n"
# -shortest handles the inputs not being the same duration. Conversion will stop when the shortest input's end is reached.
# Alternatively you can loop with "-stream_loop -1"
ffmpeg -y -stats -loglevel level+error -i "$vid_filename.$vid_extension" -i "$audio_filename.$audio_extension" -c:v copy -map 0:v:0 -map 1:a:0 $audio_encoding_opts -shortest "$output"
printf "\n${GREEN}${BOLD}Finished adding audio${NORMAL}\n\n"

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Use this to get a volume report from a video or audio file. You can use this
# info manually normalize or increase/decrease the volume using the
# change-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-volume with a value of 5. I
# find that the two pass normalize-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-volume <video or audio 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-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
@@ -94,7 +93,7 @@ reg add HKLM\SYSTEM\Setup /v DisabledDefenderServices /t REG_DWORD /d 1 /f
echo. echo.
echo Windows Defender has (hopefully) been disabled. echo Windows Defender has (hopefully) been disabled.
echo You should still be able to scan files going forward. Also, the Antimalware Service Executable should immediately stop using CPU cycles. echo You might still be able to scan files going forward depending on your version of Windows. Also, the Antimalware Service Executable should immediately stop using CPU cycles.
echo Please restart your computer to see all changes. echo Please restart your computer to see all changes.
goto eof goto eof
@@ -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

@@ -1,5 +1,30 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Creates a file containing the names of all files in a specific bucket.
#
# e.g. aws-list-deep-glacier-files my-deep-glacier images image_list
#
# You'll need the aws cli tools. Download them from https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
#
# If you see an error like along the lines of "'charmap' codec can't encode
# character '\u200e' in position 42: character maps to <undefined>" then that
# means a filename has a Unicode codepoint and the dumb aws Python code is
# trying to read it using your system's locale, which is very likely not set to
# use the Windows UTF-8 beta feature. This is an ongoing issue in this tool
# that goes back to 2013!!! There's no way to fix it using environment
# variables, at least nothing worked for me. The fix provided by the devs is
# heavy handed: you change your system locale to use UTF-8... This has
# consequences though like breaking legacy apps that don't have Unicode support
# and I'm sure other weird things will happen, such as file corruption. Anyway,
# if you're getting this charmap error then I suggest changing your system
# locale, run this again, then switch back to your previous locale. If you
# don't get the canonical file name then you won't be able to restore it.
#
# You can enable the UTF-8 locale with:
#
# win+r -> intl.cpl -> Administrative tab -> Change system locale -> Beta: Use Unicode UTF-8 box.
#
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
ncolors=$(tput colors) ncolors=$(tput colors)
fi fi

View File

@@ -1,10 +1,49 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# Restores all files/folders inside a particular bucket path, # Restores all files/folders inside a particular bucket path for the next 7 days. This uses the bulk retreival tier:
# e.g. aws-restore-deep-glacier-folder mcampagnaro-deep-glacier images restored_images #
# will restore all files inside the images folder of the mcampagnaro-deep-glacier bucket, saving # Bulk retrievals are the lowest-cost retrieval option when restoring objects
# temp restoration data in the local "restored_images" directory. # from S3 Glacier Deep Archive. They typically finish within 48 hours for
# objects stored in the S3 Glacier Deep Archive storage class or S3
# Intelligent-Tiering Deep Archive tier.
#
# If you need faster access then use the `Expedited` or `Standard` tiers.
#
# Example usage:
#
# aws-restore-deep-glacier-folder my-deep-glacier-bucket path/to/images restored_images
#
# This will create a run.sh script in a folder called "restored_images". Run that to restore all files inside the `path/to/images` folder inside the my-deep-glacier bucket.
#
# After you run the generated script, you have to wait for AWS to make the files available for download. You can check the status of a file with:
#
# aws s3api head-object --bucket my-deep-glacier --key path/to/images/photo1.jpg
#
# (obviously change the bucket and path to suit your needs).
#
# Once the files are restored you can download them on the S3 website or better yet use RcloneBrowser. I'm sure there's also a way to do it over cli too, I just haven't checked.
#
# You'll need the aws cli tools for this script. Download them from https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
# Once installed, open a new shell and verify that you can run the `aws` command.
#
# If you see an error like along the lines of "'charmap' codec can't encode
# character '\u200e' in position 42: character maps to <undefined>" then that
# means a filename has a Unicode codepoint and the dumb aws Python code is
# trying to read it using your system's locale, which is very likely not set to
# use the Windows UTF-8 beta feature. This is an ongoing issue in this tool
# that goes back to 2013!!! There's no way to fix it using environment
# variables, at least nothing worked for me. The fix provided by the devs is
# heavy handed: you change your system locale to use UTF-8... This has
# consequences though like breaking legacy apps that don't have Unicode support
# and I'm sure other weird things will happen, such as file corruption. Anyway,
# if you're getting this charmap error then I suggest changing your system
# locale, run this again, then switch back to your previous locale. If you
# don't get the canonical file name then you won't be able to restore it.
#
# You can enable the UTF-8 locale with:
#
# win+r -> intl.cpl -> Administrative tab -> Change system locale -> Beta: Use Unicode UTF-8 box.
# #
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
@@ -46,7 +85,7 @@ path="$2"
temp_dir="$3" temp_dir="$3"
number_of_objects_per_file=100 number_of_objects_per_file=100
days_available=7 days_available=7
restore_tier="Bulk" # Can also be "Standard" restore_tier="Bulk" # Can also be "Standard" or "Expedited"
if [[ $bucket == "" || $path == "" || $temp_dir == "" ]]; then if [[ $bucket == "" || $path == "" || $temp_dir == "" ]]; then
error "Usage: aws-restore-deep-glacier-folder <bucket-name> <path-in-bucket> <local-temp-dir>" error "Usage: aws-restore-deep-glacier-folder <bucket-name> <path-in-bucket> <local-temp-dir>"
@@ -61,7 +100,7 @@ pushd "$temp_dir" &>/dev/null
aws s3api list-objects-v2 --bucket $bucket --prefix $path --query "Contents[?StorageClass=='DEEP_ARCHIVE']" --output text | LC_ALL=C awk '{print substr($0, index($0, $2))}' | awk '{NF-=3};3' > all_objects_list.txt aws s3api list-objects-v2 --bucket $bucket --prefix $path --query "Contents[?StorageClass=='DEEP_ARCHIVE']" --output text | LC_ALL=C awk '{print substr($0, index($0, $2))}' | awk '{NF-=3};3' > all_objects_list.txt
# Generate the main script that will kick off the restoration. # Generate the main script that will kick off the restoration.
printf "while read x; do\n printf \"aws s3api restore-object --restore-request '{\\\\\"Days\\\\\":$days_available,\\\\\"GlacierJobParameters\\\\\":{\\\\\"Tier\\\\\":\\\\\"$restore_tier\\\\\"}}' --bucket $bucket --key \\\\\"\$x\\\\\"\\\\n\"\n aws s3api restore-object --restore-request \"{\\\\\"Days\\\\\":$days_available,\\\\\"GlacierJobParameters\\\\\":{\\\\\"Tier\\\\\":\\\\\"$restore_tier\\\\\"}}\" --bucket $bucket --key \"\$x\"\ndone < all_objects_list.txt\nprintf \"\\\\nDone! You can now delete this folder.\\\\n\"\n" > run.sh printf "while read x; do\n printf \"aws s3api restore-object --restore-request '{\\\\\"Days\\\\\":$days_available,\\\\\"GlacierJobParameters\\\\\":{\\\\\"Tier\\\\\":\\\\\"$restore_tier\\\\\"}}' --bucket $bucket --key \\\\\"\$x\\\\\"\\\\n\"\n aws s3api restore-object --restore-request \"{\\\\\"Days\\\\\":$days_available,\\\\\"GlacierJobParameters\\\\\":{\\\\\"Tier\\\\\":\\\\\"$restore_tier\\\\\"}}\" --bucket $bucket --key \"\$x\"\ndone < all_objects_list.txt\nprintf \"\\\\nDone! You can now delete this folder.\\\\nYour files are currently being restored. The time it takes to restore can be found in the AWS docs - just look for the $restore_tier restore tier, which is what you used.\\\\nOnce restored, download the files from the S3 site or better yet use RCloneBrowser.\\\\n\"\n" > run.sh
chmod +x run.sh chmod +x run.sh
printf "${BOLD}You can now run ${GREEN}$temp_dir/run.sh${NORMAL}${BOLD} to start the restoration process.\n" printf "${BOLD}You can now run ${GREEN}$temp_dir/run.sh${NORMAL}${BOLD} to start the restoration process.\n"

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Re-encodes the audio, modify the volume based on the supplied db delta. If
# given a video file then the file is copied as-is. If you want to bring the
# max_volume to 0 db then call analyze-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-volume <video or audio 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 -y -stats -loglevel level+error -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

@@ -26,7 +26,7 @@ fi
use_gpu=0 use_gpu=0
if [[ $# < 2 || $# > 3 ]]; then if [[ $# < 2 || $# > 3 ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> ${NORMAL}\n" printf "${BOLD}${RED}Usage: compress-video <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> ${NORMAL}\n"
exit 1 exit 1
fi fi

View File

@@ -26,7 +26,7 @@ fi
use_gpu=0 use_gpu=0
if [[ "$#" < 3 || "$#" > 6 ]]; then if [[ "$#" < 3 || "$#" > 6 ]]; then
printf "${BOLD}${RED}Usage: $0 <crf value> <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> <optional: start time HH:MM:SS> <optional: end time HH:MM:SS>\n\nIf you want to encode a range of CRF values then use -1 as the crf value.${NORMAL}\n" printf "${BOLD}${RED}Usage: compress-video-with-crf <crf value> <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> <optional: start time HH:MM:SS> <optional: end time HH:MM:SS>\n\nIf you want to encode a range of CRF values then use -1 as the crf value.${NORMAL}\n"
exit 1 exit 1
fi fi

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env bash
# This is for reencoding an AVI video. I wasn't able to play the encoded videos
# on my phone when using libx264 and libx265 encoders, but mpeg4 works. Also
# I'm using the aac codec because some old avi's were using a codec that's not
# supported in the mp4 container.
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 == "" || $2 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <bitrate, e.g. \"4000k\"> <optional output name>${NORMAL}\n"
exit 1
fi
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
bitrate="$2"
output_name="$3"
if [[ $output_name == "" ]]; then
output="${filename}_CONVERTED-${bitrate}.mp4"
else
output="${output_name}.mp4"
fi
printf "\n${YELLOW}${BOLD}Encoding '$filename.$extension' with target bitrate $bitrate | output: $output${NORMAL}\n"
ffmpeg -i "$filename.$extension" -c:a aac -c:v mpeg4 -b:v $bitrate "$output"
printf "\n${GREEN}${BOLD}Done encoding '$filename.$extension' to '$output'${NORMAL}\n\n"

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# This is for reencoding an FLV video to mp4 using an mpeg4 encoder.
# Can optionally compress the video.
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 == "" || $2 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <compress 1|0> <filename> <optional output name>${NORMAL}\n"
exit 1
fi
compress="$1"
filename=$(basename -- "$2")
extension="${filename##*.}"
filename="${filename%.*}"
output="$3"
if [[ $output == "" ]]; then
output="${filename}_CONVERTED"
fi
printf "\n${YELLOW}${BOLD}Encoding '$filename.$extension' | compress: $compress | output: $output.mp4${NORMAL}\n"
if [[ $compress -eq 1 ]]; then
temp_output="temp_$output.mp4"
else
temp_output="$output.mp4"
fi
# convert first.
# we convert then compress instead of compressing on first pass because this results in a slightly higher bitrate.
ffmpeg -y -stats -loglevel level+error -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i "$filename.$extension" -c:a aac -c:v h264_nvenc -b:v 5M "$temp_output"
if [[ $compress -eq 1 ]]; then
compress-video 1 "$temp_output" "$output"
rm "$temp_output"
else
printf "\n"
fi
printf "${GREEN}${BOLD}Done encoding '$filename.$extension' to '$output.mp4'${NORMAL}\n\n"

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env bash
# This is for reencoding an mkv video to mp4 using an mpeg4 encoder.
# Can optionally compress the video.
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 == "" || $2 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <compress 1|0> <filename> <optional output name>${NORMAL}\n"
exit 1
fi
compress="$1"
filename=$(basename -- "$2")
extension="${filename##*.}"
filename="${filename%.*}"
output="$3"
if [[ $output == "" ]]; then
output="${filename}_CONVERTED"
fi
printf "\n${YELLOW}${BOLD}Encoding '$filename.$extension' | compress: $compress | output: $output.mp4${NORMAL}\n"
if [[ $compress -eq 1 ]]; then
temp_output="temp_$output.mp4"
else
temp_output="$output.mp4"
fi
# convert first.
# we convert then compress instead of compressing on first pass because this results in a slightly higher bitrate.
ffmpeg -y -stats -loglevel level+error -i "$filename.$extension" -vcodec copy -acodec copy "$temp_output"
if [[ $compress -eq 1 ]]; then
compress-video 1 "$temp_output" "$output"
rm "$temp_output"
else
printf "\n"
fi
printf "${GREEN}${BOLD}Done encoding '$filename.$extension' to '$output.mp4'${NORMAL}\n\n"

View File

@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# This is for reencoding a non-mp4 video to mp4 using an mpeg4 encoder.
# Can optionally compress the video.
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
compress="$1"
filename="$2"
output_name="$3"
bitrate="$4"
if [[ $compress == "" || $filename == "" || $output_name == "" ]]; then
printf "${BOLD}${RED}Usage: convert-video-to-mp4 <compress 1|0> <filename> <output name> <optional: bitrate, e.g. \"4000k\", defaults to source>${NORMAL}\n"
exit 1
fi
filename=$(basename -- "$filename")
extension="${filename##*.}"
extension="${extension,,}" # go lower-case
filename="${filename%.*}"
output="$output_name.mp4"
bitrate_args=""
if [[ $compress -eq 1 ]]; then
temp_output="temp_$output"
else
temp_output="$output"
fi
# convert first.
# we convert then compress instead of compressing on first pass because this results in a slightly higher bitrate.
cmd=""
if [[ $extension == "mkv" || $extension == "mpg" ]]; then
if [[ $bitrate != "" ]]; then
bitrate_args="-b:v $bitrate"
else
bitrate="<source value>"
fi
cmd="ffmpeg -y -stats -loglevel level+error -i \"$filename.$extension\" -vcodec copy -acodec copy $bitrate_args \"$temp_output\""
elif [[ $extension == "flv" ]]; then
if [[ $bitrate == "" ]]; then
bitrate="5M"
fi
bitrate_args="-b:v $bitrate"
cmd="ffmpeg -y -stats -loglevel level+error -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i \"$filename.$extension\" -c:a aac -c:v h264_nvenc $bitrate_args \"$temp_output\""
elif [[ $extension == "avi" || $extension == "wmv" ]]; then
cmd="ffmpeg -y -stats -loglevel level+error -i \"$filename.$extension\" -c:a aac -c:v mpeg4 $bitrate_args \"$output\""
else
printf "${BOLD}${RED}Don't know how to convert a '$extension' to mp4. Add support!${NORMAL}\n"
exit 1
fi
printf "\n${YELLOW}${BOLD}Encoding '$filename.$extension' | compress: $compress | output: $output | bitrate: $bitrate${NORMAL}\n"
eval "$cmd"
if [[ $compress -eq 1 ]]; then
compress-video 1 "$temp_output" "$output"
rm "$temp_output"
else
printf "\n"
fi
printf "${GREEN}${BOLD}Done encoding '$filename.$extension' to '$output'${NORMAL}\n\n"

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
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"
width="$3"
if [[ $filename == "" || $output_name == "" ]]; then
printf "${BOLD}${RED}Usage: create-gif-from-video <filename> <output name> <optional width, defaults to 240>${NORMAL}\n"
exit 1
fi
output="${output_name}.gif"
if [[ $width == "" ]]; then
width=240
fi
printf "\n${YELLOW}${BOLD}Creating a gif from '$filename' | output: $output | width: $width${NORMAL}\n"
ffmpeg -y -stats -loglevel level+error -i "$filename" -vf "fps=24,scale=$width:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 "$output"
printf "\n${GREEN}${BOLD}Finished!${NORMAL}\n\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,50 +0,0 @@
#!/usr/bin/env bash
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
input="$1"
output_name="$2"
if [[ $input == "" || $output_name == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <input video> <wav output name>${NORMAL}\n"
exit 1
fi
if [[ ! -f "$input" ]]; then
printf "${RED}${BOLD}Error: failed to extract audio. Video file \"$input\" doesn't exist.\n${NORMAL}"
exit 1
fi
# Add extension if not provided.
output_basename=$(basename -- "$output_name")
output_extension="${output_basename##*.}"
if [[ $output_extension != "wav" ]]; then
output_name="${output_name}.wav"
fi
printf "\n${YELLOW}${BOLD}Extracting 16-bit WAV from $input | output: $output_name${NORMAL}\n"
ffmpeg -i "$input" -ar 16000 -ac 1 -c:a pcm_s16le "$output_name"
printf "${GREEN}${BOLD}Done extracting 16-bit WAV from $input | output: $output_name${NORMAL}\n"

View File

@@ -1,5 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Extracts audio from a video. It expects you to know what audio codecs the
# video container has, e.g. it's an mp4 video with aac and m4a audio. Just set
# the format to the appropriate extension.
#
# If you want to convert to a different format or you want to change the sample
# rate, channel count, trim the audio, etc. then use transcode-audio.
if which tput >/dev/null 2>&1; then if which tput >/dev/null 2>&1; then
ncolors=$(tput colors) ncolors=$(tput colors)
fi fi
@@ -23,13 +30,13 @@ else
NORMAL="" NORMAL=""
fi fi
transcode="$1" filename=$(basename -- "$1")
filename=$(basename -- "$2") format="$2"
format="$3" start_time="$3"
bitrate="$4" end_time="$4"
if [[ $1 == "" || $2 == "" || $3 == "" ]]; then if [[ $1 == "" || $2 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <transcode? 0|1 (needed when container doesn't contain format)> <filename> <format (mp3, m4a, aac, etc)> <optional: bitrate. Uses 64k when not specified, 0 = variable (e.g. 0, 64, 128, etc)>${NORMAL}\n" printf "${BOLD}${RED}Usage: extract-audio-from-video <filename> <format (mp3, m4a, aac, etc)> <optional: start time HH:MM:SS, use empty string or 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -37,19 +44,23 @@ extension="${filename##*.}"
filename="${filename%.*}" filename="${filename%.*}"
output_name="$filename.$format" output_name="$filename.$format"
if [[ $bitrate == "" ]]; then timing_args=""
bitrate="64" if [[ $start_time != "" ]]; then
timing_args="-ss $start_time "
fi
if [[ $end_time != "" ]]; then
if [[ $start_time == "0" && $end_time == "0" ]]; then
# We treat a start and end with 0 values as no op.
timing_args=""
elif [[ $end_time != "0" ]]; then
# Handle having a start time but end time is set to 0, can just ignore it and it'll use the remainder of the video.
timing_args+="-to $end_time"
fi
fi fi
printf "\n${YELLOW}${BOLD}Extracting audio from $filename.$extension | bitrate: ${bitrate}k | output: $output_name${NORMAL}\n" printf "\n${YELLOW}${BOLD}Extracting audio from $filename.$extension | output: $output_name | start: $start_time | end: $end_time${NORMAL}\n"
if [[ $transcode == "1" ]]; then ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -vn -acodec copy "$output_name"
# Transcode audio
ffmpeg -i "$filename.$extension" -b:a ${bitrate}k -ac 2 -ar 44100 -map a "$output_name"
else
# Grab the audio stream from the video.
ffmpeg -i "$filename.$extension" -vn -acodec copy "$output_name"
fi
printf "\n${GREEN}${BOLD}Done extracting audio from $filename.$extension | output name '$output_name'${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Done extracting audio from $filename.$extension | output name '$output_name'${NORMAL}\n\n"

View File

@@ -27,7 +27,7 @@ else
fi fi
if [[ $1 == "" ]]; then if [[ $1 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <optional output name>${NORMAL}\n" printf "${BOLD}${RED}Usage: fix-audio-in-one-channel <filename> <optional output name>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -45,7 +45,7 @@ fi
printf "\n${YELLOW}${BOLD}Repairing audio in $filename.$extension | output: $output${NORMAL}\n" printf "\n${YELLOW}${BOLD}Repairing audio in $filename.$extension | output: $output${NORMAL}\n"
ffmpeg -i "$filename.$extension" -c:v copy -ac 1 "$output" ffmpeg -y -stats -loglevel level+error -i "$filename.$extension" -c:v copy -ac 1 -map 0 "$output"
printf "\n${GREEN}${BOLD}Done repairing audio in $filename.$extension | output: $output${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Done repairing audio in $filename.$extension | output: $output${NORMAL}\n\n"

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 -y -stats -loglevel level+error -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 -y -stats -loglevel level+error -f concat -safe 0 -i "$filename" -c copy "$output"
printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n"

View File

@@ -1,70 +0,0 @@
#!/usr/bin/env bash
# Use this to normalize the audio of a video using the average loudness, or RMS-based normalization.
# This does not re-encode the video.
#
# 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: $0 <filename> <optional output name>${NORMAL}\n"
exit 1
fi
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
output_name="$2"
if [[ $output_name == "" ]]; then
output="${filename}_normalized_audio.$extension"
else
output="${output_name}.$extension"
fi
printf "\n${YELLOW}${BOLD}Normalizing audio in $filename.$extension | output: $output${NORMAL}\n"
# This is done in two passes. The first pass will compute the mean loudness and
# the second pass will normalize the audio using the mean as the target.
# -vn, -sn, and -dn tells ffmpeg to ignore non-audio streams during the analysis. This speeds things up.
ffmpeg -i "$filename.$extension" -af "volumedetect" -vn -sn -dn -f null /dev/null
#ffmpeg -i "$filename.$extension" -c:v copy -ac 1 "$output"
printf "\n${GREEN}${BOLD}Done normalizing audio in $filename.$extension | output: $output${NORMAL}\n\n"
#---------------------------------------
# This seems better. 2 pass using loudnorm filter.
# 1st pass: ffmpeg -i "$filename.$extension" -pass 1 -filter:a loudnorm=print_format=json -vn -sn -dn -f null /dev/null
# 2nd pass: ffmpeg -i "$filename.$extension" -c:v copy -pass 2 -filter:a loudnorm=linear=true:measured_I=$input_i:measured_LRA=$input_lra:measured_tp=$input_tp:measured_thresh=$input_thresh "$output"
# TODO: extract the $input_i, input_lra, etc from the 1st pass output so that this can be automated.
# TODO: stackoverflow said if there are subtitles or multiple vid streams then add "-map 0" before the output name. Test this.
# TODO: disable the log file or just delete it after normalizing.

View File

@@ -0,0 +1,77 @@
#!/usr/bin/env bash
# Use this to normalize the volume of a video or audio file using the average loudness, or RMS-based normalization. It does a pretty good job!
# If you want to modify the volume manually then checkout the analyze-volume and change-volume scripts.
#
# This does not re-encode video when given a video file.
#
# 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: normalize-volume <video or audio filename> <optional output name>${NORMAL}\n"
exit 1
fi
filename=$(basename -- "$1")
extension="${filename##*.}"
filename="${filename%.*}"
output_name="$2"
if [[ $output_name == "" ]]; then
output="${filename}_normalized_audio.$extension"
else
output="${output_name}.$extension"
fi
printf "\n${YELLOW}${BOLD}Normalizing audio in $filename.$extension | output: $output${NORMAL}\n"
# This is done in two passes. The first pass will compute the mean loudness and
# the second pass will normalize the audio using the mean as the target.
temp_file="/tmp/_audio_info_$RANDOM"
# 1st pass:
cmd="ffmpeg -i \"$filename.$extension\" -pass 1 -filter:a loudnorm=print_format=json -vn -sn -dn -f null /dev/null 2>&1 | sed -n '/{/,/}/p' > $temp_file"
printf "\n${BOLD}Running 1st pass:\n$cmd\n\n${NORMAL}"
eval "$cmd"
printf "${BOLD}${GREEN}Done.\n\n${NORMAL}"
ii=`grep \"input_i\" $temp_file | cut -d: -f2 | tr -cd [:digit:].-`
itp=`grep \"input_tp\" $temp_file | cut -d: -f2 | tr -cd [:digit:].-`
ilra=`grep \"input_lra\" $temp_file | cut -d: -f2 | tr -cd [:digit:].-`
it=`grep \"input_thresh\" $temp_file | cut -d: -f2 | tr -cd [:digit:].-`
to=`grep \"target_offset\" $temp_file | cut -d: -f2 | tr -cd [:digit:].-`
# 2nd pass:
cmd="ffmpeg -y -stats -loglevel level+error -i \"$filename.$extension\" -c:v copy -pass 2 -filter:a loudnorm=linear=true:I=-16:LRA=11:tp=-1.5:measured_I=$ii:measured_LRA=$ilra:measured_tp=$itp:measured_thresh=$it:offset=$to:print_format=summary -map 0 \"$output\""
printf "${BOLD}Re-encoding audio:\n$cmd\n\n${NORMAL}"
eval "$cmd"
printf "\n${GREEN}${BOLD}Done normalizing volume in $filename.$extension | output: $output${NORMAL}\n"
rm $temp_file

View File

@@ -24,7 +24,7 @@ else
fi fi
if [[ $1 == "" ]]; then if [[ $1 == "" ]]; then
printf "${BOLD}${RED}Usage: $0 <filename> <optional output name>${NORMAL}\n" printf "${BOLD}${RED}Usage: remove-audio-from-video <filename> <optional output name>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -43,7 +43,7 @@ fi
printf "\n${YELLOW}${BOLD}Removing audio from '$filename.$extension' | output: '$output'${NORMAL}\n" printf "\n${YELLOW}${BOLD}Removing audio from '$filename.$extension' | output: '$output'${NORMAL}\n"
# -an removes the audio. # -an removes the audio.
ffmpeg -i "$filename.$extension" -c:v copy -an "$output" ffmpeg -y -stats -loglevel level+error -i "$filename.$extension" -c:v copy -an -map 0 "$output"
printf "\n${GREEN}${BOLD}Done removing audio from '$filename.$extension' | output: '$output'${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Done removing audio from '$filename.$extension' | output: '$output'${NORMAL}\n\n"

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bash
# Transcodes audio from a video or audio source into a new audio file. If you
# just want the audio from a video as-is then use extract-audio-from-video
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="$1"
output_name="$2"
sample_rate="$3"
channel_count="$4"
start_time="$5"
end_time="$6"
output_base=$(basename -- "$output_name")
output_extension="${output_base##*.}"
if [[ $filename == "" || $output_extension == "" || $output_extension == $output_base ]]; then
printf "${BOLD}${RED}Usage: transcode-audio <filename> <output name w/ extension> <optional: sample rate. Defaults to 44100> <optional: channel count. Defaults to 2> <optional: start time HH:MM:SS, use empty string or 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
if [[ $sample_rate == "" ]]; then
sample_rate="44100"
fi
if [[ $channel_count == "" ]]; then
channel_count="2"
fi
timing_args=""
if [[ $start_time != "" ]]; then
timing_args="-ss $start_time "
fi
if [[ $end_time != "" ]]; then
if [[ $start_time == "0" && $end_time == "0" ]]; then
# We treat a start and end with 0 values as no op.
timing_args=""
elif [[ $end_time != "0" ]]; then
# Handle having a start time but end time is set to 0, can just ignore it and it'll use the remainder of the video.
timing_args+="-to $end_time"
fi
fi
printf "\n${YELLOW}${BOLD}Extracting audio from '$filename' | output: '$output_name' | sample rate: $sample_rate | channels: $channel_count | start: $start_time | end: $end_time${NORMAL}\n"
ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -i "$filename" -ar $sample_rate -ac $channel_count -map a "$output_name"
printf "\n${GREEN}${BOLD}Done extracting audio from '$filename' | output '$output_name'${NORMAL}\n\n"

View File

@@ -52,11 +52,8 @@ 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: transcribe-audio <input.wav> <output name without extension> <model name> <optional: thread count>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -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"
@@ -85,7 +90,12 @@ whisper_fullname="$(expand_path $(which whisper.exe))"
whisper_path="$(dirname $whisper_fullname)" whisper_path="$(dirname $whisper_fullname)"
models_path="$whisper_path/models" models_path="$whisper_path/models"
whisper.exe --processors ${cores} --threads ${threads} -m "$models_path/ggml-${model}.en.bin" -otxt -osrt -f "$input_wav" -of "$output_name" --print-colors --print-progress if [[ $model != "large" ]]; then
model="${model}.en"
fi
whisper.exe --processors ${cores} --threads ${threads} -m "$models_path/ggml-${model}.bin" -otxt -osrt -f "$input_wav" -of "$output_name" --print-colors --print-progress
error=$? error=$?
if [[ error -eq 0 ]]; then if [[ error -eq 0 ]]; then
printf "${GREEN}${BOLD}Done transcribing $input_wav | model: $model | cores: $cores | threads: $threads | output: $output_name${NORMAL}\n" printf "${GREEN}${BOLD}Done transcribing $input_wav | model: $model | cores: $cores | threads: $threads | output: $output_name${NORMAL}\n"

View File

@@ -25,11 +25,13 @@ fi
input_video="$1" input_video="$1"
output_name_without_ext="$2" output_name_without_ext="$2"
shift 2 start_time="$3"
end_time="$4"
shift 4
models=("$@") models=("$@")
if [[ $input_video == "" || $output_name_without_ext == "" || ${#models[@]} -eq 0 ]]; then if [[ $input_video == "" || $output_name_without_ext == "" || $start_time == "" || $end_time == "" || ${#models[@]} -eq 0 ]]; then
printf "${BOLD}${RED}Usage: $0 <input.mp4> <output name without extension> <list of model names to use>${NORMAL}\n" printf "${BOLD}${RED}Usage: transcribe-video <input.mp4> <output name without extension> <start time HH:MM:SS, use 0 for start> <end time HH:MM:SS, use 0 for no value> <list of model names to use>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -43,17 +45,13 @@ if [[ input_extension != "wav" ]]; then
wav_name="${wav_name}.wav" wav_name="${wav_name}.wav"
fi fi
extract-16bit-wav-from-video "$input_video" "$wav_name" channel_count=1
sample_rate=16000
transcode-audio "$input_video" "$wav_name" $sample_rate $channel_count $start_time $end_time
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,2 +1,37 @@
#!/usr/bin/env bash #!/usr/bin/env bash
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 [[ $2 == "" ]]; then
printf "${BOLD}${RED}Usage: transcribe-video-base <input.mp4> <output name without extension> <optional: start time HH:MM:SS, use 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
start_time="$3"
end_time="$4"
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$1" "$2" "base" transcribe-video "$1" "$2" "base"

View File

@@ -1,2 +1,37 @@
#!/usr/bin/env bash #!/usr/bin/env bash
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 [[ $2 == "" ]]; then
printf "${BOLD}${RED}Usage: transcribe-video-medium <input.mp4> <output name without extension> <optional: start time HH:MM:SS, use 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
start_time="$3"
end_time="$4"
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$1" "$2" "medium" transcribe-video "$1" "$2" "medium"

View File

@@ -1,2 +1,37 @@
#!/usr/bin/env bash #!/usr/bin/env bash
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 [[ $2 == "" ]]; then
printf "${BOLD}${RED}Usage: transcribe-video-small <input.mp4> <output name without extension> <optional: start time HH:MM:SS, use 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
start_time="$3"
end_time="$4"
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$1" "$2" "small" transcribe-video "$1" "$2" "small"

View File

@@ -1,2 +1,37 @@
#!/usr/bin/env bash #!/usr/bin/env bash
transcribe-video "$1" "$2" "tiny"
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 [[ $2 == "" ]]; then
printf "${BOLD}${RED}Usage: transcribe-video-tiny <input.mp4> <output name without extension> <optional: start time HH:MM:SS, use 0 for start> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
start_time="$3"
end_time="$4"
if [[ $start_time == "" ]]; then start_time="0"; fi
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$1" "$2" $start_time $end_time "tiny"

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Reencodes the video with a more accurate length. # Re-encodes the audio to get a more accurate seek 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 +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-audio <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n"
exit 1 exit 1
fi fi
@@ -42,7 +42,7 @@ timing_args="-ss $start_time -to $end_time"
printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time${NORMAL}\n" printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time${NORMAL}\n"
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 -accurate_seek -i "$filename.$extension" -c copy "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n" printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Re-encodes the video to get a more accurate seek time. 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
@@ -40,7 +42,10 @@ timing_args="-ss $start_time -to $end_time"
printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time${NORMAL}\n" printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time${NORMAL}\n"
ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c copy "$output" # 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.
# Trying out async to keep video and audio synced.
ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -async 1 -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

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# A fast video trim that might result in some weird seek 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
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"
start_time="$3"
end_time="$4"
if [[ $filename == "" || $output_name == "" || $start_time == "" || $end_time == "" ]]; then
printf "${BOLD}${RED}Usage: trim-video-fast <filename> <output name> <start time HH:MM:SS> <end time HH:MM:SS>${NORMAL}\n"
exit 1
fi
extension="${filename##*.}"
filename="${filename%.*}"
output="${output_name}.$extension"
timing_args="-ss $start_time -to $end_time"
printf "\n${YELLOW}${BOLD}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time${NORMAL}\n"
# 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.
ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c copy "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"

View File

@@ -11,8 +11,9 @@
built this for them. There's no way to stop this from happening other than to disable the platform entirely. built this for them. There's no way to stop this from happening other than to disable the platform entirely.
* Run `disable-windows-platform-binary-table.reg` and reboot. * Run `disable-windows-platform-binary-table.reg` and reboot.
* Change PC name and reboot * Change PC name
* Open settings -> System -> About -> Rename this PC * Open settings -> System -> About -> Rename this PC
* Reboot
* Disable the annoying Windows alert sound that plays when doing things like using a terminal, hitting tab to autocomplete and it has no match. * Disable the annoying Windows alert sound that plays when doing things like using a terminal, hitting tab to autocomplete and it has no match.
* Open C:/windows/media * Open C:/windows/media
@@ -21,6 +22,13 @@
* Back in the previous Security tab, click Edit to change permisisons -> add your user account and grant all permissions * Back in the previous Security tab, click Edit to change permisisons -> add your user account and grant all permissions
* Now you can delete the file or rename it. * Now you can delete the file or rename it.
* Maybe disable swapfile
* Not a good idea to have this turned on for SSDs since it's extra writes, and writing to an SSD degrades the drive. Probably best to put this on a spinning disk.
It's unclear if it's a bad idea to entirely disable on Windows 10 & 11. You likely won't have an issue if you have lots of RAM, but apparently its used for other
things like sleeping apps, kernel dumps, etc. It's possible that disabling it will affect your PC performance. Whether that's noticeable is something I'm unsure of.
* Advanced System Settings -> Advanced -> Performance settings -> Advanced -> Change paging settings -> set the drives to none
* Reboot
* Disable `Enhance Pointer Precision`: * Disable `Enhance Pointer Precision`:
* Mouse Properties -> Pointer Options -> Motion section * Mouse Properties -> Pointer Options -> Motion section
@@ -48,6 +56,12 @@
* Pin "This PC" to taskbar * Pin "This PC" to taskbar
* In Win 10 start menu, search for "This PC", right click top result and pin to taskbar * In Win 10 start menu, search for "This PC", right click top result and pin to taskbar
* Disable collection of recently opened files
* winkey+r -> `gpedit.msc`.
* User Configuration > Administrative Templates > Start Menu and Taskbar
* Double-click the `Do no keep history of recently opened documents` policy.
* Select Enabled.
* Configure Explorer's options * Configure Explorer's options
* Open file explorer, click on File menu then options or "Change folder and search options" * Open file explorer, click on File menu then options or "Change folder and search options"
* General tab * General tab