blob: cafe46b66263dd09c4bf601be1bfa896f1173252 (
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
76
77
78
79
80
|
;;;; downloader.lisp
(in-package #:vampire)
(defvar *dl-cluster*)
(defvar *media-directory*)
(defun start-downloader-service (config)
(let ((media-dir
(merge-pathnames "media/" (static-directory config))))
(ensure-directories-exist media-dir)
(setf *dl-cluster* (legion:make-cluster (downloader-threads config)
(lambda (job) (funcall job media-dir)))))
(legion:start *dl-cluster*))
(defun add-fetch-track-job (url ok err)
"URL is a url to some audio track. OK is a function that accepts a
TRACK instance. ERR is a function accepting an error condition"
(legion:add-job
*dl-cluster*
(lambda (media-dir)
(handler-case
(funcall ok (download-media url media-dir))
(error (e) (funcall err e))))))
(defun trackinfo-file (dir name)
(merge-pathnames
(format nil "~a.info.json" name)
dir))
(defun trackmedia-file (dir)
(find-if
(lambda (path)
(not (string-equal "json" (pathname-type path))))
(uiop:directory-files dir)))
(defun trackinfo (path)
"Returns a trackinfo object - a list whose first member is a path to
a file and whose CDR is a PLIST of attributes to pass
to (make-instance 'track ...)"
(with-plist ((title :|title|)
(track-title :|track|)
(album :|album|)
(codec :|acodec|)
(artist :|artist|)
(dur :|duration|)
(thumbs :|thumbnails|)
(source :|webpage_url|))
(jonathan:parse (alexandria:read-file-into-string path))
(with-plist ((url :|url|)) (first thumbs)
(list
:source source
:title (or track-title title)
:album album
:codec codec
:artist artist
:duration dur
:thumb-url url))))
(defun download-media (url media-dir)
"Download media and create a new track from its audio source, moving
the raw audio to the media-dir when done."
(with-temp-dir (tmpdir)
(let* ((tmpname
(default-name "media"))
(trackinfo-file
(trackinfo-file tmpdir tmpname)))
(uiop:run-program
(format nil "youtube-dl --format-sort aext --prefer-free-formats --playlist-end 1 --write-info-json -x -o \"~a/~a.%(ext)s\" '~a'"
tmpdir tmpname url))
(let* ((info
(trackinfo trackinfo-file))
(downloaded
(trackmedia-file tmpdir))
(file
(merge-pathnames (format nil "~a.~a"
(nuid) (pathname-type downloaded))
media-dir)))
(uiop:copy-file downloaded file)
(new-track file info)))))
|