Compare commits

25 Commits

Author SHA1 Message Date
fe531b185f vimrc: escape text search path 2026-03-15 17:31:28 -04:00
e009688aa0 Flash windows icon when various scripts finish running 2026-02-24 18:06:49 -05:00
bade7f762a Some improvements to the defender disable/enable scripts 2026-02-01 18:36:52 -05:00
01edb8f277 Change how gitconfig files are loaded 2026-01-15 18:11:15 -05:00
1474e23aea Small tweaks 2026-01-09 12:09:56 -05:00
08ed0a411d Update windows setup readme 2026-01-09 10:46:58 -05:00
9fb52326f9 Update aliases 2025-12-30 19:30:20 -05:00
56e4ad3386 Improve the aws deep glacier restore scripts 2025-12-30 19:30:20 -05:00
0ecad79655 Tweakin da aliases 2025-11-14 17:17:34 -05:00
8c4fbcc4a8 Update aliases 2025-10-01 01:16:23 -04:00
dcf670070d Fix yt-dlp issues with youtube and embed thumbnails/metadata in video downloads 2025-08-19 18:59:36 -04:00
121d451982 Improve some video encoding scripts, making use of the GPU again 2025-08-19 18:58:57 -04:00
240d38eea0 Update aliases 2025-05-07 16:08:14 -04:00
37e6c770d7 Update some download aliases, vimrc search for cursor term, and some volume scripts 2025-05-07 16:08:13 -04:00
1db6c9e9b0 I can't believe I didn't know about vim's line breaks at word boundaries option 2025-05-07 16:08:13 -04:00
a25c209ddf Add vim search commands for personal projects 2025-05-07 16:08:13 -04:00
3b6daf46a1 Add a git alias to see size of tracked files 2025-05-07 16:08:13 -04:00
25b741d913 Improve AWS restore script 2025-05-07 16:08:13 -04:00
8a348ac299 Update aliases 2025-05-07 16:08:13 -04:00
aed6afbe38 Remove some aliases 2025-05-07 16:08:13 -04:00
6b879c4d66 Ignore build directory when generating ctags 2025-05-07 16:08:13 -04:00
aa948710a2 Update aliases 2025-05-07 16:08:13 -04:00
923f7fbcd6 Update Windows readme 2025-05-07 16:08:13 -04:00
80227c1d76 Fix twitch vid compression failing because of extra spaces in filename 2025-05-07 16:08:13 -04:00
2d0191c775 Update windows hosts file 2025-05-07 16:08:12 -04:00
25 changed files with 1066 additions and 256 deletions

342
.aliases
View File

