aboutsummaryrefslogtreecommitdiff
path: root/emacs/.emacs.d/lisp/my/my-ytdl.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/.emacs.d/lisp/my/my-ytdl.el')
-rw-r--r--emacs/.emacs.d/lisp/my/my-ytdl.el61
1 files changed, 61 insertions, 0 deletions
diff --git a/emacs/.emacs.d/lisp/my/my-ytdl.el b/emacs/.emacs.d/lisp/my/my-ytdl.el
index 9118493..b3b1cf7 100644
--- a/emacs/.emacs.d/lisp/my/my-ytdl.el
+++ b/emacs/.emacs.d/lisp/my/my-ytdl.el
@@ -76,6 +76,67 @@
(if (eq type 'video) my-ytdl-video-args my-ytdl-audio-args)
(split-string urls)))))
+(defun my-ytdl-video-info (url)
+ "Given a video URL, return an alist of its properties."
+ (with-temp-buffer
+ (call-process my-ytdl-program nil t nil "--no-warnings" "-j" url)
+ (let ((start (point)))
+ (call-process-region
+ nil nil "jq" nil t nil
+ "pick(.webpage_url, .fulltitle, .channel_url, .channel, .channel_follower_count, .thumbnail, .duration_string, .view_count, .upload_date, .like_count, .is_live, .was_live, .categories, .tags, .chapters, .availability, .uploader, .description)")
+ (goto-char start)
+ (json-read)))
+ )
+
+(defun my-ytdl-video-url-p (url)
+ (let ((urlobj (url-generic-parse-url url)))
+ (or (and (string-match-p
+ "^\\(www\\.\\)?\\(youtube\\.com\\|yewtu\\.be\\)"
+ (url-host urlobj))
+ (string-match-p "^/watch\\?v=.*" (url-filename urlobj)))
+ (equal "youtu.be" (url-host urlobj)))))
+
+(require 'hmm)
+(defvar my-ytdl-player 'hmm-external-mpv "Function to play ytdl urls.")
+
+(defun my-ytdl-video-format-seconds (secs)
+ (setq secs (floor secs))
+ (if (>= secs 3600)
+ (format "%d:%02d:%02d"
+ (/ secs 3600) (/ (% secs 3600) 60) (% secs 60))
+ (format "%d:%02d"
+ (/ secs 60) (% secs 60))))
+
+(defun my-ytdl-video-format-chapters (chapters)
+ (mapconcat
+ (lambda (chapter)
+ (let-alist chapter
+ (format "%s: %s-%s" .title (my-ytdl-video-format-seconds .start_time)
+ (my-ytdl-video-format-seconds .end_time))))
+ chapters
+ "; "))
+
+(defun my-ytdl-video-render-info (info url)
+ (setf (alist-get 'webpage_url info)
+ (concat (alist-get 'webpage_url info)
+ " -- " (buttonize "play" (lambda (_)
+ (funcall my-ytdl-player url)))
+ " " (buttonize "context"
+ (lambda (_)
+ (funcall my-url-context-function url))))
+ (alist-get 'chapters info)
+ (my-ytdl-video-format-chapters (alist-get 'chapters info)))
+ (infobox-render
+ (infobox-translate info (infobox-default-specs info))
+ `(my-ytdl-video-infobox ,url)
+ (called-interactively-p 'interactive)))
+
+(defun my-ytdl-video-infobox (url)
+ (interactive "sytdl video url: ")
+ ;; Remove any extra queries from the URL
+ (setq url (replace-regexp-in-string "&.*" "" url))
+ (my-ytdl-video-render-info (my-ytdl-video-info url) url))
+
;;; fixme: autoload
(defun my-ytdl-video (urls)
"Download videos with ytdl."