ambrevar/ffprobe: Add some missing stream fields.

master
Pierre Neidhardt 2021-01-15 19:41:50 +01:00
parent 0a057edbd4
commit 54ef9aaaed
1 changed files with 54 additions and 19 deletions

View File

@ -14,6 +14,8 @@
(declare (ignore definition)) (declare (ignore definition))
name)) name))
;; TODO: Should leave unspecified fields unbound?
(defclass* disposition () (defclass* disposition ()
((default 0) ((default 0)
(dub 0) (dub 0)
@ -27,7 +29,9 @@
(clean-effects 0) (clean-effects 0)
(attached-pic 0) (attached-pic 0)
(timed-thumbnails 0)) (timed-thumbnails 0))
(:accessor-name-transformer #'name-identity)) (:accessor-name-transformer #'name-identity)
(:export-slot-names-p t)
(:export-class-name-p t))
(defclass* media-stream () ; REVIEW: `stream' is reserved by CL. (defclass* media-stream () ; REVIEW: `stream' is reserved by CL.
((index 0) ((index 0)
@ -45,7 +49,16 @@
(level 0) (level 0)
(color-range "") (color-range "")
(color-space "") (color-space "")
(color-transfer "")
(color-primaries "")
(chroma-location "")
(field-order "")
(refs 0) (refs 0)
(id "")
(quarter-sample nil
:type boolean)
(divx-packed nil
:type boolean)
(sample-aspect-ratio "") (sample-aspect-ratio "")
(display-aspect-ratio "") (display-aspect-ratio "")
(codec-time-base "") ; TODO: Ratio? (codec-time-base "") ; TODO: Ratio?
@ -56,6 +69,14 @@
(channels 2) (channels 2)
(channel-layout "") (channel-layout "")
(bits-per-sample 0) (bits-per-sample 0)
(dmix-mode 0)
(ltrt-cmixlev 0.0)
(ltrt-surmixlev 0.0)
(loro-cmixlev 0.0)
(loro-surmixlev 0.0)
(is-avc nil
:type boolean)
(nal-length-size 0)
(r-frame-rate "") ; TODO: Ratio? (r-frame-rate "") ; TODO: Ratio?
(avg-frame-rate "") ; TODO: Ratio? (avg-frame-rate "") ; TODO: Ratio?
(time-base "") (time-base "")
@ -64,10 +85,16 @@
(duration-ts 0.0) (duration-ts 0.0)
(duration 0.0) (duration 0.0)
(bit-rate 0) (bit-rate 0)
(bits-per-raw-sample 0)
(nb-frames 0)
(max-bit-rate 0)
(disposition nil (disposition nil
:type (or null disposition)) :type (or null disposition))
(side-data-list '())
(tags '())) (tags '()))
(:accessor-name-transformer #'name-identity)) (:accessor-name-transformer #'name-identity)
(:export-slot-names-p t)
(:export-class-name-p t))
(defclass* media-format () ; REVIEW: `format' is reserved by CL. (defclass* media-format () ; REVIEW: `format' is reserved by CL.
((filename "") ((filename "")
@ -81,7 +108,9 @@
(bit-rate 0) (bit-rate 0)
(probe-score 0) (probe-score 0)
(tags '())) (tags '()))
(:accessor-name-transformer #'name-identity)) (:accessor-name-transformer #'name-identity)
(:export-slot-names-p t)
(:export-class-name-p t))
(defun normalize-cl-json-keywords (sym) (defun normalize-cl-json-keywords (sym)
"Turn '--' to '-' and remove '+' from keywords." "Turn '--' to '-' and remove '+' from keywords."
@ -95,11 +124,14 @@
(defun normalize-cl-json-scalar (value) (defun normalize-cl-json-scalar (value)
"Turn non-ratio number string to numbers." "Turn non-ratio number string to numbers."
(if (stringp value) (if (stringp value)
(let ((result (ignore-errors (parse-number:parse-number value)))) (match value
("true" t)
("false" nil)
(_ (let ((result (ignore-errors (parse-number:parse-number value))))
(if (and result (if (and result
(not (typep result 'ratio))) (not (typep result 'ratio)))
result result
value)) value))))
value)) value))
(defun json->media-args (json) (defun json->media-args (json)
@ -107,20 +139,23 @@
((cons key value) ((cons key value)
(list (normalize-cl-json-keywords key) (list (normalize-cl-json-keywords key)
(if (listp value) (if (listp value)
(format-ffprobe-json value) (json->media-args value)
(normalize-cl-json-scalar value))))) (normalize-cl-json-scalar value)))))
json)) json))
(export-always 'ffprobe)
(defun ffprobe (path) (defun ffprobe (path)
"Return a list of (MEDIA-FORMAT MEDIA-STREAMS...)." "Return a list of (MEDIA-FORMAT MEDIA-STREAMS...)."
(let* ((json-string (let* ((json-string
(ignore-errors
(cmd:$cmd "ffprobe -v quiet -print_format json -show_format -show_streams -- " (cmd:$cmd "ffprobe -v quiet -print_format json -show_format -show_streams -- "
(write-to-string path))) (write-to-string path)))))
(json (cl-json:decode-json-from-string json-string))) (when json-string
(let* ((format-args (json->media-args (alex:assoc-value json :format))) (let* ((json (cl-json:decode-json-from-string json-string))
(format-args (json->media-args (alex:assoc-value json :format)))
(format (apply #'make-instance 'media-format format-args))) (format (apply #'make-instance 'media-format format-args)))
(cons format (cons format
(mapcar (lambda (s) (mapcar (lambda (s)
(let ((stream-args (json->media-args s))) (let ((stream-args (json->media-args s)))
(apply #'make-instance 'media-stream stream-args))) (apply #'make-instance 'media-stream stream-args)))
(alex:assoc-value json :streams)))))) (alex:assoc-value json :streams)))))))