#!/usr/bin/guile !# (use-modules (srfi srfi-2) (sph filesystem) (sph alist) (sph io) (sph list) (ice-9 pretty-print) (sph number) (sph other) (sph process) (sph string) (sph vector) (sph) (sph lang indent-syntax) (sph cli) (json)) (define description "depends on ffmpeg, guile, guile-json and sph-lib") (define (ffprobe-audio-codec path) (catch #t (nullary (let* ( (json (json-string->scm (execute->string "ffprobe" "-v" "quiet" "-print_format" "json" "-show_streams" "-select_streams" "a" path))) (codec-names (map (l (a) (alist-ref a "codec_name")) (vector->list (alist-ref json "streams"))))) (if (null? codec-names) codec-names (first codec-names)))) (l exc (pretty-print exc) #f))) (define (ffmpeg-extract-audio path-source format) (and-let* ( (audio-codec (or format (ffprobe-audio-codec path-source))) (path-destination (string-append path-source "." audio-codec))) (apply execute "ffmpeg" "-i" path-source "-map" "0:a" path-destination (if format (list) (list "-c" "copy"))))) (define (run) (let* ( (description "extract audio streams from video files, by default without quality loss\n filenames will be \"{source-path}.{audio-filename-extension}\"") (dependencies (q ("sph-lib" "guile-json" "ffmpeg" "ffprobe"))) (about (qq ( ("description" (unquote description)) ("depends on" (unquote (string-join dependencies " "))) ("maintainer and copyright" "sph@posteo.eu | http://sph.mn") ("license" "gpl3+")))) (options ( (cli-create #:description description #:about (prefix-tree->indent-tree about) #:options (q ( (format #:value-required? #t #:description "filename extension of the output format") ((source-path ...))))))) (format (alist-ref options (q format)))) (map (l (source) (ffmpeg-extract-audio source format)) (alist-ref options (q source-path) (list))))) (run)