diff options
| author | BardofSprites <[email protected]> | 2025-04-22 18:03:56 -0400 |
|---|---|---|
| committer | BardofSprites <[email protected]> | 2025-04-22 18:05:37 -0400 |
| commit | 480dfe2c09070cf4c710e6806cb3a6cbdc93f7cf (patch) | |
| tree | 50d28c5456737b20f047dcc1c50ba76a4ab23d54 | |
| parent | f9a7af16c077b89a3db907746d8e1f946b064b02 (diff) | |
update YouTube/EMMS functions
New Features:
- Download currently playing video to prompted locations.
- Tacking on current elfeed entry to bard/watch-later-file
- Play YouTube video at point
| -rw-r--r-- | bard-elisp/bard-media.el | 36 | ||||
| -rw-r--r-- | bard-elisp/bard-web.el | 23 | ||||
| -rw-r--r-- | bard-emacs-modules/bard-emacs-media.el | 3 |
3 files changed, 58 insertions, 4 deletions
diff --git a/bard-elisp/bard-media.el b/bard-elisp/bard-media.el index 22d54c9..9efa88d 100644 --- a/bard-elisp/bard-media.el +++ b/bard-elisp/bard-media.el @@ -5,10 +5,14 @@ (require 'dired-x) (defun bard/play-youtube-video () - "Prompt for a YouTube URL and play it in mpv." + "Play the YouTube URL at point or prompt for one if none is found." (interactive) - (let ((url (read-string "Enter YouTube URL: "))) - (if (and url (string-match-p "https?://\\(www\\.\\)?youtube\\.com\\|youtu\\.be" url)) + (let* ((url-at-point (thing-at-point 'url t)) + (url (if (and url-at-point + (string-match-p "https?://\\(www\\.\\)?\\(youtube\\.com\\|youtu\\.be\\)" url-at-point)) + url-at-point + (read-string "Enter YouTube URL: ")))) + (if (and url (string-match-p "https?://\\(www\\.\\)?\\(youtube\\.com\\|youtu\\.be\\)" url)) (async-shell-command (format "mpv '%s'" url)) (message "The URL is not a valid YouTube link: %s" url)))) @@ -66,4 +70,30 @@ Asks the user whether to enable recursive mode." (erase-buffer))))) (pop-to-buffer "*nsxiv*"))))) +(defun bard/emms-download-current-video (destination) + "Download the currently playing EMMS video and move it to DESTINATION." + (interactive "DSelect destination directory: ") + (require 'emms) + (let* ((track (emms-playlist-current-selected-track)) + (url (emms-track-get track 'name)) + (default-directory (file-name-as-directory temporary-file-directory)) + (downloader (executable-find "yt-dlp")) + (output-template "%(title)s.%(ext)s")) + (unless downloader + (error "yt-dlp or youtube-dl is not installed or not in PATH")) + (unless (string-match-p "^https?://" url) + (error "Current track is not a valid video URL")) + + (let ((cmd (format "%s -f best -o \"%s\" \"%s\"" + downloader output-template url))) + (message "Downloading video from: %s" url) + (let ((exit-code (shell-command cmd))) + (if (not (eq exit-code 0)) + (error "Download failed, see *Messages* for details") + ;; Move the downloaded file + (let* ((downloaded-file (car (directory-files default-directory t ".*\\(mp4\\|mkv\\|webm\\)$" 'time))) + (target-path (expand-file-name (file-name-nondirectory downloaded-file) destination))) + (rename-file downloaded-file target-path t) + (message "Video saved to: %s" target-path))))))) + (provide 'bard-media.el) diff --git a/bard-elisp/bard-web.el b/bard-elisp/bard-web.el index 702fd52..8c9473b 100644 --- a/bard-elisp/bard-web.el +++ b/bard-elisp/bard-web.el @@ -1,4 +1,5 @@ (require 'emms) +(require 'elfeed-search) (defun bard/play-elfeed-video () "Play the URL of the entry at point in mpv if it's a YouTube video." @@ -31,4 +32,26 @@ (message "The URL is not a YouTube link: %s" url))) (message "No entry selected in Elfeed.")))) +(defun bard/add-video-watch-later () + "Add the current Elfeed YouTube entry URL to '~/Videos/watch-later.m3u' and mark it as read." + (interactive) + (let ((entry (elfeed-search-selected :single))) + (if entry + (let* ((url (elfeed-entry-link entry)) + (watch-later-file (expand-file-name "~/Videos/watch-later.m3u"))) + (if (and url (string-match-p "https?://\\(www\\.\\)?youtube\\.com\\|youtu\\.be" url)) + (progn + (with-temp-buffer + (insert (concat url "\n")) + (append-to-file (point-min) (point-max) watch-later-file)) + ;; Remove the 'unread tag from the entry directly + (setf (elfeed-entry-tags entry) + (remove 'unread (elfeed-entry-tags entry))) + ;; Force UI update + (when (derived-mode-p 'elfeed-search-mode) + (elfeed-search-update-entry entry)) + (message "Added video to watch later: %s" url)) + (message "The URL is not a YouTube link: %s" url))) + (message "No entry selected in Elfeed.")))) + (provide 'bard-web) diff --git a/bard-emacs-modules/bard-emacs-media.el b/bard-emacs-modules/bard-emacs-media.el index b84d2c9..d7da6a6 100644 --- a/bard-emacs-modules/bard-emacs-media.el +++ b/bard-emacs-modules/bard-emacs-media.el @@ -15,7 +15,8 @@ ("c" . bard/emms-recenter) ("P" . emms-playlist-mode-shift-track-up) ("N" . emms-playlist-mode-shift-track-down) - ("Z" . bard/save-emms-watch-later)) + ("Z" . bard/save-emms-watch-later) + ("Y" . bard/emms-download-current-video)) :bind (("<f8>" . emms) ("M-<f8>" . emms-browser)) :hook |
