Generate YouTube Download commands for yt-dlp terminal

Enhance downloading capabilities on YouTube with playlist and channel support.

  1. // ==UserScript==
  2. // @name Generate YouTube Download commands for yt-dlp terminal
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Enhance downloading capabilities on YouTube with playlist and channel support.
  6. // @author ChatGPT
  7. // @match *://*.youtube.com/*
  8. // @grant GM_setClipboard
  9. // @grant GM_registerMenuCommand
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. let folderLocation = '.'; // Default folder location, current directory. Change it if needed.
  17. let disableViaYtDlp = false; // Set to true to remove " (via yt-dlp)" from filenames.
  18. let setToTrueToMoveChannelNameToEnd = false; // Set to true to move channel name to the end of the filename.
  19.  
  20. function isSingleOrPlaylistVideo() {
  21. // Checks if the URL indicates a single video or a video within a playlist
  22. return window.location.href.includes("/watch?v=") || window.location.href.includes("/v/");
  23. }
  24.  
  25. function isPlaylist() {
  26. // Checks if the URL includes a playlist identifier
  27. return window.location.href.includes("&list=");
  28. }
  29.  
  30. function isFullChannel() {
  31. // Checks if the URL is likely pointing to a full channel
  32. return window.location.href.includes("/channel/") || window.location.href.includes("/@");
  33. }
  34.  
  35. const ytDlpCommand = (mode, quality = '') => {
  36. const url = window.location.href;
  37. let command = "yt-dlp ";
  38. let isSPV = isSingleOrPlaylistVideo();
  39. let isPL = isPlaylist();
  40. let isFullCH = isFullChannel();
  41.  
  42. let outputFolder = folderLocation;
  43. if (isPL) {
  44. outputFolder += '/%(playlist)s';
  45. } else if (isFullCH) {
  46. outputFolder += '/%(uploader)s';
  47. }
  48.  
  49. // Define output template
  50. let outputTemplate = `${outputFolder}/%(title)s (via yt-dlp).%(ext)s`;
  51. if (!isPL && !isFullCH) {
  52. outputTemplate = `${folderLocation}/%(uploader)s - %(title)s (via yt-dlp).%(ext)s`; // Single or non-playlist video
  53. }
  54.  
  55. if (isPL || isFullCH) {
  56. command += isPL ? "--yes-playlist " : "";
  57. command += isFullCH ? "--download-archive channel_archive.txt " : ""; // Using an archive file to avoid re-downloads
  58. }
  59.  
  60. switch (mode) {
  61. case 'audio':
  62. command += `--extract-audio --audio-format m4a --audio-quality 0 -o "${outputTemplate}" -f "bestaudio[ext=m4a]/bestaudio/bestvideo+bestaudio" "${url}"`;
  63. break;
  64. case 'video':
  65. let videoQuality = 'bestvideo+bestaudio';
  66. if (quality) {
  67. videoQuality = `bestvideo[height<=${quality}]+bestaudio/best`;
  68. }
  69. command += `-f "${videoQuality}" --merge-output-format mkv -o "${outputTemplate}" "${url}"`;
  70. break;
  71. case 'comments':
  72. case 'chat':
  73. let fileType = (mode === 'comments') ? "comments and description" : "live chat";
  74. command += `--write-${mode} -o "${outputTemplate}" "${url}"`;
  75. break;
  76. }
  77.  
  78. // Remove channel-specific parts if not a full channel download
  79. if (!isFullCH) {
  80. command = command.replace(/--download-archive channel_archive\.txt /g, "");
  81. }
  82.  
  83. if( disableViaYtDlp === true){
  84. command = command.replace(" (via yt-dlp)","")
  85. }
  86.  
  87. if( setToTrueToMoveChannelNameToEnd === true){
  88. command = command.replace("%(uploader)s - ","")
  89. command = command.replace(".%(ext)s"," - %(uploader)s.%(ext)s")
  90. }
  91.  
  92. GM_setClipboard(command);
  93. alert("Command copied to clipboard:\n" + command);
  94. };
  95.  
  96. // Registering menu commands
  97. GM_registerMenuCommand("Download Audio (m4a)", () => ytDlpCommand('audio'), 'a');
  98. GM_registerMenuCommand("Download Comments", () => ytDlpCommand('comments'), 'c');
  99. GM_registerMenuCommand("Download Chat", () => ytDlpCommand('chat'), 'ch');
  100. GM_registerMenuCommand("Download Video (Best)", () => ytDlpCommand('video'), 'v');
  101. GM_registerMenuCommand("Download Video (4K)", () => ytDlpCommand('video', '2160'), '4');
  102. GM_registerMenuCommand("Download Video (1080p)", () => ytDlpCommand('video', '1080'), '1');
  103. GM_registerMenuCommand("Download Video (720p)", () => ytDlpCommand('video', '720'), '7');
  104. GM_registerMenuCommand("Download Video (480p)", () => ytDlpCommand('video', '480'), '4');
  105. })();
  106.