@@ -41,7 +41,7 @@ reload() {
}
update-shell() {
if [[ '${platform,,}' == *'ming'* ]]; then
if [[ ${platform,,} == *'ming'* ]]; then
pacman -Syu
printf "\n${BOLD}${YELLOW}Close this shell, open a new one, and then run 'pacman -Su'${NORMAL}\n"
fi
@@ -110,8 +110,12 @@ remove_windows_file() {
fi
}
open_explorer_here() {
local path_expanded=$(expand_path "$1")
open_explorer() {
local target="$1"
if [[ $target == "" ]]; then
target="$PWD"
fi
local path_expanded=$(expand_path "$target")
if [[ -d $path_expanded ]]; then
local path=$(unix_to_windows_path "$path_expanded")
explorer.exe "$path"
@@ -120,6 +124,20 @@ open_explorer_here() {
fi
}
open_filepilot() {
local target="$1"
if [[ $target == "" ]]; then
target="$PWD"
fi
local path_expanded=$(expand_path "$target")
if [[ -d $path_expanded ]]; then
local path=$(unix_to_windows_path "$path_expanded")
start fpilot.exe "$path"
else
echo "Folder no longer exists"
fi
}
remove_extra_spaces() {
# Replace consecutive spaces with a single space.
#
@@ -130,6 +148,30 @@ remove_extra_spaces() {
echo "$ret"
}
flash_taskbar() {
if [[ ${platform,,} == *'ming'* ]]; then
powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "
\$h = (Get-Process mintty -EA SilentlyContinue | ? MainWindowHandle | select -First 1).MainWindowHandle
if (-not \$h) { exit }
Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices;
public static class F {
[StructLayout(LayoutKind.Sequential)] public struct I { public uint cb; public IntPtr h; public uint f; public uint c; public uint t; }
[DllImport(\"user32.dll\")] public static extern bool FlashWindowEx(ref I i);
}'
\$i = New-Object F+I
\$i.cb = [Runtime.InteropServices.Marshal]::SizeOf(\$i)
\$i.h = [IntPtr]\$h
\$i.f = 2 -bor 12
\$i.c = 0
\$i.t = 0
[F]::FlashWindowEx([ref]\$i) | Out-Null
"
else
echo "flash_taskbar not implemented for this platform"
fi
}
##################
# Building code
##################
@@ -180,7 +222,7 @@ if [[ $platform == 'Darwin' ]]; then
alias trash='rmtrash'
alias tt='rmtrash'
elif [[ "${platform,,}" == *'ming'* ]]; then # convert to lowercase then compare with wildcard
elif [[ ${platform,,} == *'ming'* ]]; then # convert to lowercase then compare with wildcard
#alias rm='echo "use trash command instead!"'
#alias rmr='echo "use trash command instead!"'
alias trash='remove_windows_file'
@@ -208,17 +250,19 @@ mkcd() {
alias aliases='vim ~/.aliases'
alias al='aliases'
if [[ "${platform,,}" == *'ming'* ]]; then
if [[ ${platform,,} == *'ming'* ]]; then
_checksum() {
local algo="$1"
local file="$2"
certutil -hashfile $file $algo
certutil -hashfile "$file" $algo
}
alias checksum='certutil -hashfile'
alias checksum-md5='_checksum MD5'
alias checksum-sha1='_checksum SHA1'
alias checksum-sha256='_checksum SHA256'
alias checksum-sha512='_checksum SHA512'
# I use delegating to certutil via _checksum() but these programs are faster.
alias checksum-md5='md5sum.exe'
alias checksum-sha1='sha1sum.exe'
alias checksum-sha256='sha256sum.exe'
alias checksum-sha512='sha512sum.exe'
fi
check_signature() {
@@ -259,8 +303,7 @@ dos2unix_all() {
}
alias d2u='dos2unix_all'
alias e='open_explorer_here "$PWD"'
alias exp='echo "Use e instead."'
alias e='open_explorer'
alias f='fg'
alias hist='history'
alias histroy='history'
@@ -352,7 +395,7 @@ make_vid_dir_and_cd_into() {
dir_name=$(remove_extra_spaces "$dir_name")
printf "${BOLD}Creating directory ${YELLOW}'$dir_name'${NORMAL}\n"
printf "${BOLD}Creating directory ${YELLOW}\"$dir_name\"${NORMAL}\n"
mkdir "$dir_name" 2>/dev/null
cd "$dir_name"
@@ -393,6 +436,7 @@ function my_transcribe_video() {
else
transcribe-video "$file" "$output" $start_time $end_time tiny base
fi
flash_taskbar
}
function my_transcribe_video_all_models() {
@@ -414,6 +458,7 @@ function my_transcribe_video_all_models() {
if [[ $end_time == "" ]]; then end_time="0"; fi
transcribe-video "$file" "$output" $start_time $end_time tiny base small medium
flash_taskbar
}
@@ -444,13 +489,10 @@ download_youtube_vid() {
if [[ $format == "" ]]; then
printf "${BOLD}No format given; using best available.${NORMAL}\n"
# Download best mp4 video.
format="bv*[ext=mp4]+ba[ext=m4a]"
# Download best mp4 video, best audio then merge.
format="bv[ext=mp4]+ba[ext=m4a]"
fi
# We're assuming we'll always have an mp4 video only and audio track to merge.
opts+=" --merge-output-format mp4 --write-subs --sub-lang en --embed-subs"
if [[ $make_folder == "1" ]]; then
make_vid_dir_and_cd_into $url ""
if [[ $? -ne 0 ]]; then
@@ -470,6 +512,9 @@ download_youtube_vid() {
printf "filename: $filename\n"
# Download the video.
# We're assuming we'll always have an mp4 video only and audio track to merge.
opts+=" --merge-output-format mp4 --write-subs --sub-lang en --embed-subs --embed-thumbnail --embed-metadata"
local cmd="yt-dlp.exe -f $format -o \"$filename\" $opts $url"
eval $cmd # Need to eval in order to preserve the quotes wrapping the filename format string.
error=$?
@@ -490,6 +535,7 @@ download_youtube_vid() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
@@ -504,7 +550,7 @@ download_youtube_playlist() {
local url="$2"
local dir_name="$3"
shift 3
local opts="$@ --write-sub --sub-lang en --embed-subs"
local opts="$@"
if [[ $url == "" || $dir_name == "" ]]; then
error "Usage: <url> <directory name> <optional args>"
@@ -515,9 +561,8 @@ download_youtube_playlist() {
if [[ $format == "" ]]; then
printf "${BOLD}No format given; using best available.${NORMAL}\n"
# Download best mp4 video and best m4a audio, then merge.
format="bv*[ext=mp4]+ba[ext=m4a]"
opts+=" --merge-output-format mp4"
# Download best mp4 video, best audio then merge.
format="bv[ext=mp4]+ba[ext=m4a]"
fi
make_vid_dir_and_cd_into $url "$dir_name"
@@ -525,6 +570,9 @@ download_youtube_playlist() {
return
fi
# We're assuming we'll always have an mp4 video only and audio track to merge.
opts+=" --merge-output-format mp4 --write-subs --sub-lang en --embed-subs --embed-thumbnail --embed-metadata"
local cmd="yt-dlp.exe -f $format -o \"%(playlist_index)03d--%(upload_date>%Y-%m-%d)s-%(title)s-yt-%(id)s.%(ext)s\" $opts $url"
eval $cmd # Need to eval in order to preserve the quotes wrapping the filename format string.
@@ -534,6 +582,7 @@ download_youtube_playlist() {
cd ..
printf "${BOLD}Finished downloading the playlist\n${NORMAL}"
flash_taskbar
}
download_youtube_playlist_list() {
@@ -553,6 +602,7 @@ download_youtube_playlist_list() {
eval $cmd 1>"${output_name}.txt" # Need to eval in order to preserve the quotes wrapping the filename format string.
printf "${BOLD}Finished downloading the playlist video list\n${NORMAL}"
flash_taskbar
}
download_youtube_uploads_list() {
@@ -581,6 +631,7 @@ download_youtube_uploads_list() {
eval $cmd 1>"${output_name}.txt" # Need to eval in order to preserve the quotes wrapping the filename format string.
printf "${BOLD}Finished downloading the upload list\n${NORMAL}"
flash_taskbar
}
function download_youtube_audio() {
@@ -625,6 +676,7 @@ function download_youtube_audio() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Download Twitch chat transcript
@@ -662,7 +714,7 @@ download_twitch_chat() {
fi
fi
actually_download_twitch_chat $url "$(yt-dlp.exe --get-filename -o "%(upload_date>%Y-%m-%d)s-%(title)s-tw-%(id)s.chat" $opts $url)"
actually_download_twitch_chat $url "$(yt-dlp.exe --get-filename -o "%(upload_date>%Y-%m-%d)s-%(title)s-tw-%(id)s" $opts $url)"
if [[ $make_folder == "1" ]]; then cd ..; fi
}
@@ -676,7 +728,15 @@ download_twitch_chat() {
# `tw-1080p60 <url> --cookies /c/<cookie_path>/twitch_cookies.txt`
#
# To extract a portion of a video, you have to first download the entire file and then use the
# `trim-video` or `compress-video-and-trim` scripts.
# `trim-video` or `compress-video' with a time range.
#
# To download a partial stream use one of these commands. We need to reencode to remove extra frames from the start/end with a negative timeline.
#
# This reencodes during the download, slightly faster than the next option:
# yt-dlp -f "b" --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss 0:7:10.00 -to 0:8:06.00" --external-downloader-args "ffmpeg_o:-c:v libx264 -c:a aac" URL
#
# Download then re-encode:
# yt-dlp -f "b" --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss 5:25:38.00 -to 5:56:50.00" URL -o temp.mp4 ; trim-video-cpu temp.mp4 "FINAL_NAME" 0
#
download_twitch_vid() {
local format="$1"
@@ -697,12 +757,15 @@ download_twitch_vid() {
# It's a two step process because streamlink cannot pass the formatted filename to ffmpeg.
# We fallback to yt-dlp when it's a subscriber VOD because we don't have an easy way to access it with streamlink.
local subscriber_vod=0
local use_ytdlp=0
local split_opts=($opts)
if [[ ${split_opts[0]} == "--cookies" ]]; then
subscriber_vod=1
printf "${BOLD}Subscriber VOD. Will use yt-dlp to download.${NORMAL}\n"
fi
for i in "${split_opts[@]}"; do
if [[ $i == "--cookies" ]]; then
use_ytdlp=1
printf "${BOLD}Subscriber VOD. Will use yt-dlp to download.${NORMAL}\n"
fi
done
if [[ $shortname == "1" || $compress == "1" || $transcribe == "1" ]]; then
printf "${BOLD}Downloading Twitch vid "
@@ -749,12 +812,13 @@ download_twitch_vid() {
printf "filename: $filename\n"
# Download the video.
if [[ $subscriber_vod == "0" ]]; then
if [[ $use_ytdlp == "1" ]]; then
printf "${YELLOW}${BOLD}\nUsing yt-dlp to download...${NORMAL}\n"
opts+=" --embed-thumbnail --embed-metadata"
local cmd="yt-dlp.exe -f $yt_dlp_format -o \"$filename\" $opts $url"
else
printf "${YELLOW}${BOLD}\nUsing streamlink to download...${NORMAL}\n"
local cmd="streamlink.exe --twitch-low-latency --twitch-disable-ads --twitch-disable-hosting --force --progress=force $opts $url $streamlink_format -O | ffmpeg -i pipe:0 -c copy \"$filename\""
else
printf "${YELLOW}${BOLD}\nUsing yt-dlp to download...${NORMAL}\n"
local cmd="yt-dlp.exe -f $yt_dlp_format -o \"$filename\" $opts $url"
fi
eval $cmd # Need to eval in order to preserve the quotes wrapping the filename format string.
@@ -770,7 +834,7 @@ download_twitch_vid() {
local temp_name="temp_${RANDOM}"
extension="${filename##*.}"
# 0=cpu, 1=gpu
compress-video "$filename" "$temp_name" 0
compress-video "$filename" "$temp_name" 1
mv "$filename" "orig_$filename"
mv $temp_name.$extension "$filename"
printf "${BOLD}Make sure to delete the original video file\n${NORMAL}"
@@ -783,6 +847,7 @@ download_twitch_vid() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Download Vimeo videos.
@@ -790,20 +855,29 @@ download_twitch_vid() {
# e.g. --cookies cookies.txt --referer https://gillyandkeeves.tv https://player.vimeo.com/video/756941969
# The vid ID can be found by looking at the embed's iframe src attribute.
download_vimeo_vid() {
local shortname="$1"
local compress="$2"
local transcribe="$3"
local format="$4"
local format="$1"
local shortname="$2"
local compress="$3"
local transcribe="$4"
local make_folder="$5"
local url="$6"
shift 5
shift 6
local opts="$@"
if [[ $format == "" || $url == "" ]]; then
error "Usage: <format> <make folder?> <url> <optional args>"
if [[ $url == "" ]]; then
error "Usage: <make folder?> <url> <optional args>"
return
fi
if [[ $format == "" ]]; then
printf "${BOLD}No format given; using best available.${NORMAL}\n"
# Download best mp4 video, best audio then merge.
format="bv[ext=mp4]+ba[ext=m4a]"
fi
# We're assuming we'll always have an mp4 video only and audio track to merge.
opts+=" --merge-output-format mp4 --write-subs --sub-lang en --embed-subs --embed-thumbnail --embed-metadata"
if [[ $shortname == "1" || $compress == "1" || $transcribe == "1" ]]; then
printf "${BOLD}Downloading Vimeo vid "
if [[ $shortname == "1" ]]; then printf "| ${YELLOW}using short name${NORMAL}${BOLD} "; fi
@@ -841,7 +915,7 @@ download_vimeo_vid() {
if [[ $compress == "1" ]]; then
local temp_name="temp_${RANDOM}"
# 0=cpu, 1=gpu
compress-video "$filename" "$temp_name" 0
compress-video "$filename" "$temp_name" 1
extension="${filename##*.}"
mv "$filename" "orig_$filename"
mv $temp_name.$extension "$filename"
@@ -860,6 +934,7 @@ download_vimeo_vid() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Download Twitter videos.
@@ -867,7 +942,7 @@ download_twitter_vid() {
local format="$1"
local make_folder="$2"
local url="$3"
local vid_name="$4"
local vid_name="$4" # optional
if [[ $url == "" ]]; then
error "Usage: <make folder?> <url> <optional filename> <optional args>"
@@ -878,12 +953,24 @@ download_twitter_vid() {
local opts=""
if [[ $# > 3 ]]; then
# Since the name is optional and we might pass options, like --cookie etc
# we need to check if the vid name is set to an option.
if [[ $vid_name == -* ]]; then
echo "vid name is an option"
shift 3
vid_name=""
opts="$@"
else
shift 4
opts="$@"
fi
fi
if [[ $vid_name == "" ]]; then
local name_format="%(upload_date>%Y-%m-%d)s-%(title)s-twitter-%(id)s"
else
local name_format="%(upload_date>%Y-%m-%d)s-${vid_name}-twitter-%(id)s"
shift 4
opts="$@"
fi
if [[ $make_folder == "1" ]]; then
@@ -904,6 +991,7 @@ download_twitter_vid() {
printf "filename: $filename\n"
# Download the video.
opts+=" --embed-thumbnail --embed-metadata"
local cmd="yt-dlp.exe -f $format -o \"$filename\" $opts $url"
eval $cmd # Need to eval in order to preserve the quotes wrapping the filename format string.
@@ -915,15 +1003,17 @@ download_twitter_vid() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Download Instagram videos.
# If the download fails because you need to be authenticated then don't use the cookies arg because IG will flag your
# account as a bot and might ban you. Instead, use the instagram download code from private dotfiles.
download_instagram_vid() {
local transcribe="$1"
local make_folder="$2"
local url="$3"
local vid_name="$4"
local vid_name="$4" # optional
if [[ $url == "" ]]; then
error "Usage: <make folder?> <url> <optional filename> <optional args>"
@@ -934,12 +1024,24 @@ download_instagram_vid() {
local opts=""
if [[ $# > 3 ]]; then
# Since the name is optional and we might pass options, like --cookie etc
# we need to check if the vid name is set to an option.
if [[ $vid_name == -* ]]; then
echo "vid name is an option"
shift 3
vid_name=""
opts="$@"
else
shift 4
opts="$@"
fi
fi
if [[ $vid_name == "" ]]; then
local name_format="%(upload_date>%Y-%m-%d)s-%(title)s-ig-%(id)s"
else
local name_format="%(upload_date>%Y-%m-%d)s-${vid_name}-ig-%(id)s"
shift 4
opts="$@"
fi
if [[ $make_folder == "1" ]]; then
@@ -957,6 +1059,7 @@ download_instagram_vid() {
printf "filename: $filename\n"
# Download the video.
opts+=" --embed-thumbnail --embed-metadata"
local cmd="yt-dlp.exe -f $format -o \"$filename\" $opts $url"
eval $cmd # Need to eval in order to preserve the quotes wrapping the filename format string.
@@ -974,6 +1077,7 @@ download_instagram_vid() {
if [[ $make_folder == "1" ]]; then cd ..; fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Download MP4 video.
@@ -997,11 +1101,15 @@ download_mp4() {
fi
mv $temp_name "$filename.mp4"
flash_taskbar
}
# Download from m3u8 stream to mp4.
# 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:
# Download a stream to mp4. Can be from an m3u8 file, an mpd, etc. Whatever the
# supported extensions are from ffmpeg.
#
# You can supply a local file or a URL to the stream 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
#
@@ -1012,17 +1120,17 @@ download_mp4() {
#
# If you need to debug the http request then add "-v trace" to the command above.
#
download_mp4_from_m3u8() {
local m3u8_path="$1"
download_mp4_from_stream() {
local stream_path="$1"
local filename="$2"
if [[ $m3u8_path == "" || $filename == "" ]]; then
error "Usage: <m3u8 path> <filename>"
if [[ $stream_path == "" || $filename == "" ]]; then
error "Usage: <stream path> <filename>"
return
fi
printf "${BOLD}Downloading: ${YELLOW}$filename${NORMAL}\n"
ffmpeg.exe -protocol_whitelist file,data,https,crypto,tls,tcp -allowed_extensions ALL -i $m3u8_path -acodec copy -vcodec copy "${filename}.mp4"
ffmpeg.exe -protocol_whitelist file,data,https,crypto,tls,tcp -allowed_extensions ALL -i $stream_path -acodec copy -vcodec copy "${filename}.mp4"
if [[ $? -ne 0 ]]; then
error "Error: failed to download."
@@ -1030,20 +1138,21 @@ download_mp4_from_m3u8() {
fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
# Same notes from above regarding cookies/headers.
download_aac_from_m3u8() {
local m3u8_path="$1"
download_aac_from_stream() {
local stream_path="$1"
local filename="$2"
if [[ $m3u8_path == "" || $filename == "" ]]; then
error "Usage: <m3u8 path> <filename>"
if [[ $stream_path == "" || $filename == "" ]]; then
error "Usage: <stream 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"
ffmpeg.exe -protocol_whitelist file,https,crypto,tls,tcp -i $stream_path -acodec copy "${filename}.aac"
if [[ $? -ne 0 ]]; then
error "Error: failed to download."
@@ -1051,6 +1160,7 @@ download_aac_from_m3u8() {
fi
printf "${BOLD}Finished downloading ${YELLOW}$filename${NORMAL}\n"
flash_taskbar
}
@@ -1062,29 +1172,46 @@ alias yt-list-desc='download_youtube_uploads_list 1 '
alias yt='download_youtube_vid "" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-shortname='download_youtube_vid "" $SHORTNAME_ON $TRANSCRIBE_OFF'
alias yt-1440='download_youtube_vid "620+140" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1440p60='download_youtube_vid "400+140" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1440-shortname='download_youtube_vid "620+140" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1080='download_youtube_vid "137+140" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1080-shortname='download_youtube_vid "137+140" $SHORTNAME_ON $TRANSCRIBE_OFF'
alias yt-720='download_youtube_vid "136+140" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-720-shortname='download_youtube_vid "136+140" $SHORTNAME_ON $TRANSCRIBE_OFF'
alias yt-4k='download_youtube_vid "625+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-4k-shortname='download_youtube_vid "625+234" $SHORTNAME_ON $TRANSCRIBE_OFF'
alias yt-1440='download_youtube_vid "620+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1440p60='download_youtube_vid "400+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1440-shortname='download_youtube_vid "620+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
# Premium
alias yt-1080p='download_youtube_vid "616+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1080p-shortname='download_youtube_vid "616+234" $SHORTNAME_ON $TRANSCRIBE_OFF'
# Normal
alias yt-1080='download_youtube_vid "137+ba[ext=m4a]" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-1080-shortname='download_youtube_vid "137+ba[ext=m4a]" $SHORTNAME_ON $TRANSCRIBE_OFF'
alias yt-720='download_youtube_vid "136+234" $SHORTNAME_OFF $TRANSCRIBE_OFF'
alias yt-720-shortname='download_youtube_vid "136+234" $SHORTNAME_ON $TRANSCRIBE_OFF'
#TRANSCRIPTION ON
alias ytt='download_youtube_vid "" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-shortname-t='download_youtube_vid "" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-1440-t='download_youtube_vid "620+140" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-1440-shortname-t='download_youtube_vid "620+140" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-1080-t='download_youtube_vid "137+140" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-1080-shortname-t='download_youtube_vid "137+140" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-720-t='download_youtube_vid "136+140" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-720-shortname-t='download_youtube_vid "136+140" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-4k-t='download_youtube_vid "625+234" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-4k-shortname-t='download_youtube_vid "625+234" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-1440-t='download_youtube_vid "620+234" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-1440-shortname-t='download_youtube_vid "620+234" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-1080p-t='download_youtube_vid "616+234" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-1080p-shortname-t='download_youtube_vid "616+234" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-1080-t='download_youtube_vid "270+234" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-1080-shortname-t='download_youtube_vid "270+234" $SHORTNAME_ON $TRANSCRIBE_ON'
alias yt-720-t='download_youtube_vid "136+234" $SHORTNAME_OFF $TRANSCRIBE_ON'
alias yt-720-shortname-t='download_youtube_vid "136+234" $SHORTNAME_ON $TRANSCRIBE_ON'
#---------------------------
alias yt-playlist='download_youtube_playlist ""'
alias yt-playlist-audio='download_youtube_playlist "140"'
alias yt-playlist-1440='download_youtube_playlist "620+140"'
alias yt-playlist-1080='download_youtube_playlist "137+140"'
alias yt-playlist-720='download_youtube_playlist "136+140"'
alias yt-playlist-tiny='download_youtube_playlist "160+140"'
alias yt-playlist-audio='download_youtube_playlist "234"'
alias yt-playlist-4k='download_youtube_playlist "625+234"'
alias yt-playlist-1440='download_youtube_playlist "620+234"'
alias yt-playlist-1080p='download_youtube_playlist "616+234"'
alias yt-playlist-1080='download_youtube_playlist "270+234"'
alias yt-playlist-720='download_youtube_playlist "136+234"'
alias yt-playlist-tiny='download_youtube_playlist "160+234"'
alias yt-playlist-list='download_youtube_playlist_list '
#---------------------------
alias yt-audio='download_youtube_audio'
@@ -1093,6 +1220,7 @@ alias yt-audio='download_youtube_audio'
# Twitch Vid DL
#-------------------------------------------------
alias tw-chat='download_twitch_chat'
alias twc='download_twitch_chat 1'
alias tw='download_twitch_vid "" $SHORTNAME_OFF $COMPRESSION_OFF $TRANSCRIBE_OFF'
alias tw-compressed='download_twitch_vid "" $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_OFF'
@@ -1165,16 +1293,16 @@ alias tw-4k-shortname-compressed-t='download_twitch_vi "2160p" $SHORTNAM
#-------------------------------------------------
# Vimeo Vid DL
#-------------------------------------------------
alias vimeo='download_vimeo_vid $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_OFF'
alias vimeo-t='download_vimeo_vid $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_ON'
alias vimeo-compressed='download_vimeo_vid $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_OFF'
alias vimeo-compressed-t='download_vimeo_vid $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_ON'
alias vimeo='download_vimeo_vid "" $SHORTNAME_OFF $COMPRESSION_OFF $TRANSCRIBE_OFF'
alias vimeo-t='download_vimeo_vid "" $SHORTNAME_OFF $COMPRESSION_OFF $TRANSCRIBE_ON'
alias vimeo-compressed='download_vimeo_vid "" $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_OFF'
alias vimeo-compressed-t='download_vimeo_vid "" $SHORTNAME_OFF $COMPRESSION_ON $TRANSCRIBE_ON'
#-------------------------------------------------
# Instagram Vid DL
#-------------------------------------------------
alias ig='download_instagram_vid $TRANSCRIBE_OFF'
alias igt='download_instagram_vid $TRANSCRIBE_ON'
alias ig='echo using my accounts with cookies to dl ig vids makes instagram think i am a bot and they might close my account. do not use your accounts; download_instagram_vid $TRANSCRIBE_OFF'
alias igt='echo using my accounts with cookies to dl ig vids makes instagram think i am a bot and they might close my account. do not use your accounts' #download_instagram_vid $TRANSCRIBE_ON'
#-------------------------------------------------
# Twitter Vid DL
@@ -1185,41 +1313,40 @@ alias twitter='download_twitter_vid "" '
# Misc
#-------------------------------------------------
alias download-mp4='download_mp4'
alias download-from-m3u8='download_mp4_from_m3u8'
alias download-audio-from-m3u8='download_aac_from_m3u8'
alias download-from-stream='download_mp4_from_stream'
alias download-audio-from-stream='download_aac_from_stream'
alias download-audio-from-m3u8='echo Use download-audio-from-stream instead.'
####################################################################################################
# Video Compression
####################################################################################################
function _compress_video_hard() {
local crf=35
local name="$1"
local out="$2"
if [[ name == "" || out == "" ]]; then
error "Usage: cmd <source> <dest>"
return
fi
# 0=cpu, 1=gpu
compress-video-with-crf $crf "$name" "$out" 0
}
alias compress-video-hard='_compress_video_hard'
alias cv='compress-video'
alias cvh='compress-video-hard'
alias jv='join-video'
alias av='analyze-volume'
alias aa='analyze-volume'
alias nv='normalize-volume'
alias na='normalize-volume'
alias tv='trim-video'
alias tv='echo can just do a cv with a time range...' #trim-video-vbr'
function compress_and_normalize_volume() {
local final_name="$1"
shift 1
local opts="$@"
if [[ $final_name == "" ]]; then
error "Provide a final file name and optional args for compress-video"
return
fi
compress-video f.mp4 ff $opts ; normalize-volume ff.mp4 "$final_name" ; flash_taskbar
}
alias cvn='compress_and_normalize_volume'
####################################################################################################
# Git
####################################################################################################
if [[ '${platform,,}' == *'ming'* ]]; then
if [[ ${platform,,} == *'ming'* ]]; then
# Fix a weird mingw 'not a valid identifierline' error.
# Got the fix from https://github.com/Alexpux/MSYS2-packages/issues/735#issuecomment-328938800
alias git="PATH=/usr/bin git"
@@ -1330,8 +1457,11 @@ alias gf='git fetch'
alias gfa='git fetch --all'
alias gfd='git fetch --prune' # Removes remote branches that don't have a counterpart branch on the remote.
alias gfix='git commit --amend -C HEAD'
alias gfx='git commit --amend -C HEAD'
alias gfixs='git commit -S -a --amend -C HEAD' # signed
alias gfxs='git commit -S -a --amend -C HEAD' # signed
alias gfixno='git_fix_nocheckin'
alias gfxno='git_fix_nocheckin'
alias gfo='git fetch origin'
alias gfu='git fetch up'
alias gfm='git fetch origin master'
@@ -1364,7 +1494,7 @@ alias gpt='git push --tags'
alias gptf='git push --tags -f'
alias gpu='git push --set-upstream origin HEAD'
alias gr='git reset'
alias gr1='git reset HEAD^1; gl'
alias gr1='git reset HEAD^1'
alias grb='git rebase --autostash'
alias grba='git rebase --abort'
alias grbc='git rebase --continue'

View File

@@ -1,12 +1,15 @@
[include]
path = ~/.gitconfig.private
# Shared config from private dotfiles
path = ~/.private-dotfiles.common/gitconfig
# Computer-specific config from private dotfiles (might not exist)
path = ~/.private-dotfiles/gitconfig
[init]
defaultBranch = master
[merge]
summary = true
tool = vimdiff
[core]
excludesfile = ~/.gitignore.global
excludesfile = ~/.private-dotfiles.common/gitignore
hookspath = ~/.git_hooks
preloadindex = true
fscache = true

158
.vimrc
View File

@@ -144,6 +144,10 @@ let g:campo_files_to_force_stripping_trailing_whitespace = []
" let g:campo_custom_search_args = \"-g \"!3rd_party/*\" -tc"
let g:campo_custom_search_args = ""
" Set to your projects path. Used for scoping search commands to all projects.
" This includes CtrlP.
let g:campo_projects_path = ''
"##################################################################################
" CTAGS
"##################################################################################
@@ -299,6 +303,7 @@ set switchbuf=useopen,split
set numberwidth=5
set showtabline=2
set winwidth=79
"set linebreak " Break wrapped text at word boundaries
" Use abbreviations.
set shortmess=a
@@ -767,11 +772,16 @@ call Cabbrev('WQ', 'call WriteCurrentFileAndCreateCtagsThenQuit()')
" Faster way to open a file in the same directory.
" <tab> will autocomplete the expansion here because we set wildcharm to <tab>.
nnoremap <leader>e :e %:p:h/<tab>
" Jai folders
" Open a file with the path pre-populated with...
" * Projects folder
nnoremap <leader>ep :e <C-r>=g:campo_projects_path<CR>/<tab>
" * Jai folders
nnoremap <leader>ee :e <C-r>=g:campo_jai_path<CR>/<tab>
nnoremap <leader>em :e <C-r>=g:campo_jai_path<CR>/modules/<tab>
nnoremap <leader>eh :e <C-r>=g:campo_jai_path<CR>/how_to/<tab>
" Saving/quitting
nnoremap <leader>w :call WriteCurrentFileAndCreateCtags()<cr>
nnoremap <leader>x :call WriteCurrentFileAndCreateCtagsThenQuit()<cr>
nnoremap <leader>q :q<cr>
@@ -883,7 +893,6 @@ let g:rg_window_height = g:quickfix_pane_height
" ctrl-y = create file and open it.
" ctrl-z = mark multiple file search results to open (I think you can only use ctrl-v or ctrl-x and not enter).
" ctrl-o = ask how to open a file search result.
" ctrl-o = ask how to open a file search result.
" ctrl-p | ctrl-n = traverse search history.
" CtrlP finds the tags file by using vim's 'tags' option value. I initially
@@ -900,14 +909,14 @@ fu! CtrlP_Search(search_path)
execute 'CtrlP ' . a:search_path
endfu
fu! CtrlP_JaiSearch(jai_rel_search_path)
if g:campo_jai_path == ''
call PrintError("g:campo_jai_path isn't set!")
fu! CtrlP_CustomSearch(global_root_path, relative_search_path)
if a:global_root_path == ''
call PrintError("The global root path is empty. See a:global_root_path")
return
endif
let l:path = g:campo_jai_path
if a:jai_rel_search_path != ''
let l:path .= '/' . a:jai_rel_search_path
let l:path = a:global_root_path
if a:relative_search_path != ''
let l:path .= '/' . a:relative_search_path
endif
if !isdirectory(l:path)
call PrintError("Directory ".l:path." doesn't exist.")
@@ -917,11 +926,12 @@ fu! CtrlP_JaiSearch(jai_rel_search_path)
endfu
" CtrlP File Searching
noremap <leader>g :call CtrlP_Search('')<cr> " Search in current directory
noremap <leader>gg :call CtrlP_JaiSearch('')<cr> " Search in Jai directory
noremap <leader>gm :call CtrlP_JaiSearch('modules')<cr> " Search in Jai modules
noremap <leader>gh :call CtrlP_JaiSearch('how_to')<cr> " Search in Jai how_to
noremap <leader>ge :call CtrlP_JaiSearch('examples')<cr> " Search in Jai examples
noremap <leader>g :call CtrlP_Search('')<cr> " Search in current directory
noremap <leader>gp :call CtrlP_CustomSearch(g:campo_projects_path, '')<cr> " Search in projects directory.
noremap <leader>gg :call CtrlP_CustomSearch(g:campo_jai_path, '')<cr> " Search in Jai directory
noremap <leader>gm :call CtrlP_CustomSearch(g:campo_jai_path, 'modules')<cr> " Search in Jai modules
noremap <leader>gh :call CtrlP_CustomSearch(g:campo_jai_path, 'how_to')<cr> " Search in Jai how_to
noremap <leader>ge :call CtrlP_CustomSearch(g:campo_jai_path, 'examples')<cr> " Search in Jai examples
" @note we're using a modified version of ctrlp that removes duplicate tags
" when using multiple tag files. See https://github.com/sir-pinecone/ctrlp.vim/commit/5cceab
@@ -936,6 +946,7 @@ let g:ctrlp_switch_buffer = 'et' " If a file is already open, open it again in a
let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'
let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard'] " If a git repo, use checked in files (ignore things in .gitignore); fallback to globpath()
let g:ctrlp_match_func = { 'match': 'pymatcher#PyMatch' }
let g:ctrlp_split_window = 0 " Replace current buffer.
"##################################################################################
" GIT
@@ -1524,11 +1535,14 @@ nnoremap <C-p> :cp<CR>
"##################################################################################
" Search using ripgrep (first install with Rust: cargo install ripgrep).
fu! Search(path, search_args, case_insensitive=0)
fu! Search(path, search_args, case_insensitive=0, token="")
let l:helper = "Search '" . a:path . "' (" . (len(a:search_args) > 0 ? a:search_args . " | " : '') . (a:case_insensitive ? "INSENSITIVE" : "SENSITIVE") . "): "
let l:term = input(l:helper)
let l:term = a:token
if empty(l:term)
return
let l:term = input(l:helper)
if empty(l:term)
return
endif
endif
" @note --pretty (i.e. colors) is not enabled in vim-ripgrep because the
@@ -1541,11 +1555,9 @@ fu! Search(path, search_args, case_insensitive=0)
" Some characters need to be escaped.
let l:escaped_term = substitute(l:term, '[#%]', '\\\\\\&', 'g')
let l:escaped_path = substitute(a:path, '[#%]', '\\\\\\&', 'g')
let l:format = 'Rg ' . l:rg_args . ' ' . a:path . ' -e %s'
let l:cmd = printf(l:format, shellescape(l:escaped_term))
exec l:cmd
exec printf("Rg " . l:rg_args . " %s -e %s", shellescape(l:escaped_path), shellescape(l:escaped_term))
call ConvertQuickfixPathsToUnixSlashes()
endfu
@@ -1567,27 +1579,49 @@ fu! SearchExt(path, search_args, case_insensitive=0)
call Search(a:path, l:args, a:case_insensitive)
endfu
fu! SearchCursor(path, search_args, case_insensitive=0)
let l:term = expand('<cword>')
call Search(a:path, a:search_args, a:case_insensitive, l:term)
endfu
"/////////////////////////////////////////////////
" SEARCH IN CURRENT WORKING DIRECTORY
"/////////////////////////////////////////////////
" Case insensitive:
nnoremap <leader>s :call Search( '.', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sd :call SearchExt('.', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>s :call Search(getcwd(), g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sd :call SearchExt(getcwd(), g:campo_custom_search_args, 1)<cr>
nnoremap <leader>se :call SearchCursor(getcwd(), g:campo_custom_search_args, 1)<cr>
" Case sensitive:
nnoremap <leader>ss :call Search( '.', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssd :call SearchExt('.', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ss :call Search(getcwd(), g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssd :call SearchExt(getcwd(), g:campo_custom_search_args, 0)<cr>
nnoremap <leader>sse :call SearchCursor(getcwd(), g:campo_custom_search_args, 0)<cr>
"/////////////////////////////////////////////////
" SEARCH IN DIRECTORY CONTAINING THE ACTIVE FILE
"/////////////////////////////////////////////////
" Case insensitive:
nnoremap <leader>sf :call Search( expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdf :call SearchExt(expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
" Case insensitive
nnoremap <leader>sf :call Search(expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdf :call SearchExt(expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sef :call SearchCursor(expand('%:p:h'), g:campo_custom_search_args, 1)<cr>
" Case sensitive:
nnoremap <leader>ssf :call Search( expand('%:p:h'), g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssf :call Search(expand('%:p:h'), g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdf :call SearchExt(expand('%:p:h'), g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssef :call SearchCursor(expand('%:p:h'), g:campo_custom_search_args, 0)<cr>
"/////////////////////////////////////////////////
" SEARCH IN ALL PROJECTS
"/////////////////////////////////////////////////
" Case insensitive:
nnoremap <leader>sp :call Search(g:campo_projects_path, g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdp :call SearchExt(g:campo_projects_path, g:campo_custom_search_args, 1)<cr>
" Case sensitive:
nnoremap <leader>ssp :call Search(g:campo_projects_path, g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdp :call SearchExt(g:campo_projects_path, g:campo_custom_search_args, 0)<cr>
"/////////////////////////////////////////////////
" SEARCH IN JAI FOLDERS
@@ -1596,32 +1630,40 @@ nnoremap <leader>ssdf :call SearchExt(expand('%:p:h'), g:campo_custom_search_arg
" Case insensitive:
"
" ROOT
nnoremap <leader>sg :call Search( g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdg :call SearchExt(g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sg :call Search(g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdg :call SearchExt(g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
nnoremap <leader>seg :call SearchCursor(g:campo_jai_path, g:campo_custom_search_args, 1)<cr>
" MODULES
nnoremap <leader>sm :call Search( g:campo_jai_path.'/modules', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdm :call SearchExt(g:campo_jai_path.'/modules', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sm :call Search(g:campo_jai_path.'/modules', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdm :call SearchExt(g:campo_jai_path.'/modules', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sem :call SearchCursor(g:campo_jai_path.'/modules', g:campo_custom_search_args, 1)<cr>
" HOW TO
nnoremap <leader>sh :call Search( g:campo_jai_path.'/how_to', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdh :call SearchExt(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sh :call Search(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sdh :call SearchExt(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 1)<cr>
" EXAMPLES
nnoremap <leader>se :call Search( g:campo_jai_path.'/examples', g:campo_custom_search_args, 1)<cr>
nnoremap <leader>sde :call SearchExt(g:campo_jai_path.'/examples', g:campo_custom_search_args, 1)<cr>
" Using the 'e' for cursor search.
"nnoremap <leader>se :call Search(g:campo_jai_path.'/examples', g:campo_custom_search_args, 1)<cr>
"nnoremap <leader>sde :call SearchExt(g:campo_jai_path.'/examples', g:campo_custom_search_args, 1)<cr>
"nnoremap <leader>sae :call SearchCursor(g:campo_jai_path.'/examples', g:campo_custom_search_args, 1)<cr>
" Case sensitive:
"
" ROOT
nnoremap <leader>ssg :call Search( g:campo_jai_path, g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdg :call SearchExt(g:campo_jai_path, g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssg :call Search(g:campo_jai_path, g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdg :call SearchExt(g:campo_jai_path, g:campo_custom_search_args, 0)<cr>
nnoremap <leader>sseg :call SearchCursor(g:campo_jai_path, g:campo_custom_search_args, 0)<cr>
" MODULES
nnoremap <leader>ssm :call Search( g:campo_jai_path.'/modules', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdm :call SearchExt(g:campo_jai_path.'/modules', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssm :call Search(g:campo_jai_path.'/modules', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdm :call SearchExt(g:campo_jai_path.'/modules', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssem :call SearchCursor(g:campo_jai_path.'/modules', g:campo_custom_search_args, 0)<cr>
" HOW TO
nnoremap <leader>ssh :call Search( g:campo_jai_path.'/how_to', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdh :call SearchExt(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssh :call Search(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssdh :call SearchExt(g:campo_jai_path.'/how_to', g:campo_custom_search_args, 0)<cr>
" EXAMPLES
nnoremap <leader>sse :call Search( g:campo_jai_path.'/examples', g:campo_custom_search_args, 0)<cr>
nnoremap <leader>ssde :call SearchExt(g:campo_jai_path.'/examples', g:campo_custom_search_args, 0)<cr>
" Using the 'e' for cursor search.
"nnoremap <leader>sse :call Search(g:campo_jai_path.'/examples', g:campo_custom_search_args, 0)<cr>
"nnoremap <leader>ssde :call SearchExt(g:campo_jai_path.'/examples', g:campo_custom_search_args, 0)<cr>
"nnoremap <leader>ssae :call SearchCursor(g:campo_jai_path.'/examples', g:campo_custom_search_args, 0)<cr>
" Navigation for the vim-ripgrep search results.
" Hit o on a result line to open the file at that line.
@@ -1741,6 +1783,34 @@ nnoremap <leader>cc :call CenterPane()<cr>
nnoremap <leader>cd :call RemoveCenterPane()<cr>
"##################################################################################
" EDIT TODO PLAN & SMALL WINDOW
"##################################################################################
fu! EditTodoPlan()
execute 'vsplit todo.plan'
exec 'vertical resize' string(&columns * 0.25)
endfu
fu! EditTodoPlanH()
execute 'split todo.plan'
exec 'horizontal resize' string(&lines * 0.25)
endfu
fu! MakeSmall()
exec 'vertical resize' string(&columns * 0.25)
endfu
fu! SmallWindow()
execute 'vsplit'
exec 'vertical resize' string(&columns * 0.25)
endfu
nnoremap <leader>t :call EditTodoPlan()<cr>
nnoremap <leader>th :call EditTodoPlanH()<cr>
nnoremap <leader>tt :call MakeSmall()<cr>
nnoremap <leader>ts :call SmallWindow()<cr>
"##################################################################################
" SIMPLE VIEW
"##################################################################################

View File

@@ -5,11 +5,13 @@
# 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
# find that the two pass normalize-volume 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
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -50,3 +52,4 @@ 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"
flash_taskbar

View File

@@ -1,22 +1,32 @@
@setlocal enableextensions enabledelayedexpansion
@echo off
rem Make sure we're running as admin. Got this garbage from https://stackoverflow.com/a/40388766
if not "%1"=="am_admin" (
powershell -Command "Start-Process -Verb RunAs -FilePath '%0' -ArgumentList 'am_admin'"
exit /b
)
setlocal enableextensions enabledelayedexpansion
rem NOTE: Defender may see this file as malware, so you might need to exclude this before things can be disabled.
rem
rem Modified version of
rem https://raw.githubusercontent.com/mattreecebentley/win10_disable_defender/main/win10_enable_defender.bat
rem https://gist.github.com/xezrunner/a7a42dbc1096a40b0c78f09488fe5a2b
rem Modified version of:
rem https://github.com/ggannann/win10_disable_defender
rem https://gist.github.com/xezrunner/a7a42dbc1096a40b0c78f09488fe5a2b (as of Jan 2026 this seems to have been deleted or made private)
rem ============================
rem Self-elevate via UAC if needed
rem - Detect admin by checking membership in Administrators (SID S-1-5-32-544)
rem - Relaunch this script elevated using PowerShell Start-Process -Verb RunAs
rem ============================
rem Test for membership in Administrators group
whoami /groups | find "S-1-5-32-544" >nul
if errorlevel 1 (
echo Requesting administrative privileges...
rem Relaunch the same script elevated, preserving args and working directory
powershell -NoProfile -Command ^
"Start-Process -FilePath '%~f0' -ArgumentList '%*' -Verb RunAs -WorkingDirectory (Get-Location).Path"
exit /b
)
echo Running with administrative privileges.
echo.
reg query HKLM\SYSTEM\Setup /v DisabledDefenderServices | find "0x1"
if %errorlevel% == 0 goto already_patched
echo.
echo Please note that Defender can only be disabled in Win10 v2004 and upwards if Tamper Protection is disabled.
echo This setting can be found in Window settings (hint: search for 'tamper'). Please do this now and then,
pause
@@ -104,3 +114,4 @@ echo Defender has already been disabled by this script.
:eof
echo.
pause

View File

@@ -1,17 +1,11 @@
@setlocal enableextensions enabledelayedexpansion
@echo off
setlocal enableextensions enabledelayedexpansion
rem Make sure we're running as admin. Got this garbage from https://stackoverflow.com/a/40388766
if not "%1"=="am_admin" (
powershell -Command "Start-Process -Verb RunAs -FilePath '%0' -ArgumentList 'am_admin'"
exit /b
)
rem NOTE: Defender may see this file as malware, so you might need to exclude this before things can be disabled.
rem USE AT OWN RISK AS IS WITHOUT WARRANTY OF ANY KIND !!!!!
rem
rem Modified version of
rem https://raw.githubusercontent.com/mattreecebentley/win10_disable_defender/main/win10_enable_defender.bat
rem https://gist.github.com/xezrunner/a7a42dbc1096a40b0c78f09488fe5a2b
rem Modified version of:
rem https://github.com/ggannann/win10_disable_defender
rem https://gist.github.com/xezrunner/a7a42dbc1096a40b0c78f09488fe5a2b (as of Jan 2026 this seems to have been deleted or made private)
rem
rem Resources:
rem https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=win10-ps
@@ -19,7 +13,23 @@ rem https://docs.microsoft.com/en-us/windows/threat-protection/windows-defender-
rem https://github.com/AndyFul/ConfigureDefender
rem https://github.com/AndyFul/Hard_Configurator
rem ============================
rem Self-elevate via UAC if needed
rem - Detect admin by checking membership in Administrators (SID S-1-5-32-544)
rem - Relaunch this script elevated using PowerShell Start-Process -Verb RunAs
rem ============================
rem Test for membership in Administrators group
whoami /groups | find "S-1-5-32-544" >nul
if errorlevel 1 (
echo Requesting administrative privileges...
rem Relaunch the same script elevated, preserving args and working directory
powershell -NoProfile -Command ^
"Start-Process -FilePath '%~f0' -ArgumentList '%*' -Verb RunAs -WorkingDirectory (Get-Location).Path"
exit /b
)
echo Running with administrative privileges.
echo.
echo Enabling Windows Defender
reg query HKLM\SYSTEM\Setup /v DisabledDefenderServices | find "0x0"
if %errorlevel% == 0 goto already_patched
@@ -106,3 +116,4 @@ echo Defender has already been enabled by this script.
:eof
echo.
pause

View File

@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# Shows you the status of an object restore job.
#
# e.g. aws-check-restore-status my-deep-glacier-bucket object/path.png
#
# You know it's ready when ongoing-request is false and there's a date. If that field is null then the file isn't being restored.
#
# 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
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
error() {
printf "${BOLD}${RED}$1${NORMAL}\n"
}
abort() {
error "\nAborting...\n"
exit 1
}
set -e
bucket="$1"
path="$2"
if [[ $bucket == "" || $path == "" ]]; then
error "Usage: aws-check-restore-status <bucket-name> <path-in-bucket>"
exit 1
fi
aws s3api head-object --bucket $bucket --key "$path" --query "{Restore:Restore, StorageClass:StorageClass}" --output json

View File

@@ -52,11 +52,6 @@ error() {
printf "${BOLD}${RED}$1${NORMAL}\n"
}
abort() {
error "\nAborting...\n"
exit 1
}
set -e
bucket="$1"
@@ -68,4 +63,24 @@ if [[ $bucket == "" || $path == "" || $output_file == "" ]]; then
exit 1
fi
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' > "$output_file"
# .Key gives us just the object paths. If you want the other metadata then remove that from the query.
items="$(aws s3api list-objects-v2 --bucket $bucket --prefix "$path" --query "Contents[?StorageClass=='DEEP_ARCHIVE'].Key" --output text | tr '\t' '\n' | tr -d '\r')"
error=$?
if [[ ! $error -eq 0 ]]; then
error "Error: failed to run the aws command. Aborting."
exit 1
fi
if [[ $items == "None" ]]; then
error "Didn't find any files. Check that your bucket name and path is correct."
exit 1
fi
mapfile -t lines_array <<< "$items"
item_count="${#lines_array[@]}"
echo "$items" > "$output_file"
printf "Number of items: ${BOLD}${YELLOW}$item_count${NORMAL}\n"
printf "Wrote file list to ${BOLD}${YELLOW}$output_file${NORMAL}\n"

View File

@@ -1,28 +1,44 @@
#!/usr/bin/env bash
# Restores all objects recursively from a specific bucket path. If want to
# restore objects from an rclone crypt (encrypted remote), then you'll need to
# do some manual steps first. See the `# Rclone Crypt` section for details.
#
# Restores all files/folders inside a particular bucket path for the next 7 days. This uses the bulk retrieval tier:
# You can set how long restore files are available for download and the AWS
# retrieval tier. The defaults are 7 days and the bulk tier respectively.
#
# Available tiers: bulk, standard, and expedited.
#
# Bulk retrievals are the lowest-cost retrieval option when restoring objects
# 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.
# 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
# aws-restore-deep-glacier-folder my-deep-glacier-bucket path/to/images restored_images 14 expedited
#
# 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.
# 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 from the
# my-deep-glacier bucket. Restored objects will be available for 14 days and
# retrieved using the expedited tier.
#
# 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:
# 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
# aws s3api head-object --bucket my-deep-glacier-bucket --key "path/to/images/photo1.jpg" --query "{Restore:Restore, StorageClass:StorageClass}"
#
# (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.
# Or use the aws-check-restore-status script.
# You know it's ready when ongoing-request is false and there's a date. If that
# field is null then the file isn't being restored.
#
# 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.
@@ -44,6 +60,67 @@
# You can enable the UTF-8 locale with:
#
# win+r -> intl.cpl -> Administrative tab -> Change system locale -> Beta: Use Unicode UTF-8 box.
##########################
# Rclone Crypt
##########################
#
# To restore an rclone crypt, you need to first find the encrypted name that
# maps to the parent folder or the file you want to restore. To do this you
# need to use rclone. There are two ways to go about this.
#
# 1. The simple way is to use `cryptdecode` to convert your object path to its
# encrypted form.
#
# For example, say you have an rclone crypt called `s3-deep-glacier-encrypted`
# that is stored in S3 at `my-deep-glacier-bucket:encrypted/` You have a folder
# called `dev/fonts` that you want to restore. To get its path, run the following
# command:
#
# rclone cryptdecode --reverse s3-deep-glacier-encrypted: dev/fonts
#
# This will give you the encrypted path, e.g. "44ildo3grlk44jmfr96nb5r56o/oatuh75ej3l4re96nvq2qbj8ik"
#
# You can now restore this by running:
#
# aws-restore-deep-glacier-folder my-deep-glacier-bucket 44ildo3grlk44jmfr96nb5r56o/oatuh75ej3l4re96nvq2qbj8ik restore_dev_fonts
#
# You should be able to simply download the dev/fonts folder after its
# restored. The easiest way is using rclone browser because it'll decrypt them
# for you. Alternatively you can download the encrypted files using whatever
# method you want and then decrypt them locally with rclone.
#
# 2. You can also get the encrypted names by enabling the 'show_mapping' option
# in the rclone remote config. This will log the encrytped names of folders and
# files with the original name in the same log line. This makes it easy to
# parse the output.
#
# To enable the option, edit your rclone config, edit the remote you want to
# restore from, edit the advanced config and set `show_mapping` to true.
#
# Now you can list the directories and files with rclone and get the mapping
# output on stderr. e.g. let's capture all folders and files in a txt file:
#
# rclone lsf s3-deep-glacier-encrypted: -R &> keys.txt
#
# If your rclone config has password protection then you'll be prompted for it
# but won't see the output since it's being written to the file. Just paste it
# and hit enter.
#
# Now you have a listing of all objects and the encrypted keys that they map
# to. If you want to scope the output to a specific path in the crypt then add
# it after the remote name, e.g. `s3-deep-glacier-encrypted:dev/fonts`
#
# If you scope it like that then be aware that the output won't contain the
# mapping for the parent path, i.e. `dev/fonts`, but you can get that using
# `cryptdecode` (see above) or with some non-recursive outputs of the parent
# parts using `lsd`, e.g.
#
# // First call will include the dev/ key
# rclone lsd s3-deep-glacier-encrypted:
#
# // Second call has the fonts key
# rclone lsd s3-deep-glacier-encrypted:dev
#
if which tput >/dev/null 2>&1; then
@@ -73,57 +150,177 @@ error() {
printf "${BOLD}${RED}$1${NORMAL}\n"
}
abort() {
error "\nAborting...\n"
exit 1
}
set -e
bucket="$1"
path="$2"
temp_dir="$3"
number_of_objects_per_file=100
days_available=7
restore_tier="Bulk" # Can also be "Standard" or "Expedited"
restore_tier="bulk" # Can also be "standard" or "expedited"
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> <optional: days available> <optional: restore tier>"
exit 1
fi
printf "Restoring ${BOLD}${GREEN}$bucket:$path${NORMAL} with local temp folder ${BOLD}${GREEN}$temp_dir${NORMAL}\n"
# Get the days available.
if [[ $4 != "" ]]; then
days_available=$4
fi
# Get the restore tier.
if [[ $5 != "" ]]; then
restore_tier="$5"
fi
if ! grep -qiE '\b(bulk|standard|expedited)\b' <<<"$restore_tier"; then
error "Restore tier is invalid. Accepted values is \"bulk\", \"standard\" and \"expedited\""
exit 1
fi
# Normalize the tier; lowercase it then capitalize the first character.
restore_tier="${restore_tier,,}"
restore_tier="${restore_tier^}"
printf "Restoring ${BOLD}${YELLOW}$bucket:$path${NORMAL} for ${BOLD}${YELLOW}$days_available${NORMAL} days using the ${BOLD}${YELLOW}\"$restore_tier\"${NORMAL} restore tier.\nSaving the restoration script in ${BOLD}${YELLOW}$temp_dir${NORMAL}\n"
mkdir -p "$temp_dir"
pushd "$temp_dir" &>/dev/null
items="$(aws s3api list-objects-v2 --bucket $bucket --prefix $path --query "Contents[?StorageClass=='DEEP_ARCHIVE']" --output text)"
# .Key gives us just the object paths. If you want the other metadata then remove that from the query.
items="$(aws s3api list-objects-v2 --bucket $bucket --prefix "$path" --query "Contents[?StorageClass=='DEEP_ARCHIVE'].Key" --output text | tr '\t' '\n' | tr -d '\r')"
error=$?
if [[ ! $error -eq 0 ]]; then
error "Error: failed to run the aws command. Aborting."
exit 1
fi
if [[ $items == "None" ]]; then
error "Didn't find any files. Check that your bucket name and path is correct."
exit 1
fi
# Format the items list.
output="$(echo "$items" | LC_ALL=C awk '{print substr($0, index($0, $2))}' | awk '{NF-=3};3')"
mapfile -t lines_array <<< "$items"
item_count="${#lines_array[@]}"
mapfile -t lines_array <<< "$output"
num_items="${#lines_array[@]}"
# Generate the main script that will kick off the restoration.
printf "Number of items to restore: ${BOLD}${YELLOW}$item_count${NORMAL}\n"
printf "${BOLD}${RED}Create the restore script?\n> ${NORMAL}"
printf "Number of items to restore: ${BOLD}${YELLOW}$num_items${NORMAL}\n"
printf "${BOLD}${RED}Proceed?\n> ${NORMAL}"
read -e proceed
if [[ $proceed == "1" || $proceed == "y" || $proceed == "Y" || $proceed == "yes" || $proceed == "YES" ]]; then
echo "$output" > all_objects_list.txt
echo "$items" > all_objects_list.txt
RUN_TEMPLATE=$(cat <<EOF
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
# Open an output file.
exec 3>>output.txt
fail_count=0
failed_filename="failed_keys_\$(printf '%%04x' \$((RANDOM * RANDOM))).txt"
before_sleep_count=0
sleep_every_n_requests=25
sleep_duration=0.2
printf "Files are being restored for $days_available days using the $restore_tier tier\\\n\\\n"
printf "Files are being restored for $days_available days using the $restore_tier tier\\\n\\\n" >&3
printf "\${BOLD}NOTE: Request failures will be saved to \${YELLOW}\$failed_filename\${NORMAL}\${BOLD} as they happen. If this script terminates prematurely then check this file for failures.\\\n\\\n"
printf "NOTE: Request failures will be saved to \$failed_filename as they happen. If this script terminates prematurely then check this file for failures.\\\n\\\n" >&3
index=1
while read key; do
printf "* [\$index/$item_count] \${BOLD}\$key\${NORMAL}\\\n"
printf "* [\$index/$item_count] \$key\\\n" >&3
err=\$(
aws s3api restore-object \\
--bucket mcampagnaro-deep-glacier \\
--key \\"\$key\\" \\
--restore-request '{\\"Days\\":$days_available,\\"GlacierJobParameters\\":{\\"Tier\\":\\"$restore_tier\\"}}' \\
2>&1 >/dev/null
)
index=\$((index + 1))
before_sleep_count=\$((before_sleep_count + 1))
# strip newlines
err="\${err//[$'\\\t\\\r\\\n']}"
if [[ \$err != "" ]]; then
if ! grep -qE 'RestoreAlreadyInProgress|ObjectAlreadyInActiveTierError' <<<"\$err"; then
printf "\${BOLD}\${RED}FAILED! \$err\${NORMAL}"
printf "FAILED! \$err\" >&3
# Save the failure to a file now in case the script exits prematurely.
fail_count=\$((fail_count + 1))
printf "%%s\\\n" "\$key" >> \$failed_filename
else
if grep -qE 'RestoreAlreadyInProgress' <<<"\$err"; then
printf "\${BOLD}\${YELLOW}SKIPPING! File restore is already in progress.\${NORMAL}"
printf "SKIPPING! File restore is already in progress." >&3
else
printf "\${BOLD}\${YELLOW}SKIPPING! File is already restored. You can now download it.\${NORMAL}"
printf "SKIPPING! File is already restored. You can now download it." >&3
fi
fi
else
printf "\${BOLD}\${GREEN}SUCCESS!\${NORMAL}"
printf "SUCCESS!" >&3
fi
printf "\\\n\\\n"
printf "\\\n\\\n" >&3
if [[ \$before_sleep_count -eq sleep_every_n_requests ]]; then
printf "SLEEPING...\\\n\\\n"
printf "SLEEPING...\\\n\\\n" >&3
sleep \$sleep_duration
before_sleep_count=0
fi
done < all_objects_list.txt
printf "\${BOLD}\${GREEN}Done!\${NORMAL}\\\n\\\n"
printf "Done!\\\n\\\n" >&3
if [[ \$fail_count > 0 ]]; then
printf "\${BOLD}\${RED}There were \$fail_count failures!\\\nSee \${NORMAL}\${BOLD}\$filename\${RED} for the list. You can replace the contents of \${NORMAL}\${BOLD}all_objects_list.txt\${RED} with the list of failures and re-run this script to process them.\${NORMAL}\\\n\\\n"
printf "There were \$fail_count failures!\\\nSee \$filename for the list. You can replace the contents of all_objects_list.txt with the list of failures and re-run this script to process them.\\\n\\\n" >&3
else
printf "There were no failures. All the files are being restored. You can now delete this folder.\\\n\\\n"
printf "There were no failures. All the files are being restored. You can now delete this folder.\\\n\\\n" >&3
fi
printf "(Note: the time it takes to restore an object 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"
printf "You can check the status of a file using the aws-check-restore-status script)\\\n"
exec 3>&-
EOF
)
printf "$RUN_TEMPLATE" > run.sh
# 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.\\\\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
printf "${BOLD}You can now run ${GREEN}$temp_dir/run.sh${NORMAL}${BOLD} to start the restoration process.\n"

View File

@@ -7,6 +7,8 @@
#
# Inspired by https://superuser.com/a/323127 and https://superuser.com/a/1312885
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -57,3 +59,4 @@ eval $cmd
printf "\n${GREEN}${BOLD}Done modifying volume in $filename.$extension | output: $output | delta: $delta_db${NORMAL}\n"
flash_taskbar

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env bash
# Bigger crf values == bigger compression.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -23,10 +27,13 @@ else
NORMAL=""
fi
use_gpu=0
use_gpu=1
# Found the following to work best with vids containing text (e.g. programming vids). These give similar bitrates.
cpu_crf=20
gpu_crf=33
if [[ $# < 2 || $# > 3 ]]; then
printf "${BOLD}${RED}Usage: compress-video <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> ${NORMAL}\n"
if [[ $# < 2 || $# > 5 ]]; then
printf "${BOLD}${RED}Usage: compress-video <filename> <output name> <optional: use-gpu (1|0), defaults to $use_gpu> <optional: start time HH:MM:SS> <optional: end time HH:MM:SS> (NOTE: gpu crf is $gpu_crf and cpu crf is $cpu_crf - change it by calling compress-video-with-crf)${NORMAL}\n"
exit 1
fi
@@ -37,11 +44,12 @@ if [[ $# > 2 ]]; then
use_gpu=$3
fi
# Found the following to work best with vids containing text (e.g. programming vid): 21 for CPU encoding and 28 for GPU (similar bitrates).
use_crf=21
use_crf=$cpu_crf
if [[ $use_gpu -eq 1 ]]; then
use_crf=28
use_crf=$gpu_crf
fi
compress-video-with-crf $use_crf "$filename" "$output_name" $use_gpu
compress-video-with-crf $use_crf "$filename" "$output_name" $use_gpu $4 $5
flash_taskbar

View File

@@ -1,5 +1,9 @@
#!/usr/bin/env bash
# Bigger crf values == bigger compression.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -23,7 +27,7 @@ else
NORMAL=""
fi
use_gpu=0
use_gpu=1
if [[ "$#" < 3 || "$#" > 6 ]]; then
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"
@@ -66,18 +70,24 @@ function encode() {
if [[ $use_gpu -eq 1 ]]; then
# RTX 3080
ffmpeg -y -stats -loglevel level+error $timing_args -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i "$filename.$extension" -c:a copy -c:v h264_nvenc -profile:v high -rc:v vbr_hq -cq:v $crf -b:v 5M -maxrate 5M -max_muxing_queue_size 9999 "$output"
# vbr_hq is smaller file and less bitrate than vbr - strange!
ffmpeg -y -stats -loglevel level+error -hwaccel cuda -hwaccel_output_format cuda $timing_args -accurate_seek -i "$filename.$extension" -c:v h264_nvenc -profile:v high -preset 3 -rc:v vbr -cq:v $crf -c:a copy -max_muxing_queue_size 9999 -movflags +faststart "$output"
# GTX 1070
#ffmpeg -y -stats -loglevel level+error $timing_args -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i "$filename.$extension" -c:a copy -c:v h264_nvenc -profile:v high -rc:v vbr_hq -cq:v $crf -b:v 5M -maxrate 5M -max_muxing_queue_size 9999 "$output"
# capped bitrate w/ crf is weird. gives a more compressed copy
# ffmpeg -y -stats -loglevel level+error -hwaccel cuda -hwaccel_output_format cuda $timing_args -accurate_seek -i "$filename.$extension" -c:v h264_nvenc -profile:v high -preset 3 -cq:v $crf -b:v 1200K -maxrate:v 1200K -bufsize:v 2400K -c:a copy -max_muxing_queue_size 9999 -movflags +faststart "$output"
else
ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c:v libx264 -crf $crf -preset veryfast -profile:v high -level 3.0 -strict -2 "$output"
fi
printf "\n${GREEN}${BOLD}Finished encoding '$filename.$extension' (CRF $crf) | output name '$output'${NORMAL}\n\n"
original_size=$(wc -c <"$filename.$extension")
new_size=$(wc -c <"$output")
printf "${BOLD}Original size: $original_size${NORMAL}\n"
printf "${BOLD}New size: $new_size${NORMAL}\n\n"
}
if [[ $use_crf -ne -1 ]]; then
encode $use_crf
time encode $use_crf
else
printf "\n${YELLOW}${BOLD}Encoding using a range of CRF values.${NORMAL}\n"
@@ -87,3 +97,5 @@ else
encode $crf
done
fi
flash_taskbar

View File

@@ -3,6 +3,8 @@
# This is for reencoding a non-mp4 video to mp4 using an mpeg4 encoder.
# Can optionally compress the video.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -94,3 +96,5 @@ else
fi
printf "${GREEN}${BOLD}Done encoding '$filename.$extension' to '$output'${NORMAL}\n\n"
flash_taskbar

View File

@@ -1,6 +1,9 @@
#!/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.
# Re-encodes the video to get a more accurate timeline. Same settings as trim-video-vbr.
# If you want fast video joining at the expense of accuracy then use join-video-fast.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
@@ -26,18 +29,41 @@ else
fi
filename=$(basename -- "$1")
output_name="$2"
output="$2"
target_crf="$3"
max_bitrate_mb="$4"
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"
default_crf="33" # if you want to compress then use the same gpu compression level from compress-video (i.e. 33, but verify it's still set to this)
default_max_bitrate="6"
if [[ $filename == "" || $output == "" ]]; 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\njoin-video <list filename> <output name> <optional: crf (quality, value = compression level) - defaults to $default_crf, use 0 for no value> <optional: max bitrate in MB - defaults to ${default_max_bitrate}M>${NORMAL}\n"
exit 1
fi
output="${output_name}.mp4"
extension="${output##*.}"
if [[ $extension == $output ]]; then
printf "${BOLD}${RED}output arg should have an extension!\n\nUsage: join-video <list filename> <output name> <optional: crf (quality, value = compression level) - defaults to $default_crf, use 0 for no value> <optional: max bitrate in MB - defaults to ${default_max_bitrate}M>${NORMAL}\n"
exit 1
fi
printf "\n${YELLOW}${BOLD}Joining contents of '$filename'| output: $output${NORMAL}\n"
if [[ $target_crf == "" || $target_crf == "0" ]] then
target_crf=$default_crf
fi
ffmpeg -y -stats -loglevel level+error -f concat -safe 0 -accurate_seek -i "$filename.$extension" -c:v libx264 -c:a copy "$output"
if [[ $max_bitrate_mb == "" ]] then
max_bitrate_mb=$default_max_bitrate
fi
# bufsize is typically double the maxrate
bufsize=$((max_bitrate_mb * 2))
bufsize="${bufsize}M"
max_bitrate="${max_bitrate_mb}M"
printf "\n${YELLOW}${BOLD}Joining contents of '$filename' | output: $output | crf: $target_crf | max rate: $max_bitrate | buffer size: $bufsize ${NORMAL}\n"
time ffmpeg -y -stats -loglevel level+error -hwaccel cuda -hwaccel_output_format cuda -f concat -safe 0 -accurate_seek -i "$filename" -c:v h264_nvenc -profile:v high -preset 3 -rc:v vbr -cq:v $target_crf -maxrate:v $max_bitrate -bufsize:v $bufsize -c:a copy -movflags +faststart "$output"
printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n"
flash_taskbar

View File

@@ -5,6 +5,8 @@
# playback time might oscillate a bit. Use join-video for accurate joining at
# the cost of a much slower processing time.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -44,3 +46,4 @@ ffmpeg -y -stats -loglevel level+error -f concat -safe 0 -i "$filename" -c copy
printf "\n${GREEN}${BOLD}Finished joining${NORMAL}\n\n"
flash_taskbar

View File

@@ -1,12 +1,17 @@
#!/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.
# 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
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -75,3 +80,4 @@ eval "$cmd"
printf "\n${GREEN}${BOLD}Done normalizing volume in $filename.$extension | output: $output${NORMAL}\n"
rm $temp_file
flash_taskbar

View File

@@ -2,6 +2,8 @@
# Re-encodes the audio to get a more accurate seek time.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -53,5 +55,9 @@ printf "\n${YELLOW}${BOLD}Trimming '$filename' | output: $output_name_with_exten
ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -i "$filename" -map a "$output_name_with_extension"
#If you want to have a specific bit rate and sample rate then you need to add it before the output filename. Might also need to remove the -map a arg. e.g.
#ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -i "$filename" -c:a aac -b:a 191k -ar 48000 "$output_name_with_extension"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"
flash_taskbar

View File

@@ -2,6 +2,8 @@
# 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.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -62,3 +64,4 @@ ffmpeg -y -stats -loglevel level+error $timing_args -accurate_seek -async 1 -i "
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"
flash_taskbar

View File

@@ -5,6 +5,8 @@
# time might oscillate a bit. Use trim-video for accurate trimming at the cost
# of a much slower processing time.
source "$HOME/dotfiles/script_helpers/windows.sh"
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
@@ -64,3 +66,4 @@ ffmpeg -y -stats -loglevel level+error $timing_args -i "$filename.$extension" -c
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"
flash_taskbar

View File

@@ -0,0 +1,95 @@
#!/usr/bin/env bash
# Re-encodes the video using a constrained bitrate/output size. If you want to
# control the visual quality with a variable bitrate then use trim-video-vbr
source "$HOME/dotfiles/script_helpers/windows.sh"
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"
target_bitrate_mb="$3"
start_time="$4"
end_time="$5"
if [[ $filename == "" || $output_name == "" || $target_bitrate_mb == "" || $start_time == "" ]]; then
printf "${BOLD}${RED}Usage: trim-video <filename> <output name> <target bitrate in MB, e.g. 6> <start time HH:MM:SS> <optional: end time HH:MM:SS, use empty string or 0 for no value>${NORMAL}\n"
exit 1
fi
extension="${filename##*.}"
filename="${filename%.*}"
output="${output_name}.$extension"
# bufsize is typically double the maxrate
bufsize=$((target_bitrate_mb * 2))
bufsize="${bufsize}M"
bitrate="${target_bitrate_mb}M"
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}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time | max rate: $bitrate | buffer size: $bufsize ${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. If you want to target one of
# the video streams then use `-map 0:v:0` and if you want to re-encode
# subtitles then include `-c:s mov_text` with either of the `-map` args.
# -preset 3 and 4 are the fastest on my 3080 and have the same output file
# size. p3 seems slightly faster. Apparently 7 is the best for 30 series
# according to chatgpt (lol) but it was slow and compressed.
# -accurate_seek doesn't seem to be needed when -ss is after -i, only when -ss
# is before -i. Having -ss after is apparently a way of enabling accurate
# seeking. The catch is that if the trim doesn't start at 0, it can be a long
# wait before the encoder gets to the portion you want to start trimming from.
# To speed this up we are putting -ss and -accurate_seek before -i ... the
# video duration might be slightly off from this but so far I haven't seen any
# seeking issues. If they come up then we can move -ss to after -i again and
# delete -accurate_seek.
# I'm using -b:v, -maxrate:v, and -bufsize:v to constrain the bitrate and
# indirectly control quality. The bitrate won't be fixed exactly to -b:v
# unless using CBR, but NVENC will attempt to average around it and cap the
# bitrate at -maxrate:v, using -bufsize:v as a smoothing buffer.
ffmpeg -y -stats -loglevel level+error -hwaccel cuda -hwaccel_output_format cuda $timing_args -accurate_seek -i "$filename.$extension" -c:v h264_nvenc -profile:v high -preset 3 -b:v $bitrate -maxrate:v $bitrate -bufsize:v $bufsize -c:a copy -movflags +faststart "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"
flash_taskbar

129
dotfiles/bin/trim-video-vbr Normal file
View File

@@ -0,0 +1,129 @@
#!/usr/bin/env bash
# Re-encodes the video using a target quality level and a variable bitrate.
# To have a mostly fixed bitrate with no variable quality, use trim-video-target-rate
# Just note that it'll result in larger files for a similar max bitrate target and the
# quality won't really be noticeably better.
#
# The higher the CRF value, the higher the compression.
source "$HOME/dotfiles/script_helpers/windows.sh"
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"
target_crf="$5"
max_bitrate_mb="$6"
default_crf="33" # if you want to compress then use the same gpu compression level from compress-video (i.e. 33, but verify it's still set to this)
default_max_bitrate="6"
if [[ $filename == "" || $output_name == "" || $start_time == "" ]]; then
printf "${BOLD}${RED}Usage: trim-video-vbr <filename> <output name> <start time HH:MM:SS> <optional: end time HH:MM:SS, use empty string or 0 for no value> <optional: crf (quality, value = compression level) - defaults to $default_crf, use 0 for no value> <optional: max bitrate in MB - defaults to ${default_max_bitrate}M>${NORMAL}\n"
exit 1
fi
extension="${filename##*.}"
filename="${filename%.*}"
output="${output_name}.$extension"
if [[ $target_crf == "" || $target_crf == "0" ]] then
target_crf=$default_crf
fi
if [[ $max_bitrate_mb == "" ]] then
max_bitrate_mb=$default_max_bitrate
fi
# bufsize is typically double the maxrate
bufsize=$((max_bitrate_mb * 2))
bufsize="${bufsize}M"
max_bitrate="${max_bitrate_mb}M"
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}Trimming '$filename.$extension' | output: $output | start: $start_time | end: $end_time | crf: $target_crf | max rate: $max_bitrate | buffer size: $bufsize ${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. If you want to target one of
# the video streams then use `-map 0:v:0` and if you want to re-encode
# subtitles then include `-c:s mov_text` with either of the `-map` args.
# -preset 3 and 4 are the fastest on my 3080 and have the same output file
# size. p3 seems slightly faster. Apparently 7 is the best for 30 series
# according to chatgpt (lol) but it was slow and compressed.
# -accurate_seek doesn't seem to be needed when -ss is after -i, only when -ss
# is before -i. Having -ss after is apparently a way of enabling accurate seeking.
# The catch is that if the trim doesn't start at 0, it can be a long wait before
# the encoder gets to the portion you want to start trimming from. To speed this up
# we are putting -ss and -accurate_seek before -i ... the video duration might be
# slightly off from this but so far I haven't seen any seeking issues. If they come
# up then we can move -ss to after -i again and delete -accurate_seek.
# I'm using -rc:v vbr -cq:v 20 (higher = more compression) to have a variable
# bit-rate with a quality target. This gives us a good looking re-encoding that
# does a good job preserving the quality of the source video (at least for
# twitch streams I'm trimming) but the bitrate might be higher or lower than
# the source. The quality metric will fluctuate during encoding because NVENC
# does't use a fixed quantization parameter. -cq:v is a target, not a constraint.
# So you can have quite the fluctuating (or high) bitrate with these two params.
# In order to set a birate cap that is prioritized over visual fidelity, we can
# add in:
# -maxrate:v -bufsize:v
# (with bufsize typically being double the maxrate)
#
# Using this with the vbr and crf params tells the NVENC encoder to try to
# encode at a perceptual quality level around CQ=20 but keep the bitrate under
# 6000 kbps (constrained VBR). If a scene is too complex to maintain CQ=20
# within the bitrate cap, the encoder will:
# * Raise the quantizer (lower quality) to obey the -maxrate
# * Result: CQ metric fluctuates upward
# If a scene is simple:
# * Encoder can exceed CQ=20 (e.g. better quality) while staying under maxrate
# * Result: CQ metric fluctuates downward
#
# To have a mostly fixed bitrate with no variable quality, use trim-video-target-rate
time ffmpeg -y -stats -loglevel level+error -hwaccel cuda -hwaccel_output_format cuda $timing_args -accurate_seek -i "$filename.$extension" -c:v h264_nvenc -profile:v high -preset 3 -rc:v vbr -cq:v $target_crf -maxrate:v $max_bitrate -bufsize:v $bufsize -c:a copy -movflags +faststart "$output"
printf "\n${GREEN}${BOLD}Finished trimming${NORMAL}\n\n"
flash_taskbar

View File

@@ -1,3 +1,5 @@
NOTE: Best option is to create/store private keys in Bitwarden.
# Creating an elliptic curve keypair (ed25519)
* Create: `ssh-keygen -a 100 -t ed25519 -f ~/.ssh/filename`

View File

@@ -59,18 +59,18 @@
127.0.0.1 www.wip2.adobe.com www.wip3.adobe.com www.wip4.adobe.com wwis-dubc1-vip60.adobe.com crl.verisign.net CRL.VERISIGN.NET ood.opsource.net
# Block Facebook
127.0.0.1 www.facebook.com
127.0.0.1 facebook.com
127.0.0.1 static.ak.fbcdn.net
127.0.0.1 www.static.ak.fbcdn.net
127.0.0.1 login.facebook.com
127.0.0.1 www.login.facebook.com
127.0.0.1 fbcdn.net
127.0.0.1 www.fbcdn.net
127.0.0.1 fbcdn.com
127.0.0.1 www.fbcdn.com
127.0.0.1 static.ak.connect.facebook.com
127.0.0.1 www.static.ak.connect.facebook.com
#127.0.0.1 www.facebook.com
#127.0.0.1 facebook.com
#127.0.0.1 static.ak.fbcdn.net
#127.0.0.1 www.static.ak.fbcdn.net
#127.0.0.1 login.facebook.com
#127.0.0.1 www.login.facebook.com
#127.0.0.1 fbcdn.net
#127.0.0.1 www.fbcdn.net
#127.0.0.1 fbcdn.com
#127.0.0.1 www.fbcdn.com
#127.0.0.1 static.ak.connect.facebook.com
#127.0.0.1 www.static.ak.connect.facebook.com
#----------------------------------------------
@@ -15825,15 +15825,3 @@
127.0.0.1 spynetalt.microsoft.com
# End of en inserted by Spybot Anti-Beacon for Windows 10
# TailscaleHostsSectionStart
# This section contains MagicDNS entries for Tailscale.
# Do not edit this section manually.
100.69.212.80 gamma.sir-pinecone.github.beta.tailscale.net.
100.69.212.80 gamma.taile86d5.ts.net. gamma
100.105.152.57 quark.sir-pinecone.github.beta.tailscale.net.
100.105.152.57 quark.taile86d5.ts.net. quark
100.90.157.82 samsung-sm-s901w.sir-pinecone.github.beta.tailscale.net.
100.90.157.82 samsung-sm-s901w.taile86d5.ts.net. samsung-sm-s901w
# TailscaleHostsSectionEnd

View File

@@ -0,0 +1,4 @@
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell]
"FolderType"="NotSpecified"

View File

@@ -60,6 +60,12 @@
* Desktop: turn off hibernation
* Open admin cmd prompt: `powercfg.exe /hibernate off`
* Enable long paths:
* winkey+r -> `gpedit.msc`.
* Computer Configuration > Administrative Templates > System > Filesystem
* Double-click the `Enable Win32 long paths` policy.
* Select Enabled.
* Disable power throttling:
* winkey+r -> `gpedit.msc`.
* Computer Configuration > Administrative Templates > System > Power Management > Power Throttling Settings