Recently Written · git

librivox

Automated youtube uploading of audiobooks

git clone https://github.com/equwal/librivox

Log | Files | Refs


src/ffmpeg.lisp (2897 bytes)

1 (in-package :librivox)
2 (defvar *downloads-dir* "/run/media/raw-downloads/")
3 (defvar *max-seconds* (* 60 60 12))
4 (defvar *image-types* (list "jpg"))
5 (defvar *archive-types* (list "m3u"))
6 (defvar *video-types* (list "mp4"))
7 (defvar *audio-types* (list "mp3"))
8 (defvar *text-types* (list "txt"))
9 (defvar *types* (list *image-types*
10                       *archive-types*
11                       *video-types*
12                       *audio-types*
13                       *text-types*))
14 (defvar *comletion-name* "completion.tmp")
15 (defun change-dir (dir code)
16   (format nil "cd ~A && ~A" dir code))
17 (defun run-line* (code &optional (output *debug-io*))
18   (run-line (change-dir *downloads-dir* code) :output output))
19 (defun run-line*-integer-output (code)
20   (parse-integer (run-program (change-dir *downloads-dir* code)
21 			      :output :string) :junk-allowed t))
22 (defun book-down (path)
23   (with-open-file (s path)
24     (dolines (line s)
25       (run-line* (format nil "wget -nc ~A" line)) (print line))))
26 (defmacro unwind-prog1 (cleanup &body protected)
27   `(unwind-protect (progn ,@protected) ,cleanup))
28 (defun delete-types (&optional more)
29   (dolist (y (append *types* more))
30     (run-line* (concat "rm *." y))))
31 (defun safe-exit (old-dir)
32   (setf *downloads-dir* old-dir)
33   (delete-types))
34 (defun convert (&key dir image input)
35   "Convert the zip to video."
36   (let ((old-dir *downloads-dir*))
37     (setf *downloads-dir* dir)
38     (unwind-prog1
39         (safe-exit old-dir)
40       (book-down input)
41       (run-line* "for f in *.mp3; do echo \"file '$f'\" >> concat.txt; done")
42       (run-line* "ffmpeg -f concat -safe 0 -i concat.txt -c copy output1.mp3")
43       (mvbind (times rem) (ceiling (/ (run-line*-integer-output "mp3info -p \"%S\" output1.mp3") *max-seconds*))
44 	      (dotimes (n times)
45 	        (let ((duration (if (= times (1+ n))
46 				    (* (1+ rem) *max-seconds*)
47 				    *max-seconds*)))
48 		  (run-line* (format nil "ffmpeg -loop 1 -i ~A -t ~D -c mjpeg temp-~D.mp4"
49 				     image duration n))
50 		  (run-line* (format nil "ffmpeg -ss ~D -t ~D -i output1.mp3 -c copy output-~D.mp3"
51 				     (* n *max-seconds*) duration n))
52 		  (run-line* (format nil "ffmpeg -i temp-~D.mp4 -i output-~:*~D.mp3 -c copy output-~:*~D.mp4"
53 				     n))
54 		  (run-line* (format nil "rm temp-~D.mp4" n))))))))
55 (defmacro deftypep (name general &key (test 'string-equal))
56   "Specific file type check."
57   (with-gensyms (x)
58     `(defun ,name (path)
59        (some #'(lambda (,x) (funcall ,test (pathname-type path) ,x))
60              ,general))))
61 (deftypep image-typep *image-types*)
62 (deftypep archive-typep *archive-types*)
63 (deftypep video-typep *video-types*)
64 (defun convert-all ()
65   (dolist (dir (subdirectories *downloads-dir*))
66     (let ((contents (directory-files dir)))
67       (when (not (some #'video-typep contents))
68 	(convert :image (select #'image-typep contents)
69 		 :input (select #'archive-typep contents)
70 		 :dir dir)))))