-
Notifications
You must be signed in to change notification settings - Fork 0
/
make-mkv.lisp
executable file
·119 lines (102 loc) · 4.3 KB
/
make-mkv.lisp
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
":"; C="exec sbcl --noinform --end-runtime-options --disable-debugger"
":"; $C --load "$0" --eval '(main)' --quit --end-toplevel-options "$@"
;; Make small MKV-files for Smart-TVs
;; For teletext, see https://ffmpeg.org/ffmpeg-codecs.html#Options-9
(dolist (package '(:cl-ppcre :trivial-file-size :cl-diskspace))
(require package))
(unless (constantp '+defaults+)
(defconstant +defaults+
`(:vdr-dir "/var/spool/video"
:dest-dir "/opt/video"
:in-opts ("-fix_sub_duration" "-txt_page" "subtitle")
:out-opts ("-map" "0" "-c:v" "libx264" "-preset" "faster"
"-crf" "20" "-c:a" "copy" "-c:s" "dvdsub" "-dn")
:cmd "nice"
:nice-args ("-n19" "ffmpeg"))))
(defvar *config-file* "~/.config/make-mkv.conf" "configuration file")
(defvar *config* nil "configuration list")
(defvar *src-dir* nil "directory with info and TS files")
(defvar *channel* nil "channel name")
(defvar *name* nil "prefix for the files, name of the film")
(defvar *imdb-id* nil "IMDB identifier")
(defun file-to-list (file)
(with-open-file (in file)
(with-standard-io-syntax
(loop for obj = (read in nil)
while obj collect obj))))
(defun read-config ()
"Read configuration from configuration file."
(when *config-file*
(setf *config* (file-to-list *config-file*))))
(defun cv (name)
"Get configuration value."
(or (getf *config* name) (getf +defaults+ name)))
(defun strmerge (&rest strings)
(apply #'concatenate 'string strings))
(defun new-ts ()
"Check, if new TS is to be converted.
There should be at least 2 candidates, because it’s possible,
that a cutting process is still running.
Side effect: *src-dir* is set."
(let ((l (sort (directory (format nil "~a/%*/*.rec" (cv :vdr-dir)))
#'< :key #'(lambda (x) (file-write-date x)))))
(if (> (length l) 1)
(setf *src-dir* (native-namestring (first l))))))
(defun get-name ()
(let* ((seq (subseq *src-dir* (search "%" *src-dir*)))
(end (search "/" seq)))
(subseq seq 1 end)))
(defun split-name+imdb-id ()
(multiple-value-bind (res n+i) (cl-ppcre:scan-to-strings "^(.*)-(tt[0-9]+)$" *name*)
(if res
(setf *name* (elt n+i 0)
*imdb-id* (elt n+i 1)))))
(defun gather-infos ()
(with-open-file (in (native-pathname (strmerge *src-dir* "info")))
(let ((first-line (read-line in)))
(setf *channel* (subseq first-line
(1+ (search " " first-line :start2 2))))))
(setf *name* (get-name))
(split-name+imdb-id))
(defun my-exit (str arg code)
(format t str arg)
(exit :code code))
(defun convert-to-mkv ()
(let* ((in-file (strmerge *src-dir* "00001.ts"))
(prefix (strmerge (cv :dest-dir) "/" *name*))
(out-file (strmerge prefix ".mkv"))
(size (trivial-file-size:file-size-in-octets in-file))
(free (diskspace:disk-available-space (cv :dest-dir))))
(format t "Trying to create ~a:~%" out-file)
(if (> size free)
(my-exit "Very low available space: ~d MiB. Exiting...~%"
(round (/ free 1024 1024)) 1))
(if (probe-file (native-pathname out-file))
(my-exit "File ~a already exists. Exiting...~%" out-file 1))
(let* ((inf (native-pathname (strmerge prefix ".inf")))
(log (strmerge prefix ".log"))
(nice-args (cv :nice-args))
(args (append nice-args (cv :in-opts) (list "-i" in-file)
(cv :out-opts) (list out-file)))
(proc (run-program (cv :cmd) args
:output (native-pathname log) :search t))
(code (process-exit-code proc)))
(when (/= code 0)
(my-exit "Error, please see ~a.~%" log code))
(rename-file (native-pathname (strmerge *src-dir* "info")) inf)
(with-open-file (s inf :direction :output :if-exists :append)
(format s "I ~a~%" *imdb-id*))
(format t "Success.~%Arguments were:~%~a~%"
(nthcdr (length nice-args) args)))))
(defun main ()
"Main program."
(if (second sb-ext:*posix-argv*)
(setf *config-file* (second sb-ext:*posix-argv*)))
(read-config)
(when (new-ts)
(gather-infos)
(convert-to-mkv)
(delete-directory (native-pathname *src-dir*) :recursive t)))
;; Local Variables:
;; pm/slime-auto-load: t
;; End: