Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
####### # # E-scripts on YouTube, youtube-dl, etc. # # Note 1: use the eev command (defined in eev.el) and the # ee alias (in my .zshrc) to execute parts of this file. # Executing this file as a whole makes no sense. # An introduction to eev can be found here: # # (find-eev-quick-intro) # http://angg.twu.net/eev-intros/find-eev-quick-intro.html # # Note 2: be VERY careful and make sure you understand what # you're doing. # # Note 3: If you use a shell other than zsh things like |& # and the for loops may not work. # # Note 4: I always run as root. # # Note 5: some parts are too old and don't work anymore. Some # never worked. # # Note 6: the definitions for the find-xxxfile commands are on my # .emacs. # # Note 7: if you see a strange command check my .zshrc -- it may # be defined there as a function or an alias. # # Note 8: the sections without dates are always older than the # sections with dates. # # This file is at <http://angg.twu.net/e/youtube.e> # or at <http://angg.twu.net/e/youtube.e.html>. # See also <http://angg.twu.net/emacs.html>, # <http://angg.twu.net/.emacs[.html]>, # <http://angg.twu.net/.zshrc[.html]>, # <http://angg.twu.net/escripts.html>, # and <http://angg.twu.net/>. # ####### # «.standard-installation» (to "standard-installation") # «.debian» (to "debian") # «.restrict-filenames» (to "restrict-filenames") # «.youtube-dl-git» (to "youtube-dl-git") # «.irc-channel» (to "irc-channel") # «.update» (to "update") # «.youtube-dl-U» (to "youtube-dl-U") # «.upload-date» (to "upload-date") # «.splitting-file-names» (to "splitting-file-names") # «.thumbnails» (to "thumbnails") # «.video-formats» (to "video-formats") # «.title-is-deprecated» (to "title-is-deprecated") # «.youtube-title» (to "youtube-title") # «.username-and-password» (to "username-and-password") # «.subtitles» (to "subtitles") # «.auto-generated-subtitles» (to "auto-generated-subtitles") # «.bug-report» (to "bug-report") # «.extract-audio» (to "extract-audio") # «.youtube-dl-avconv-warning» (to "youtube-dl-avconv-warning") # «.vimeo» (to "vimeo") # «.write-auto-sub» (to "write-auto-sub") # «.lbry» (to "lbry") # «.time-syntax» (to "time-syntax") # «.ytdl» (to "ytdl") # «.ytel» (to "ytel") # «.youtube-sub-extractor.el» (to "youtube-sub-extractor.el") # «.automatic-captioning» (to "automatic-captioning") # «.slk500-culturevein» (to "slk500-culturevein") # «.ytdious» (to "ytdious") # «.editing-captions» (to "editing-captions") # «.peertube» (to "peertube") # «.wafficus» (to "wafficus") # «.kolektiva» (to "kolektiva") # «.yewtube» (to "yewtube") # «.invidious-git» (to "invidious-git") # «.invidious-tampermonkey» (to "invidious-tampermonkey") # «.odysee» (to "odysee") # «.vagner-aliases» (to "vagner-aliases") # «.yt-dlp» (to "yt-dlp") # «.channel-id» (to "channel-id") # «.output-template» (to "output-template") # «.toobnix» (to "toobnix") # «.sacha-srv-hint» (to "sacha-srv-hint") # «.hypervideo» (to "hypervideo") # «.transcript-downloader» (to "transcript-downloader") # «.youtube_transcript_api» (to "youtube_transcript_api") # «.chapters» (to "chapters") # «.yeetube» (to "yeetube") # «.yt-dlp-to-stdout» (to "yt-dlp-to-stdout") # «.subtitles-only» (to "subtitles-only") # «.info» (to "info") # (find-esgrep "grep -nH -e youtube-dl *.e") https://youtube.com/@eduardoochs https://youtube.com/c/eduardoochs https://youtube.com/user/eduardoochs https://support.google.com/youtube/answer/11585688 handles ##### # # Standard installation of youtube-dl (from upstream) # 2018nov11 # ##### # «standard-installation» (to ".standard-installation") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) apti youtube-dl aptrm youtube-dl # http://youtube-dl.org/ # http://rg3.github.io/youtube-dl/download.html sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl sudo chmod a+rx /usr/local/bin/youtube-dl # Update: sudo youtube-dl -U ##### # # Debian package # 2013aug18 # ##### # «debian» (to ".debian") # (find-status "youtube-dl") # (find-vldifile "youtube-dl.list") # (find-udfile "youtube-dl/") # (find-fline "/usr/share/pyshared/youtube_dl/extractor/") # (find-fline "/usr/share/pyshared/youtube_dl/extractor/youtube.py") ##### # # -restrict-filenames # 2013aug18 # ##### # «restrict-filenames» (to ".restrict-filenames") (code-c-d "ydl" "/usr/share/pyshared/youtube_dl/") (code-c-d "ydle" "/usr/share/pyshared/youtube_dl/extractor/") ;; (find-ydlfile "") ;; (find-ydlefile "") # (find-ydlgrep "grep -nH -e restrict *") # (find-ydlfile "__init__.py" "'--restrict-filenames'") # (find-ydlgrep "grep -nrH -e restrictfilenames *") # (find-ydlgrep "grep -nrH -e restricted *") # (find-ydlgrep "grep -nrH -e sanitize *") # (find-ydlfile "utils.py" "def sanitize_filename") ##### # # youtube-dl from git # 2013aug18 # ##### # «youtube-dl-git» (to ".youtube-dl-git") # (find-angg ".emacs" "youtube-dl") # http://rg3.github.io/youtube-dl/ # https://github.com/rg3/youtube-dl # https://github.com/rg3/youtube-dl.git # https://yt-dl.org/ # http://youtube-dl.org/ # http://rg3.github.io/youtube-dl/download.html # (find-git-links "https://github.com/rg3/youtube-dl.git" "youtubedl") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # rm -Rfv ~/usrc/youtube-dl/ cd ~/usrc/ git clone https://github.com/rg3/youtube-dl.git cd ~/usrc/youtube-dl/ # (code-c-d "youtubedl" "~/usrc/youtube-dl/") # (code-c-d "youtubedly" "~/usrc/youtube-dl/youtube_dl/") # (code-c-d "youtubedlye" "~/usrc/youtube-dl/youtube_dl/extractor/") # (find-youtubedlfile "") # (find-youtubedlsh "find * | sort") # (find-youtubedlfile "") # (find-youtubedlyfile "") # (find-youtubedlyefile "") # (find-youtubedlyefile "instagram.py") # (find-sh "youtube-dl") # (find-sh "youtube-dl -h") # (find-freenode-links "#youtube-dl") # From now on, get the binaries from # http://rg3.github.io/youtube-dl/download.html, not from the git # repository. # (find-youtubedlgrep "grep --color -nrH -e update *") # (find-youtubedlyfile "options.py" "'-U', '--update'") ##### # # IRC channel # 2013aug18 # ##### # «irc-channel» (to ".irc-channel") # (find-freenode "#youtube-dl") # (find-freenode-3a "#youtube-dl") # (find-fline "~/LOGS/2013aug18.youtube-dl") ##### # # update # 2013oct11 # ##### # «update» (to ".update") # «youtube-dl-U» (to ".youtube-dl-U") # (find-youtubedlgrep "grep -nirH -e update *") # (find-youtubedlfile "README.md" "-U, --update") # (find-youtubedlyfile "__init__.py" "'--update'") # (find-youtubedlyfile "update.py") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) youtube-dl -U # (find-sh "locate youtube-dl") # (find-fline "/usr/bin/youtube-dl") # (find-fline "/usr/local/bin/youtube-dl") ##### # # upload date # 2014apr21 # ##### # «upload-date» (to ".upload-date") # (find-youtubedlfile "README.md" "upload_date") # (find-youtubedlfile "README.md" "-e, --get-title") # (find-youtubedlfile "README.md" "--get-format") # (find-youtubedlfile "README.md" "--get-filename") # (find-youtubedlfile "README.md" "-o, --output TEMPLATE" "%(upload_date)s") # (find-youtubedlfile "README.md" "The current default template is") # (find-anggfile "LUA/youtube-db.lua" "yt ()" "youtube-dl -e") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ youtube-dl --get-format "http://www.youtube.com/watch?v=g5quWjBJMwc" youtube-dl --get-title "http://www.youtube.com/watch?v=g5quWjBJMwc" youtube-dl --get-description "http://www.youtube.com/watch?v=g5quWjBJMwc" youtube-dl --get-filename "http://www.youtube.com/watch?v=g5quWjBJMwc" youtube-dl --get-filename -o "%(upload_date)s" "http://www.youtube.com/watch?v=g5quWjBJMwc" yt-dlp --get-description "http://www.youtube.com/watch?v=g5quWjBJMwc" ##### # # Splitting the file name of a video downloaded by youtube-dl # 2013aug18 # ##### # «splitting-file-names» (to ".splitting-file-names") # (find-eevgrep "grep -nH -e tubedl *.el") # (find-eevgrep "grep -nH -e termpl *.el") # (find-eev "eev-tlinks.el" "find-youtubedl-links") # (find-angg ".emacs.templates" "find-youtubedl-links") (setq re "\\(\\.[A-Za-z0-9]\\{2,5\\}\\)\\{0,2\\}$") (setq str "foo.bar.plic.ploc.mp4") (setq str "foo.bar.plich.plocaboo.mp4") (setq str "plocaboo") (and (string-match re str) (list (substring str 0 (match-beginning 0)) (match-string 0 str))) (substring "abcdefgh" 0 1) (substring "abcdefgh" 0 -2) (substring "abcdefgh" -4 0) (match-string 0 fname)) ##### # # thumbnails # 2013sep14 # ##### # «thumbnails» (to ".thumbnails") # (find-man "youtube-dl") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ ~/usrc/youtube-dl/youtube-dl --write-thumbnail 'http://www.youtube.com/watch?v=Rx-L8hxrJlg' cd /tmp/ # Bad char: # youtube-dl --write-thumbnail 'http://www.youtube.com/watch?v=1_7HV_Vq2CE' ##### # # video formats # 2013sep14 # ##### # «video-formats» (to ".video-formats") # (find-es "android" "video-formats") Available formats: 35 : flv [480x854] 44 : webm [480x854] 34 : flv [360x640] 18 : mp4 [360x640] 43 : webm [360x640] 5 : flv [240x400] 17 : mp4 [144x176] # 2023dec24: # (find-sh "youtube-dl --help") # (find-sh "youtube-dl --help" "-f, --format FORMAT") # (find-sh "youtube-dl --help" "-S, --format-sort SORTORDER") * (eepitch-shell2) * (eepitch-kill) * (eepitch-shell2) youtube-dl -F 'http://www.youtube.com/watch?v=r2o11yHAa2U' youtube-dl -t -F 'http://www.youtube.com/watch?v=r2o11yHAa2U' youtube-dl -t -F --no-simulate 'http://www.youtube.com/watch?v=r2o11yHAa2U' ##### # # --title is deprecated # 2021oct17 # ##### # «title-is-deprecated» (to ".title-is-deprecated") # WARNING: --title is deprecated. Use -o "%(title)s-%(id)s.%(ext)s" instead. ##### # # youtube-title # 2013nov24 # ##### # «youtube-title» (to ".youtube-title") # (find-angg ".emacs" "youtube-title") # (find-es "charsets" "recode") # (find-sh "recode -l" "HTML") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) youtube-dl -e 'http://www.youtube.com/watch?v=TqoUp0_4aMY' youtube-dl -e 'http://www.youtube.com/watch?v=TqoUp0_4aMY' | recode h..l1 ##### # # user and password # 2014apr23 # ##### # «username-and-password» (to ".username-and-password") # (find-sh "youtube-dl" "-u, --username") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ youtube-dl -u [email protected] -p sikrit \ 'https://www.facebook.com/photo.php?v=658872984184130' ##### # # subtitles # 2014jun05 # ##### # «subtitles» (to ".subtitles") # (find-sh "youtube-dl -h" "Subtitle Options:") ##### # # auto-generated-subtitles # 2019nov13 # ##### # «auto-generated-subtitles» (to ".auto-generated-subtitles") # https://www.quora.com/How-do-I-download-auto-generated-subtitles-in-YouTube # https://unix.stackexchange.com/questions/450214/youtube-dl-download-autotranslate-subs # (find-man "1 youtube-dl") # (find-man "1 youtube-dl" "--write-auto-sub") # http://www.youtube.com/watch?v=hOAqBc42Gg8 On why most of the best features in eev look like 5-minute hacks (@ EmacsConf 2020) * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ laf *hOAqBc42Gg8* rv -fv *hOAqBc42Gg8* youtube-dl \ -f worst --list-subs \ "http://www.youtube.com/watch?v=hOAqBc42Gg8" youtube-dl \ -f worst --write-auto-sub \ "http://www.youtube.com/watch?v=hOAqBc42Gg8" youtube-dl --write-sub --skip-download --sub-lang=en \ "http://www.youtube.com/watch?v=hOAqBc42Gg8" ##### # # The "--write-auto-sub" option # 2017dez27 # ##### # «write-auto-sub» (to ".write-auto-sub") # (find-man "1 youtube-dl") # (find-man "1 youtube-dl" "--write-auto-sub") # (find-fline "/tmp/") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ youtube-dl \ -f worst --list-subs \ "https://www.youtube.com/watch?v=VLI09O8bMkU" youtube-dl \ -f worst --write-auto-sub \ "https://www.youtube.com/watch?v=VLI09O8bMkU" cd /tmp/ cp David_Jay_-_Asexuality-VLI09O8bMkU.en.vtt o.vtt * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) -- (find-lua51manual "#pdf-string.gmatch") -- (find-fline "/tmp/o.vtt") bigstr = ee_readfile "/tmp/o.vtt" pat = "(%d%d:[^\n]*)\n([^\n]+)\n\n" for a,b in string.gmatch(bigstr, pat) do -- print(b) print((b:gsub("<.->", ""))) end # http://www.youtube.com/watch?v=VLI09O8bMkU # (find-fline "/tmp/o.vtt") # (find-davidjayvideo "6:38") # http://www.youtube.com/watch?v=VLI09O8bMkU # (find-fline "/tmp/o.vtt") # (find-fline "/tmp/o.vtt" "5:52") # (find-fline "/tmp/o.vtt" "15:03" "close") ##### # # Bug report: non-ascii chars in -e # 2014aug06 # ##### # «bug-report» (to ".bug-report") # https://github.com/rg3/youtube-dl/issues # https://github.com/rg3/youtube-dl/issues/3460 # Non-ascii chars in "-e", and a project that uses youtube-dl #3460 ##### # # extract-audio # 2015feb15 # ##### # «extract-audio» (to ".extract-audio") # http://www.gluglug.org.uk/tutorials/accessing-youtube/#comment-101 # (find-sh "youtube-dl") # (find-sh "youtube-dl -h") # (find-sh "youtube-dl -h" "-x, --extract-audio") # (find-sh "youtube-dl -h" "--audio-format FORMAT") # (find-sh "youtube-dl -h" "--restrict-filenames") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ youtube-dl -x --audio-format mp3 "http://www.youtube.com/watch?v=YVXftEvBipI" youtube-dl -x --audio-format mp3 --restrict-filenames \ "http://www.youtube.com/watch?v=DbyzmiXnB7o" # 2015feb14: # http://www.gluglug.org.uk/tutorials/accessing-youtube/#comment-304 ##### # # WARNING: Your copy of avconv is outdated and unable to properly mux... # 2016jan05 # ##### # «youtube-dl-avconv-warning» (to ".youtube-dl-avconv-warning") # WARNING: Your copy of avconv is outdated and unable to properly mux # separate video and audio files, youtube-dl will download single file # media. Update avconv to version 10-0 or newer to fix this. # https://github.com/rg3/youtube-dl/issues/4451 # http://askubuntu.com/questions/563245/avconv-warning-while-downloading-youtube-video https://askubuntu.com/questions/563245/avconv-warning-while-downloading-youtube-video ##### # # vimeo # 2017dez06 # ##### # «vimeo» (to ".vimeo") # (find-man "1 youtube-dl" "-f, --format FORMAT") # (find-man "1 youtube-dl" "-F, --list-formats") # (find-man "1 youtube-dl" "FORMAT SELECTION") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) cd /tmp/ youtube-dl -F https://vimeo.com/195735897 youtube-dl -f worst https://vimeo.com/195735897 format code extension resolution note dash-akfire_interconnect_quic_sep-audio-656380193 m4a audio only DASH audio 128k , mp4a.40.2 (48000Hz) dash-fastly_skyfire_sep-audio-656380193 m4a audio only DASH audio 128k , mp4a.40.2 (48000Hz) dash-akfire_interconnect_quic_sep-audio-656380234 m4a audio only DASH audio 256k , mp4a.40.2 (48000Hz) dash-fastly_skyfire_sep-audio-656380234 m4a audio only DASH audio 256k , mp4a.40.2 (48000Hz) dash-akfire_interconnect_quic_sep-video-656380193 mp4 640x360 DASH video 685k , avc1.4D401E, 30fps, video only dash-fastly_skyfire_sep-video-656380193 mp4 640x360 DASH video 685k , avc1.4D401E, 30fps, video only dash-akfire_interconnect_quic_sep-video-656380234 mp4 960x540 DASH video 1926k , avc1.64001F, 30fps, video only dash-fastly_skyfire_sep-video-656380234 mp4 960x540 DASH video 1926k , avc1.64001F, 30fps, video only dash-akfire_interconnect_quic_sep-video-656380222 mp4 1280x720 DASH video 3112k , avc1.640020, 30fps, video only dash-fastly_skyfire_sep-video-656380222 mp4 1280x720 DASH video 3112k , avc1.640020, 30fps, video only dash-akfire_interconnect_quic_sep-video-656380223 mp4 1920x1080 DASH video 5298k , avc1.640028, 30fps, video only dash-fastly_skyfire_sep-video-656380223 mp4 1920x1080 DASH video 5298k , avc1.640028, 30fps, video only http-360p mp4 640x360 30fps hls-akfire_interconnect_quic-640 mp4 640x360 640k , avc1.4D401E, 30.0fps, mp4a.40.2 hls-fastly_skyfire-640 mp4 640x360 640k , avc1.4D401E, 30.0fps, mp4a.40.2 dash-akfire_interconnect_quic-video-656380193 mp4 640x360 DASH video 685k , avc1.4D401E, 30fps, mp4a.40.2 (48000Hz) dash-fastly_skyfire-video-656380193 mp4 640x360 DASH video 685k , avc1.4D401E, 30fps, mp4a.40.2 (48000Hz) http-540p mp4 960x540 30fps hls-akfire_interconnect_quic-1723 mp4 960x540 1723k , avc1.64001F, 30.0fps, mp4a.40.2 hls-fastly_skyfire-1723 mp4 960x540 1723k , avc1.64001F, 30.0fps, mp4a.40.2 dash-akfire_interconnect_quic-video-656380234 mp4 960x540 DASH video 1926k , avc1.64001F, 30fps, mp4a.40.2 (48000Hz) dash-fastly_skyfire-video-656380234 mp4 960x540 DASH video 1926k , avc1.64001F, 30fps, mp4a.40.2 (48000Hz) http-720p mp4 1280x720 30fps hls-akfire_interconnect_quic-2653 mp4 1280x720 2653k , avc1.640020, 30.0fps, mp4a.40.2 hls-fastly_skyfire-2653 mp4 1280x720 2653k , avc1.640020, 30.0fps, mp4a.40.2 dash-akfire_interconnect_quic-video-656380222 mp4 1280x720 DASH video 3112k , avc1.640020, 30fps, mp4a.40.2 (48000Hz) dash-fastly_skyfire-video-656380222 mp4 1280x720 DASH video 3112k , avc1.640020, 30fps, mp4a.40.2 (48000Hz) hls-akfire_interconnect_quic-4760 mp4 1920x1080 4760k , avc1.640028, 30.0fps, mp4a.40.2 hls-fastly_skyfire-4760 mp4 1920x1080 4760k , avc1.640028, 30.0fps, mp4a.40.2 dash-akfire_interconnect_quic-video-656380223 mp4 1920x1080 DASH video 5298k , avc1.640028, 30fps, mp4a.40.2 (48000Hz) dash-fastly_skyfire-video-656380223 mp4 1920x1080 DASH video 5298k , avc1.640028, 30fps, mp4a.40.2 (48000Hz) Original mp4 1920x1080 549.24MiB (best) # (find-efunction 'find-youtubedl-links) ##### # # lbry # 2019jun26 # ##### # «lbry» (to ".lbry") # https://www.youtube.com/watch?v=ZQuE0wfjzf0 ##### # # time-syntax - documentation for "&t=16s" # 2019nov03 # ##### # «time-syntax» (to ".time-syntax") # (find-angg "LUA/lua50init.lua" "youtube_make_url") # (find-angg "LUA/lua50init.lua" "youtube_make_url" "youtube_time =") # (find-eev "eev-audiovideo.el" "youtube-time") # http://www.youtube.com/watch?v=86yiRG8YJD0#t=0m00s # http://www.youtube.com/watch?v=86yiRG8YJD0#t=16m00s # http://www.youtube.com/watch?v=86yiRG8YJD0#t=0h00m00s # https://stackoverflow.com/questions/37402749/url-syntax-for-youtube-video-in-fullscreen-and-start-at-time-index # https://developers.google.com/youtube/player_parameters # https://developers.google.com/youtube/player_parameters#start * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) = youtube_make_url("0123456789a", "01:23") youtube_time = youtube_time_hhmmss = youtube_make_url("0123456789a", "1:02") = youtube_make_url("0123456789a", "1:02:03") * (eepitch-blogme3) * (eepitch-kill) * (eepitch-blogme3) = youtube_make_url("0123456789a", "01:23") ##### # # editing-captions # 2020oct18 # ##### # «editing-captions» (to ".editing-captions") # https://www.google.com/search?q=how+to+i+edit+the+captions+of+a+video+on+youtube # https://studio.youtube.com/video/86yiRG8YJD0/translations ##### # # peertube # 2021jan13 # ##### # «peertube» (to ".peertube") # https://vidcommons.org/videos/watch/4c9cece6-68dc-45be-a657-7118a5794123?start=1m23s https://video.hardlimit.com/signup https://solvespace.com/forum.pl?action=viewthread&parent=3756&tt=1625649760 Video tutorials now on PeerTube https://peertube.linuxrocks.online/video-channels/homehack/videos ##### # # Wafficus: newsboat, channels, etc # 2021jan13 # ##### # «wafficus» (to ".wafficus") # https://git.musimatic.net/dotfiles/tree/newsboat/.newsboat/urls # https://commentpicker.com/youtube-channel-id.php ##### # # kolektiva # 2021jun26 # ##### # «kolektiva» (to ".kolektiva") # https://kolektiva.media/videos/local https://kolektiva.media/videos/watch/5afe8f58-b07a-46e3-bd03-2ee4f5f2884a?start=1m2s ##### # # yewtube # 2021jul03 # ##### # «yewtube» (to ".yewtube") # https://yewtu.be/ # (find-TH "2021projeto-de-ensino") # (find-angg ".emacs.videos" "testbls") # (find-eevvideo-links "testbls" "2020-test-blocks" "fpsF_M55W4o") # (find-eevvideo-links "testbls" "2020-test-blocks" "fpsF_M55W4o" "1:23") # (find-efunction 'find-eevvideo-links) # (find-efunction 'ee-time-to-arg) # (find-efunction 'ee-time-to-youtube-time) # (find-fline "~/LOGS/2021sep22.invidious") # (find-fline "~/LOGS/2021sep22.invidious" "autoplay") (defun ee-find-yewtube-url (hash &optional time &rest rest) (format "http://www.yewtu.be/watch?v=%s%s" hash (ee-time-to-youtube-time time "&"))) (defun find-yewtube (hash &optional time &rest rest) (find-firefox (ee-find-yewtube-url hash time))) (find-yewtube "fpsF_M55W4o" "1:23") http://www.youtube.com/watch?v=fpsF_M55W4o#t=1m23s http://www.yewtu.be/watch?v=fpsF_M55W4o&t=1m23s http://www.yewtu.be/watch?v=fpsF_M55W4o&t=1m23s&autoplay=1 http://www.yewtu.be/watch?v=fpsF_M55W4o&autoplay=1 https://invidious-us.kavin.rocks/watch?v=fpsF_M55W4o&t=1m23s&autoplay=1 ##### # # invidious-git # 2021sep22 # ##### # «invidious-git» (to ".invidious-git") # https://github.com/iv-org/invidious # (find-git-links "https://github.com/iv-org/invidious" "invidious") # (code-c-d "invidious" "~/usrc/invidious/") # (find-invidiousfile "") # (find-invidiousgrep "grep --color=auto -nRH --null -e autoplay *") # (find-invidiousgrep "grep --color=auto -nRiH --null -e autoplay *") # (find-invidiousgrep "grep --color=auto -nRiH --null -e minute *") &autoplay=1 ##### # # invidious-tampermonkey # 2021sep22 # ##### # «invidious-tampermonkey» (to ".invidious-tampermonkey") # https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/ // ==UserScript== // @description Redirects Youtube URLs to Invidio.us // @name Invidious Redirect // @namespace Backend // @include http://www.youtube.com/* // @include https://www.youtube.com/* // @version 1.1 // @run-at document-start // @grant none // ==/UserScript== // invidio instances // https://instances.invidio.us/ //invidious.snopyta.org -> off //invidious.exonip.de //yewtu.be //invidious.tube //invidious.xyz //invidious.silkky.cloud //etc... var a = 0; setInterval(function () { if (a === 0 && window.location.href.indexOf('watch?') > -1 && window.location.href.indexOf('list=WL') < 0) { a = '//yewtu.be/watch?' + window.parent.location.href.split('?')[1]; window.location.replace(a); } }, 10); ##### # # odysee # 2021sep09 # ##### # «odysee» (to ".odysee") https://odysee.com/ https://odysee.com/@freegafo:8/only-here-the-lavender-fields-are-next:5 https://odysee.com/@LittleApostate:5/journalism-is-dead-and-vice-proved-it:7 https://odysee.com/@club_brick:f/lego-stop-motion-contest-champion!-the:f https://odysee.com/@EarthTitan:0/little-apple-of-death-fruits-you've:5 ##### # # vagner-aliases # 2021sep09 # ##### # «vagner-aliases» (to ".vagner-aliases") alias yt='youtube-dl --add-metadata -ic' alias ytCurl='youtube-dl --external-downloader-args curl -c --newline' alias ytLsub='youtube-dl --list-subs' alias ytPfree='youtube-dl -c --prefer-free-formats' alias ytTitle='youtube-dl -c --restrict-filename -o '\''%(title)s'\''' alias ytWget='youtube-dl --external-downloader-args wget -c --newline' alias yta='youtube-dl --add-metadata -xic' alias ytaufmt='youtube-dl -c --audio-format mp3' alias ytmp3='youtube-dl -cx' alias ytnp='youtube-dl -c --no-playlist' alias ytvF='youtube-dl -F' alias ytvidfmt='youtube-dl -c --recode-video ogg' ##### # # yt-dlp # 2021sep29 # ##### # «yt-dlp» (to ".yt-dlp") # (find-fline "~/bin/youtube-dl") # https://news.ycombinator.com/item?id=28289981 Youtube-dl is possibly dead (reddit.com) # https://old.reddit.com/r/DataHoarder/comments/p9riey/youtubedl_is_possibly_dead/ # https://github.com/yt-dlp/yt-dlp # (find-git-links "https://github.com/yt-dlp/yt-dlp" "ytdlp") # (code-c-d "ytdlp" "~/usrc/yt-dlp/") # (find-ytdlpfile "") # (find-ytdlpfile "README.md") # (find-ytdlpfile "README.md" "Use pip+git:") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) python3 -m pip install --upgrade git+https://github.com/yt-dlp/yt-dlp.git@release rehash which yt-dlp * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) yt-dlp yt-dlp --help yt-dlp --version which youtube-dl youtube-dl youtube-dl --version # (find-sh "yt-dlp --help") # (find-sh "yt-dlp --help" "--cache-dir DIR") ##### # # channel-id # 2024mar08 # ##### # «channel-id» (to ".channel-id") # https://www.reddit.com/r/youtubedl/comments/txuqnj/how_to_get_channel_ids_from_list_of_cuser_ids/ # https://michal.sapka.me/emacs/watching-youtube-with-emacs/ channel_id # https://github.com/yt-dlp/yt-dlp/issues/2117 How to get the whole list of video-ids from the specific channel id #2117 * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) yt-dlp --playlist-items 0 -O playlist:channel_url https://www.youtube.com/c/ChrisWereDigital yt-dlp --print channel_url --playlist-items 1 https://www.youtube.com/c/ChrisWereDigital yt-dlp --playlist-items 0 -O playlist:channel_url https://www.youtube.com/@Team_Recorder yt-dlp --playlist-items 0 -O playlist:channel_url https://www.youtube.com/@eduardoochs * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-fline "/tmp/yt/") rm -Rv /tmp/yt/ mkdir /tmp/yt/ cd /tmp/yt/ yt-dlp --skip-download --force-write-archive --download-archive test.txt https://www.youtube.com/@eduardoochs yt-dlp -U ##### # # output-template # 2024mar09 # ##### # «output-template» (to ".output-template") # https://github.com/yt-dlp/yt-dlp#output-template * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) yt-dlp --flat-playlist --print id <channel url> yt-dlp --flat-playlist --print id <channel url> URL="http://www.youtube.com/watch?v=qM0Luz78qGw" URL="https://www.youtube.com/@eduardoochs" URL="https://www.youtube.com/@Team_Recorder" FMT="%(id)s" FMT="%(title)s" FMT="%(upload_date>%Y-%m-%d)s http://www.youtube.com/watch?v=%(id)s %(title)s" FMT="%(upload_date)s http://www.youtube.com/watch?v=%(id)s %(title)s" FMT="http://www.youtube.com/watch?v=%(id)s %(title)s" yt-dlp --skip-download --flat-playlist --print "$FMT" $URL yt-dlp --skip-download --flat-playlist --print id $URL yt-dlp --skip-download --flat-playlist --print id <channel url> yt-dlp --flat-playlist --print id <channel url> FMT="%(channel)s %(channel_id)s %(channel_url)s %(channel_follower_count)s %(channel_is_verified)s" URL="http://www.youtube.com/watch?v=qM0Luz78qGw" yt-dlp --skip-download --flat-playlist --print "$FMT" $URL ##### # # toobnix # 2021nov28 # ##### # «toobnix» (to ".toobnix") https://emacsconf.org/2021/talks/test/ https://toobnix.org/w/qRKLj4VdBG8cFN1MEfcRho ##### # # sacha-srv-hint # 2022jan27 # ##### # «sacha-srv-hint» (to ".sacha-srv-hint") # https://mail.google.com/mail/u/0/#inbox/QgrcJHrjCFDVFRMhWpbXFgDjhJbNZdgGWVv * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) rm -Rv /tmp/srv/ mkdir /tmp/srv/ cd /tmp/srv/ youtube-dl --write-sub --write-auto-sub --no-warnings --sub-lang en \ --skip-download --sub-format srv1 -o temp-file \ "http://www.youtube.com/watch?v=WowDSciGs1A" # (find-fline "/tmp/srv/") # (find-fline "/tmp/srv/temp-file.en.srv1") # pict2e-lua: youtube-dl --write-sub --write-auto-sub --no-warnings --sub-lang en \ --skip-download --sub-format vtt -o temp-file \ "http://www.youtube.com/watch?v=hiHsUhGVLGM" youtube-dl --write-sub --write-auto-sub --no-warnings --sub-lang en \ --skip-download --sub-format srv1 -o temp-file \ "http://www.youtube.com/watch?v=hiHsUhGVLGM" # (find-pip3-links "pysubs2") # (find-pip3spfile "pysubs2/") # https://github.com/tkarabela/pysubs2 # (find-sh "pysubs2 --help") # (find-sh "pysubs2 --help" "--to srt") cd /tmp/srv/ pysubs2 --to srt *.vtt * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-fline "/tmp/edrx-pict2e/") rm -Rv /tmp/edrx-pict2e/ mkdir /tmp/edrx-pict2e/ cd /tmp/edrx-pict2e/ yt-dlp --write-sub --write-auto-sub --skip-download \ -o 2022-pict2e-lua \ "http://www.youtube.com/watch?v=hiHsUhGVLGM" wget http://angg.twu.net/eev-videos/2022-pict2e-lua.mp4 ls -lAF mpv /tmp/edrx-pict2e/2022-pict2e-lua.mp4 --no-warnings --sub-lang en \ --skip-download --sub-format srv1 -o temp-file \ ##### # # hypervideo # 2022mar24 # ##### # «hypervideo» (to ".hypervideo") # https://git.conocimientoslibres.ga/software/hypervideo.git # (find-git-links "https://git.conocimientoslibres.ga/software/hypervideo.git" "hypervideo") # (code-c-d "hypervideo" "~/usrc/hypervideo/") # (find-hypervideofile "") ##### # # transcript-downloader # 2022mar29 # ##### # «transcript-downloader» (to ".transcript-downloader") # (find-pip3-links "youtube-transcript-downloader") # https://github.com/t4skmanag3r/youtube_transcript_downloader # (find-pip3spfile "youtube_transcript_downloader/") # (find-pip3spfile "youtube_transcript_downloader/yt_transcript_downloader.py") # https://github.com/t4skmanag3r/youtube_transcript_downloader # https://ag91.github.io/blog/2022/03/27/an-elisp-snippet-to-dowload-youtube-videos-transcripts/ # https://ag91.github.io/blog/2022/03/28/something-i-missed-point-free-composition-in-elisp/ * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # pip3 install youtube_transcript_downloader (defun get-youtube-transcript (url) "Get YouTube transcript of URL." (if (s-contains-p "youtube-transcript-downloader" (shell-command-to-string "pip list")) (progn (with-temp-file "/tmp/yt-transcr-downloader.py" (insert (format " import youtube_transcript_downloader url = \"%s\" transcript = youtube_transcript_downloader.get_transcript(url) print(\"(\") for key, val in transcript.items(): print(f\"(:key \\\"{key}\\\" :text \\\"{val}\\\")\") print(\")\") " url))) (read (shell-command-to-string "python3 /tmp/yt-transcr-downloader.py"))) (error "Please install youtube_transcript_downloader via pip install youtube_transcript_downloader"))) You can use it like this (get-youtube-transcript "https://www.youtube.com/watch?v=vJ1STks8MUU"). (shell-command-to-string "python3 /tmp/yt-transcr-downloader.py") (shell-command-to-string "pip list") # (find-sh "pip3 list" "youtube-transcript-downloader") <bpalmer> https://developers.google.com/youtube/iframe_api_reference -- change the onPlayerReady function to include 'if (window.location.hash) { var timestamp = window.location.hash.substring(1); var secs = parseInt(timestamp); if (!isNaN(secs)) { player.seekTo(secs); } } ' or some such ##### # # YouTubeTranscriptApi - by Bruno Macedo # 2024sep08 # ##### # «youtube_transcript_api» (to ".youtube_transcript_api") # (find-eev "eev-tlinks.el" "find-yttranscript-links") # (find-telegachat "@macedobruno#237268") # (find-wget-elisp "https://0x0.st/XvdP.txt") # (find-pip3-links "youtube_transcript_api") # https://github.com/jdepoix/youtube-transcript-api # (find-git-links "https://github.com/jdepoix/youtube-transcript-api" "yttrapi") # (code-c-d "yttrapi" "~/usrc/youtube-transcript-api/") # (code-c-d "yttrapia" "~/usrc/youtube-transcript-api/youtube_transcript_api/") # (find-yttrapifile "") # (find-yttrapifile "README.md") # (find-yttrapiafile "_transcripts.py") # (find-yttrapiafile "_transcripts.py" "class TranscriptList(object):") # (find-yttranscript-links "acmetour" "dP1xVpMPn8M") # (find-yttranscript-links "eev2021" "qM0Luz78qGw") # (find-telegachat "@macedobruno#237747" "manually created transcripts") # (find-telegachatm "@macedobruno#237747" "manually created transcripts") trlist = YouTubeTranscriptApi.list_transcripts("dP1xVpMPn8M") tr = YouTubeTranscriptApi.get_transcript ("dP1xVpMPn8M") trlist.find_manually_created_transcript() trlist.find_manually_created_transcript(['de', 'en']) ##### # # How slk500's https://culturevein.com/ controls embedded videos # 2022sep04 # ##### # «slk500-culturevein» (to ".slk500-culturevein") # https://developers.google.com/youtube/iframe_api_reference # (find-fline "~/LOGS/2022sep04.slk500" "oKsxPW6i3pM") # (find-fline "/tmp/") # file:///tmp/play.html <!DOCTYPE html> <html> <body> <!-- 1. The <iframe> (and video player) will replace this <div> tag. --> <div id="player"></div> <script> // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '390', width: '640', videoId: 'M7lc1UVf-VE', playerVars: { 'playsinline': 1 }, events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { event.target.playVideo(); } // 5. The API calls this function when the player's state changes. // The function indicates that when playing a video (state=1), // the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } } function stopVideo() { player.stopVideo(); } </script> <a href="" onclick="alert('Hello'); return false;">foo</a> <a href="" onclick="player.seekTo(100); player.playVideo(); return false;">bar</a> </body> </html> ##### # # ytdious # 2022oct10 # ##### # «ytdious» (to ".ytdious") # (find-epackage-links 'ytdious "ytdious" t) # (find-epackages 'ytdious) # (find-epackage 'ytdious) # (code-c-d "ytdious" "~/.emacs.d/elpa/ytdious-20210228.2111/") # (find-ytdiousfile "") https://github.com/spiderbit/ytdious ##### # # ytdl # 2022oct10 # ##### # «ytdl» (to ".ytdl") # https://www.reddit.com/r/emacs/comments/hxbmda/ytdl_an_emacs_interface_for_youtubedl/ # (find-epackage-links 'ytdl "ytdl" t) # (find-epackages 'ytdl) # (find-epackage 'ytdl) # (code-c-d "ytdl" "~/.emacs.d/elpa/ytdl-20210506.914/") # (find-ytdlfile "") # https://gitlab.com/tuedachu/ytdl ##### # # ytel # 2022oct10 # ##### # «ytel» (to ".ytel") # (find-epackage-links 'ytel "ytel" t) # (find-epackages 'ytel) # (find-epackage 'ytel) # (code-c-d "ytel" "~/.emacs.d/elpa/ytel-20200725.1056/") # (find-ytelfile "") # https://github.com/grastello/ytel ##### # # youtube-sub-extractor.el # 2022dec05 # ##### # «youtube-sub-extractor.el» (to ".youtube-sub-extractor.el") # (find-es "emacs" "youtube-sub-extractor") # (find-epackage-links 'youtube-sub-extractor "youtubesubextractor" t) # (find-epackages 'youtube-sub-extractor) # (find-epackage 'youtube-sub-extractor) # (code-c-d "youtubesubextractor" "{d}") # (find-youtubesubextractorfile "") ##### # # automatic-captioning # 2023aug11 # ##### # «automatic-captioning» (to ".automatic-captioning") # https://support.google.com/youtube/answer/6373554?hl=en-GB Use automatic captioning # There's a long period of silence at the beginning of the video. # https://www.3playmedia.com/blog/long-take-manually-caption-videos/ To use YouTube’s automatic captioning function: Log into your YouTube account. Find the video you want captioned in your Video Editor, then select Edit > Subtitles & CC. When you select Add new subtitles or CC, a search bar will appear. Search for the English (Automatic). You’ll be taken to YouTube’s caption editor. Here you can edit each caption frame, while previewing them on the video. Once your captions are ready, just hit Publish. ##### # # chapters # 2024feb10 # ##### # «chapters» (to ".chapters") # https://support.google.com/youtube/answer/9884579?hl=en # https://teenahughesonline.com/new-youtube-chapter-thumbnails-what-are-they-and-where-do-i-find-them-2.html To add your own video chapters: Sign in to YouTube Studio. From the left menu, select Content. Click the video that you'd like to edit. In the Description, add a list of timestamps and titles. Make sure that the first timestamp you list starts with 00:00. Your video should have at least three timestamps listed in ascending order. The minimum length for video chapters is 10 seconds. Click SAVE. http://www.youtube.com/watch?v=6-0cERIVsFg How to Use YouTube Chapters - YouTube Video Sections http://www.youtube.com/watch?v=pvkTC2xIbeY How to Add Chapters to YouTube Videos. Chapters Explained! http://www.youtube.com/watch?v=dto1u84qf5M NEW YouTube Chapter Thumbnails - What are they and where do I find them? http://www.youtube.com/watch?v=ySqnRRNQyhk How to add multiple images for YouTube Chapter Thumbnails - Part 2 # (find-yttranscript-links "{c}" "6-0cERIVsFg") # (find-yttranscript-links "{c}" "pvkTC2xIbeY") https://www.reddit.com/r/PartneredYoutube/comments/ozjjox/are_chapter_thumbnails_customizable/ ##### # # yeetube # 2024mar07 # ##### # «yeetube» (to ".yeetube") # (find-angg ".emacs" "yeetube") # https://thanosapollo.org/post/yeetube/ # https://git.thanosapollo.org/yeetube # https://melpa.org/#/yeetube # https://michal.sapka.me/emacs/watching-youtube-with-emacs/ # (find-epackage-links 'yeetube "yeetube" t) # (code-c-d "yeetube" "~/.emacs.d/elpa/yeetube-20240307.358/") # (find-yeetubefile "") ##### # # yt-dlp-to-stdout # 2024mar26 # ##### # «yt-dlp-to-stdout» (to ".yt-dlp-to-stdout") yt-dlp LINK -o - | mpv - ##### # # Use yt-dlp to download only the subtitles for a video # 2024may10 # ##### # «subtitles-only» (to ".subtitles-only") # https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#subtitle-options # https://www.reddit.com/r/youtubedl/comments/wpq4y0/ytdlp_how_to_ensure_download_of_english_subtitles/ # https://github.com/yt-dlp/yt-dlp/issues/7496 How to download a subtitle file only from youtube without the timecode * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-fline "/tmp/yt/") rm -Rv /tmp/yt/ mkdir /tmp/yt/ cd /tmp/yt/ # http://www.youtube.com/watch?v=aVwxzDHniEw youtube-dl -t -F 'http://www.youtube.com/watch?v=aVwxzDHniEw' youtube-dl -t -f sb3 'http://www.youtube.com/watch?v=aVwxzDHniEw' youtube-dl -t -f sb3 --restrict-filenames --all-subs 'http://www.youtube.com/watch?v=aVwxzDHniEw' * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-fline "/tmp/yt/") rm -Rv /tmp/yt/ mkdir /tmp/yt/ cd /tmp/yt/ youtube-dl -t -F --restrict-filenames --all-subs 'http://www.youtube.com/watch?v=8jtiBlaDor4' youtube-dl -t -f sb2 --restrict-filenames --all-subs 'http://www.youtube.com/watch?v=8jtiBlaDor4' youtube-dl -t -f sb2 --restrict-filenames --write-auto-subs 'http://www.youtube.com/watch?v=8jtiBlaDor4' ##### # # info # 2024nov10 # ##### # «info» (to ".info") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) # (find-fline "/tmp/yt/") rm -Rv /tmp/yt/ mkdir /tmp/yt/ cd /tmp/yt/ yt-dlp --skip-download --write-info-json "http://www.youtube.com/watch?v=QVilpxowsUQ" mv -iv *.info.json video.info.json python3 -m json.tool video.info.json > video.info-2.json # (find-fline "/tmp/yt/video.info-2.json") # Not working yet: # https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#embedding-examples * (eepitch-python) * (eepitch-kill) * (eepitch-python) import json import yt_dlp import pprint URL = 'https://www.youtube.com/watch?v=BaW_jenozKc' ydl_opts = {} ydl = yt_dlp.YoutubeDL(ydl_opts) info = ydl.extract_info(URL, download=False) o = json.dumps(ydl.sanitize_info(info)) print(json.dumps(ydl.sanitize_info(info))) pprint(info) https://support.google.com/youtube/answer/7631406?hl=en Keyboard shortcuts for YouTube cd /tmp/ youtube-dl -v -v -v \ --write-info-json \ -e "http://www.youtube.com/watch?v=n72B3zCOLU0" \ |& tee /tmp/o # write_youtube_date_into("Pap4N7G2rPM", "/tmp/ydb/Pap4N7G2rPM.date") # write_youtube_title_into("Pap4N7G2rPM", "/tmp/ydb/Pap4N7G2rPM.title") # download_youtube_mp4("Pap4N7G2rPM", "/tmp/ydb/videos/") # (find-sh "youtube-dl -h") # (find-fline "~/LOGS/2014aug06.youtube-dl") https://github.com/ytdl-org/youtube-dl/issues/3460 https://mail.google.com/mail/ca/u/0/#inbox/FMfcgxwDrbvswpFDPgfBPfQbvDrqnVjt October Creator Monthly newsletter https://mspoweruser.com/microsofts-github-removes-open-source-youtube-video-download-code/ NewPipe (Front-end leve para o YouTube): https://f-droid.org/packages/org.schabi.newpipe https://lushka.al/posts/youtube-alternatives/ https://www.youtube.com/feed/history https://www.youtube.com/watch?v=xabq4e-fJaU&pp=sAQA https://www.youtube.com/watch?v=wNsIpF7g2lQ&pp=sAQA https://www.youtube.com/watch?v=7Q7c0yvsLRc&pp=sAQA https://www.youtube.com/watch?v=_AaOFCl2ihc&pp=sAQA https://www.youtube.com/watch?v=mWfq1daZH8c&pp=sAQA https://www.youtube.com/watch?v=eN4Lc0Arzww&pp=sAQA https://www.youtube.com/watch?v=60z_hpEAtD8&pp=sAQA There is the YouTube option, which I imagine no one would like (me neither). The only thing in its favor is that Invidious can be used to watch the videos. BTW, I watch YT videos through Invidious in Emacs, with the Ytel package and EMMS/MPV. https://news.ycombinator.com/item?id=34264487 Yark: Advanced and easy YouTube archiver now stable (github.com/owez) https://news.ycombinator.com/item?id=34653813 Reverse-Engineering YouTube: Revisited (tyrrrz.me) https://joinpeertube.org/news/isd-study A statement about the German ISD study on PeerTube https://news.ycombinator.com/item?id=37112615 Downloading a video should be “fair use” as recording a song from the radio (mastodon.social) https://github.com/mattwright324/youtube-metadata/wiki/YouTube-Oddities https://news.ycombinator.com/item?id=39368155 YouTube Oddities (github.com/mattwright324) https://web.archive.org/web/20220428003450/http://composition.al/blog/2021/07/14/how-to-create-an-srt-caption-file-for-a-video/ https://gitlab.com/tuedachu/ytdl An Emacs interface for youtube-dl https://github.com/grastello/ytel Youtube "front-end" for Emacs https://frontendmasters.com/blog/youtube-embeds-are-bananas-heavy-and-its-fixable/ # Local Variables: # modes: (fundamental-mode emacs-lisp-mode) # coding: utf-8-unix # End: