123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #!/usr/bin/env -S guile --no-auto-compile -e main -s
- !#
- ;;; convert-music --- Convert video clips to audio only
- ;;; Copyright © 2019, 2022 Oleg Pykhalov <go.wigust@gmail.com>
- ;;;
- ;;; This file is part of convert-music.
- ;;;
- ;;; convert-music is free software; you can redistribute it and/or modify it
- ;;; under the terms of the GNU General Public License as published by
- ;;; the Free Software Foundation; either version 3 of the License, or (at
- ;;; your option) any later version.
- ;;;
- ;;; convert-music is distributed in the hope that it will be useful, but
- ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;; GNU General Public License for more details.
- ;;;
- ;;; You should have received a copy of the GNU General Public License
- ;;; along with convert-music. If not, see <http://www.gnu.org/licenses/>.
- ;; Convert video clips in /srv/music directory to audio files without a video
- ;; part and store them in /srv/audio directory. To do that, run:
- ;;
- ;; convert-music /srv/music /srv/audio
- (use-modules (ice-9 format)
- (ice-9 ftw)
- (ice-9 match)
- (ice-9 popen)
- (ice-9 rdelim)
- (ice-9 readline)
- (json)
- (srfi srfi-1)
- (srfi srfi-26)
- (srfi srfi-37))
- (define (list-files dir)
- (filter (match-lambda
- ((name #(_ _ _ _ _ _ _ _ _ _ _ _ _ 'regular _ _ _ _)) name)
- (_ #f))
- (file-system-tree dir)))
- (define %options
- (let ((display-and-exit-proc (lambda (msg)
- (lambda (opt name arg loads)
- (display msg) (quit)))))
- (list (option '(#\v "version") #f #f
- (display-and-exit-proc "convert-music version 0.0.1\n"))
- (option '(#\h "help") #f #f
- (display-and-exit-proc
- "Usage: convert-music /srv/music /srv/audio ...")))))
- (define %default-options
- '())
- (define (codec-name->file-extension codec-name)
- (case codec-name
- ((opus) ".opus")
- ((vorbis) ".ogg")
- ((aac) ".aac")
- (else #f)))
- (define (main . args)
- (define opts
- (args-fold (cdr (program-arguments))
- %options
- (lambda (opt name arg loads)
- (error "Unrecognized option `~A'" name))
- (lambda (op loads)
- (cons op loads))
- %default-options))
- (define input-directory
- (first (reverse opts)))
- (define output-directory
- (second (reverse opts)))
- (for-each (lambda (file)
- (match file
- ((n ... ext)
- (let* ((input (string-append input-directory "/"
- (string-join file ".")))
- (output-file-name
- (match (string-split (basename input) #\.)
- ((file-name ... file-extension)
- (string-join file-name "."))
- ((file-name file-extension)
- file-name))))
- (let* ((port (open-pipe* OPEN_READ "ffprobe"
- "-show_streams"
- "-loglevel" "error"
- "-print_format" "json"
- input))
- (output (read-string port)))
- (close-port port)
- (for-each (lambda (stream)
- (when (string= (assoc-ref stream "codec_type")
- "audio")
- (let ((output
- (string-append
- output-directory "/"
- output-file-name
- (codec-name->file-extension
- (string->symbol
- (assoc-ref stream "codec_name"))))))
- (format #t "input: ~a~%"
- input)
- (format #t "format: ~a~%"
- (assoc-ref stream "codec_name"))
- (format #t "output: ~a~%"
- output)
- (unless (file-exists? output)
- (unless
- (= 0 (system*
- "ffmpeg"
- "-loglevel" "quiet"
- "-i" input
- "-vn" ;no video
- "-c:a" "copy" ;copy audio
- output))
- (exit 1)))
- (newline))))
- (array->list
- (assoc-ref (json-string->scm
- (string-trim-right output #\newline))
- "streams"))))))))
- (map (cut string-split <> #\.)
- (map (match-lambda ((file _ ...) file))
- (list-files input-directory)))))
|