blob: 1a8f558694864ef142b74d251953fa450100a2a4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
;;; wasp-youtube --- YouTube integration -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 's)
(require 'dash)
(require 'ht)
(require 'wasp-utils)
(require 'selector)
(defcustom w/youtube-mpv-process "wasp-mpv-search"
"Name of process running MPV player for YouTube videos."
:type '(string)
:group 'wasp)
(defcustom w/youtube-search-process "wasp-youtube-search"
"Name of process running YouTube search."
:type '(string)
:group 'wasp)
(defcustom w/youtube-search-buffer " *wasp-youtube-search*"
"Name of buffer used to store YouTube search results."
:type '(string)
:group 'wasp)
(defun w/youtube-search (query k)
"Search YouTube for QUERY and pass the resulting list of title-URL pairs to K."
(let ((buf (generate-new-buffer w/youtube-search-buffer)))
(make-process
:name w/youtube-search-process
:buffer buf
:command
(list
"yt-dlp" "--dump-json" (format "ytsearch20:%s" query)
"--skip-download" "--no-playlist" "--default-search" "ytsearch"
"--no-check-certificate" "--geo-bypass" "--flat-playlist"
"--quiet" "--ignore-errors")
:sentinel
(lambda (_ _)
(with-current-buffer buf
(funcall
k
(->>
(buffer-string)
(s-lines)
(-map #'s-trim)
(-filter #'s-present?)
(-map #'json-parse-string)
(--map (cons (ht-get it "title") (ht-get it "url"))))))))))
(defun w/youtube-play (url)
"Play the YouTube video at URL."
(message (format "Opening video at %s" url))
(make-process
:name w/youtube-mpv-process
:command (list "mpv" "--force-window=yes" url)))
(defun w/youtube ()
"Interactively search for and play a YouTube video."
(interactive)
(let ((query (read-string "YouTube: ")))
(w/youtube-search
query
(lambda (results)
(selector
(list
(selector-source-create
(format "YouTube search: %s" query)
:candidates
(--map (selector-candidate-create (car it) :value (cdr it)) results)
:actions
'(w/youtube-play))))))))
(provide 'wasp-youtube)
;;; wasp-youtube.el ends here
|