Last active
August 12, 2024 00:15
-
-
Save anonymous1184/e08453e3ba393622d8fef3046764a2a3 to your computer and use it in GitHub Desktop.
YouTube Download Helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| |
; | |
; REQUIRED | |
; | |
ytdl.Path := "D:\CLI\youtube" | |
; Path of yt-dlp.exe | |
; | |
; OPTIONAL | |
; The values below represent the defaults | |
; | |
; FFmpeg directory | |
ytdl.FFmpeg := "..\FFmpeg" | |
; Simple bypass | |
ytdl.GeoBypass := true | |
; Via country code | |
; ytdl.GeoBypass := "US" | |
; From an IP block (CDIR) | |
; ytdl.GeoBypass := "35.190.247.0/24" | |
; Embed metadata? | |
ytdl.Metadata := true | |
; Time between downloads | |
ytdl.SleepInterval := 0 | |
; Audio options | |
; 'm4a'/'opus' natively | |
ytdl.Audio.Format := "m4a" | |
; Others need recoding (like mp3) | |
; Thumbnail? | |
ytdl.Audio.Thumbnail := false | |
; Video options | |
; mkv | |
; mp4 | |
; ogg | |
; webm | |
ytdl.Video.Container := "mp4" | |
; 144p = 144 | |
; 240p = 240 | |
; 360p = 360 | |
; 480p = 480 | |
; HD = 720 | |
; FHD = 1080 | |
; QHD = 1440 | |
; 4k = 2160 | |
; 8k = 4320 | |
ytdl.Video.Quality := 1080 | |
; Thumbnail? | |
ytdl.Video.Thumbnail := true | |
#NoEnv | |
EnvGet UserProfile, USERPROFILE | |
MusicDir := UserProfile "\Music" | |
VideoDir := UserProfile "\Videos" | |
GroupAdd Browsers, ahk_exe chrome.exe | |
GroupAdd Browsers, ahk_exe firefox.exe | |
GroupAdd Browsers, ahk_exe msedge.exe | |
GroupAdd Browsers, ahk_exe opera.exe | |
return ; End of auto-execute | |
#If WinActive("ahk_group Browsers") | |
!y::ytdl(MusicDir, 1) | |
^y::ytdl(VideoDir, 2) | |
#If |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| |
; Version: 2023.10.13.1 | |
/* | |
# Examples | |
See the file above. | |
# Dependencies | |
## yt-dlp | |
https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe | |
## FFmpeg | |
https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-essentials.7z | |
FFmpeg binaries must be accessible to `yt-dlp` for format conversions. | |
You can drop them in the folder where yt-dlp.exe resides: | |
- ffmpeg.exe | |
- ffplay.exe | |
- ffprobe.exe | |
Else, function expects them to be in the same level as yt-dlp binary. Example: | |
- D:\CLI\FFmpeg | |
- D:\CLI\yt-dlp | |
Alternatively, to use an explicit path, set the option: | |
ytdl.FFmpeg := "D:\Path\to\FFmpeg\bin" | |
## GetUrl() | |
https://gist.github.com/anonymous1184/7cce378c9dfdaf733cb3ca6df345b140/raw/GetUrl1.ahk | |
*/ | |
/** | |
* Downloads a video from YouTube. | |
* | |
* @param {string} Directory Path to save the downloaded file | |
* @param {integer} Mode 1 = Audio, 2 = Video | |
*/ | |
ytdl(Directory, Mode) { | |
if !(FileExist(ytdl.Path) ~= "D") { | |
throw Exception("Not a directory", -1, ytdl.Path) | |
} | |
if (!FileExist(ytdl.Path "\yt-dlp.exe")) { | |
throw Exception("yt-dlp.exe was not found.", -1, ytdl.Path) | |
} | |
if (!FileExist(ytdl.Path "\cache")) { | |
FileCreateDir % ytdl.Path "\cache" | |
} | |
cmd := "yt-dlp.exe" | |
Directory := RTrim(Directory, "\") | |
loop files, % Directory, D | |
Directory := A_LoopFileLongPath "\" | |
if !(Directory ~= "\\$") { | |
throw Exception("Invalid directory.", -1, Directory) | |
} | |
if !(Mode ~= "^[12]$") { | |
msg := "'Mode' must be either '1' or '2'" "`n" | |
. "`n" "1 = Audio" | |
. "`n" "2 = Video" | |
throw Exception(msg "`n", -1, Mode) | |
} | |
ytdl.Video.Container := Format("{:L}", ytdl.Video.Container) | |
if !(ytdl.Video.Container ~= "^(mkv|mp4|ogg|webm)$") { | |
ytdl.Video.Container := "mp4" | |
} | |
ytdl.Video.Quality := ytdl.Video.Quality | |
if !(ytdl.Video.Quality ~= "^(144|240|360|480|720|1080|1440|2160|4320)$") { | |
ytdl.Video.Quality := 1080 | |
} | |
if !(url := GetUrl()) { | |
MsgBox 0x40010, Error, Couldn't retrieve the URL. | |
return | |
} | |
if (!InStr(url, "youtube.com")) { | |
return | |
} | |
regex := "i)(?=.*v=(?<videoId>[^&]+))?(?=.*list=(?<listId>[^&]+))?" | |
RegExMatch(url, regex, _) | |
if (!_videoId && !_listId) { | |
MsgBox 0x40010, Error, No video or playlist found on the URL. | |
return | |
} | |
isPlaylist := false | |
if (_listId && !_videoId) { | |
isPlaylist := true | |
} else if (_listId && _videoId) { | |
MsgBox 0x40024, Playlist, Download the full playlist? | |
IfMsgBox Yes | |
isPlaylist := true | |
} | |
if (isPlaylist) { | |
Directory .= "%(playlist)s\%(playlist_index)s - " | |
} | |
Directory .= "%(title)s.%(ext)s" | |
; Options: | |
;; yt-dlp.exe --help | |
; General Options | |
cmd .= " --ignore-errors" | |
cmd .= " --ignore-config" | |
; Network Options | |
cmd .= " --force-ipv4" ; Avoid leaking for split tunnels | |
; Geo restriction | |
if (ytdl.GeoBypass = true) { | |
cmd .= " --geo-bypass" | |
} else if (ytdl.GeoBypass ~= "^\w{2}$") { | |
cmd .= " --geo-bypass-country """ ytdl.GeoBypass """" | |
} else if (ytdl.GeoBypass ~= "^[\d\.\/]+$") { | |
cmd .= " --geo-bypass-ip-block """ ytdl.GeoBypass """" | |
} | |
; Video Selection | |
cmd .= " --yes-playlist" | |
; Download Options | |
cmd .= " --hls-prefer-ffmpeg" | |
; Filesystem Options | |
cmd .= " --output """ Directory """" | |
cmd .= " --no-overwrites" | |
cmd .= " --continue" | |
cmd .= " --no-part" | |
cmd .= " --cookies """ ytdl.Path "\cache\cookies.txt""" | |
cmd .= " --cache-dir """ ytdl.Path "\cache""" | |
; Verbosity | |
cmd .= " --no-warnings" | |
cmd .= " --console-title" | |
cmd .= " --no-call-home" | |
; Workarounds | |
cmd .= " --no-check-certificate" | |
cmd .= " --prefer-insecure" | |
; User agent: | |
;; Firefox (2023/10) like when reloading page without cache | |
cmd .= " --user-agent ""Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0""" | |
cmd .= " --referer """ url """" | |
cmd .= " --add-header ""Accept-Encoding: gzip, deflate, br""" | |
cmd .= " --add-header ""Accept-Language: en-US,en;q=0.5""" | |
cmd .= " --add-header ""Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8""" | |
cmd .= " --add-header ""Cache-Control: no-cache""" | |
cmd .= " --add-header ""Connection: keep-alive""" | |
cmd .= " --add-header ""DNT: 1""" | |
cmd .= " --add-header ""Pragma: no-cache""" | |
cmd .= " --add-header ""SEC-FETCH-DEST: document""" | |
cmd .= " --add-header ""SEC-FETCH-MODE: navigate""" | |
cmd .= " --add-header ""SEC-FETCH-SITE: same-origin""" | |
cmd .= " --add-header ""SEC-FETCH-USER: ?1""" | |
cmd .= " --add-header ""TE: trailers""" | |
cmd .= " --add-header ""UPGRADE-INSECURE-REQUESTS: 1""" | |
; Sleep Interval | |
cmd .= " --sleep-interval """ Format("{:d}", ytdl.SleepInterval) """" | |
; Video Format Options | |
cmd .= " --youtube-skip-dash-manifest" | |
cmd .= " --merge-output-format """ ytdl.Video.Container """" | |
; Subtitle Options | |
; -none- | |
; Authentication Options | |
; -none- | |
; Adobe Pass Options | |
; -none- | |
; Post-processing Options | |
;; Format | |
if (Mode = 1) { | |
cmd .= " --format " | |
ext := Format("{:L}", ytdl.Audio.Format) | |
if (ext ~= "^(m4a|opus)$") { | |
cmd .= """bestaudio[ext=" ext "]""" | |
} else { | |
cmd .= " --extract-audio" | |
cmd .= " --audio-format """ ext """" | |
cmd .= " --audio-quality 0" | |
} | |
} else { | |
cmd .= " --format ""bestvideo[height<=" ytdl.Video.Quality "]+bestaudio""" | |
} | |
;; Thumbnails | |
if (Mode = 1 && ytdl.Audio.Thumbnail) | |
|| (Mode = 2 && ytdl.Video.Thumbnail) { | |
cmd .= " --embed-thumbnail" | |
} | |
;; Metadata | |
if (ytdl.Metadata) { | |
cmd .= " --add-metadata" | |
} | |
;; FFmpeg | |
if (!FileExist(ytdl.Path "\ffmpeg.exe")) { | |
ffmpegPath := "" | |
if (FileExist(ytdl.FFmpeg "\ffmpeg.exe")) { | |
loop files, % ytdl.Path, D | |
ffmpegPath := A_LoopFileLongPath | |
} | |
if (FileExist(ytdl.Path "\" ytdl.FFmpeg "\ffmpeg.exe")) { | |
loop files, % ytdl.Path "\" ytdl.FFmpeg, D | |
ffmpegPath := A_LoopFileLongPath | |
} | |
if (ffmpegPath) { | |
cmd .= " --ffmpeg-location """ ffmpegPath """" | |
} | |
} | |
; Execute | |
cmd .= " """ (isPlaylist ? _listId : _videoId) """" | |
try { | |
Run % cmd, % ytdl.Path | |
} catch { | |
MsgBox 0x40010, Error, There was an error running yt-dlp. | |
} | |
} | |
class ytdl { | |
static Path := "" ; Path to the binary | |
; FFmpeg directory | |
, FFmpeg := "..\FFmpeg" | |
; Uncensor | |
, GeoBypass := true | |
; Embed metadata? | |
, Metadata := true | |
; Time between downloads | |
, SleepInterval := 0 | |
; Audio options | |
, Audio := {} | |
; 'm4a'/'opus' natively | |
, Audio.Format := "m4a" | |
; Others need recoding (like mp3) | |
; Thumbnail? | |
, Audio.Thumbnail := false | |
; Video options | |
, Video := {} | |
; mkv | |
; mp4 | |
; ogg | |
; webm | |
, Video.Container := "mp4" | |
; 144p = 144 | |
; 240p = 240 | |
; 360p = 360 | |
; 480p = 480 | |
; HD = 720 | |
; FHD = 1080 | |
; QHD = 1440 | |
; 4k = 2160 | |
; 8k = 4320 | |
, Video.Quality := 1080 | |
; Thumbnail? | |
, Video.Thumbnail := true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey there.
I have not yet tested this - I'm not at home rn, but finally got around to taking some time for it. Last couple weeks were... shit, so this got stashed very thoroughly. So this comment is based fully on a brief read-through of the code above. So excuse my semi-ignorant question now:
(How) can I get a channel's name before downloading? The reason is that I use a system of
D:\YTD\%channelName%\%videotitle%.%filetype%
, because otherwhise holy hell would this get crammed.From what I can tell, the example-script is almost all I need - a few changes to iterate over a file of URLs, and an optional way to shutdown PC at script ending, but aside from that I think I can almost use this verbatim.