[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

video downloader [CODE SNIPPET]

As a follow-up to my previous post regarding youtube support, I decided
to write something to allow downloading videos from within an emacs-w3m
background sub-process. I don't do much video downloading, but when I
do, my method is to use a command-line program called `youtube-dl'
[1][2]. The following code snippet uses that external program. There is
no need to actually navigate to a specific youtube video's page; rather,
from a search result page with links, position your cursor on one of the
links and run `M-x w3m-download-video-at-point'. The function notifies
the user on completion or error, and logs progress to a unique message
buffer for each download.

I've tested it for my limited use case. If anyone has feedback from
other sites, or other recommendations, let me know.

#+BEGIN_SRC emacs-lisp
(defcustom w3m-download-video-alist
  '(("\\.youtube\\." . "-f 18"))
  "*An alist of arguments to use for downloading from specific urls.

Each element should be of the form (URL . ARGS),
for example (\"www.youtube.com\" . \"-f 18\").

Refer to `man(1) youtube-dl' for information on available arguments."
  :group 'w3m
  :type '(repeat
	  (cons :format "%v" :indent 12
		(string :format "url base:            %v")
		(string :format "args for youtube-dl: %v"))))

(defun w3m-download-video (url)
  "Invoke `youtube-dl' in a sub-process to download a video."
  (if (not (w3m-url-valid url))
    (error "Invalid URL")
  (let* (proc
         (buf (generate-new-buffer "*w3m-download-video*"))
         (base (and (string-match "//\\([^/]+\\)/" url)
           (substring-no-properties url
             (match-beginning 1) (match-end 1))))
         (args (catch 'found-replacement
           (dolist (elem w3m-download-video-alist "--")
             (when (string-match (car elem) base)
               (throw 'found-replacement (cdr elem)))))))
    (with-current-buffer buf
      ; How can I customize this buffer so incoming 'C-m' will be
      ; dynamically converted to 'C-j' in order to appear correctly
      ; as new-lines?
      ; (set-buffer-file-coding-system 'utf-8-dos)
      ; (set-buffer-file-coding-system 'utf-8-mac)
      (insert (current-time-string)
        "\n  youtube-dl " args " " url "\n\n")
      (setq proc
        (start-process "w3m-download-video" buf "youtube-dl" args url)))
    (w3m-message "Requesting download.")
    (set-process-sentinel proc
      (lambda (proc event)
        (let ((buf (process-buffer proc)))
         (with-current-buffer buf (insert event))
		  ((string-match "^finished" event)
               "Download complete. Check buffer %s for details." buf))
		  ((string-match "^open" event) t)
          (t (message
               "Download error. Check buffer %s for details." buf)))))))))

(defun w3m-download-video-at-point ()
  "Invoke `youtube-dl' in a sub-process to download the video at point."
  (let ((url (w3m-anchor)))
   (if (not url)
     (user-error "No url found at point.")
    (w3m-download-video url))))

[1] https://rg3.github.com/youtube-dl/

[2] https://packages.debian.org/stretch/youtube-dl

CA45 09B5 5351 7C11 A9D1  7286 0036 9E45 1595 8BC0