aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bard-elisp/bard-media.el36
-rw-r--r--bard-elisp/bard-web.el23
-rw-r--r--bard-emacs-modules/bard-emacs-media.el3
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