No places.
This commit is contained in:
@@ -21,8 +21,7 @@ absolute mount points are not stored, and path separators are always `/`.
|
|||||||
## FLAC 48 kHz manager
|
## FLAC 48 kHz manager
|
||||||
|
|
||||||
The command keeps a FLAC directory tree at a maximum sample rate of 48 kHz.
|
The command keeps a FLAC directory tree at a maximum sample rate of 48 kHz.
|
||||||
Files above the configured threshold are converted in place through a Racket
|
Files above the configured threshold are converted synchronously by the batch process. The conversion path uses `racket-audio/audio-encoder` dynamically, so the
|
||||||
place. The conversion path uses `racket-audio/audio-encoder` dynamically, so the
|
|
||||||
package can still compile on systems where the native audio libraries are not
|
package can still compile on systems where the native audio libraries are not
|
||||||
installed yet.
|
installed yet.
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,9 @@
|
|||||||
(summary-inc s 'removed)))))
|
(summary-inc s 'removed)))))
|
||||||
|
|
||||||
(define (find-source-files source-dir)
|
(define (find-source-files source-dir)
|
||||||
(filter (lambda (p) (not (manager-admin-relpath? (source-relpath-string source-dir p))))
|
(filter (lambda (p)
|
||||||
|
(and (not (manager-temp-path? p))
|
||||||
|
(not (manager-admin-relpath? (source-relpath-string source-dir p)))))
|
||||||
(directory-file-paths source-dir)))
|
(directory-file-paths source-dir)))
|
||||||
|
|
||||||
(define (manage-flac2opus-tree source-directory target-directory
|
(define (manage-flac2opus-tree source-directory target-directory
|
||||||
|
|||||||
+30
-33
@@ -1,9 +1,7 @@
|
|||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require racket/file
|
(require racket/file
|
||||||
racket/path
|
racket/path)
|
||||||
racket/place
|
|
||||||
"util.rkt")
|
|
||||||
|
|
||||||
(provide convert-flac-to-target-in-place)
|
(provide convert-flac-to-target-in-place)
|
||||||
|
|
||||||
@@ -12,35 +10,34 @@
|
|||||||
(define name-str (path->string name))
|
(define name-str (path->string name))
|
||||||
(build-path base (format ".~a.tmp-~a.flac" name-str (current-inexact-milliseconds))))
|
(build-path base (format ".~a.tmp-~a.flac" name-str (current-inexact-milliseconds))))
|
||||||
|
|
||||||
(define (settings->alist max-sample-rate compression-level)
|
(define (settings->hash max-sample-rate compression-level)
|
||||||
(list (cons 'target-sample-rate max-sample-rate)
|
(make-immutable-hash
|
||||||
(cons 'compression-level compression-level)))
|
(list (cons 'target-sample-rate max-sample-rate)
|
||||||
|
(cons 'compression-level compression-level))))
|
||||||
|
|
||||||
(define (convert-flac-to-target-in-place input-path max-sample-rate compression-level)
|
(define (delete-file/quiet path)
|
||||||
|
(with-handlers ([exn:fail? (lambda (_) #f)])
|
||||||
|
(when (file-exists? path) (delete-file path))))
|
||||||
|
|
||||||
|
(define (convert-flac-to-target-in-place input-path max-sample-rate compression-level
|
||||||
|
#:progress-callback [progress-callback #f])
|
||||||
(define tmp-path (temp-output-path input-path))
|
(define tmp-path (temp-output-path input-path))
|
||||||
(define worker
|
(define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode))
|
||||||
(place ch
|
(with-handlers ([exn:break?
|
||||||
(define msg (place-channel-get ch))
|
(lambda (e)
|
||||||
(define in-file (list-ref msg 0))
|
(delete-file/quiet tmp-path)
|
||||||
(define out-file (list-ref msg 1))
|
(raise e))]
|
||||||
(define settings (list-ref msg 2))
|
[exn:fail?
|
||||||
(with-handlers ([exn:fail?
|
(lambda (e)
|
||||||
(lambda (e)
|
(delete-file/quiet tmp-path)
|
||||||
(place-channel-put ch (list 'error (exn-message e))))])
|
(error 'convert-flac-to-target-in-place
|
||||||
(define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode))
|
"conversion failed for ~a: ~a" input-path (exn-message e)))])
|
||||||
(define result (audio-encode in-file out-file (make-immutable-hash settings)
|
(define result
|
||||||
#:encoder 'flac
|
(audio-encode (path->string input-path)
|
||||||
#:copy-tags? #t))
|
(path->string tmp-path)
|
||||||
(place-channel-put ch (list 'ok result)))))
|
(settings->hash max-sample-rate compression-level)
|
||||||
(place-channel-put worker (list (path->string input-path)
|
#:encoder 'flac
|
||||||
(path->string tmp-path)
|
#:copy-tags? #t
|
||||||
(settings->alist max-sample-rate compression-level)))
|
#:progress-callback progress-callback))
|
||||||
(define response (place-channel-get worker))
|
(rename-file-or-directory tmp-path input-path #t)
|
||||||
(cond [(and (pair? response) (eq? (car response) 'ok))
|
result))
|
||||||
(rename-file-or-directory tmp-path input-path #t)
|
|
||||||
(cadr response)]
|
|
||||||
[else
|
|
||||||
(when (file-exists? tmp-path) (delete-file tmp-path))
|
|
||||||
(error 'convert-flac-to-target-in-place "conversion failed for ~a: ~a"
|
|
||||||
input-path
|
|
||||||
(if (and (pair? response) (pair? (cdr response))) (cadr response) response))]))
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
(require racket/file
|
(require racket/file
|
||||||
racket/list
|
racket/list
|
||||||
racket/path
|
racket/path
|
||||||
racket/place
|
|
||||||
racket/string
|
racket/string
|
||||||
"util.rkt")
|
"util.rkt")
|
||||||
|
|
||||||
@@ -84,28 +83,34 @@
|
|||||||
(tags-save! tags)))
|
(tags-save! tags)))
|
||||||
#:mode 'read-write))
|
#:mode 'read-write))
|
||||||
|
|
||||||
(define (convert-flac-to-opus input-path output-path kbps)
|
(define (delete-file/quiet path)
|
||||||
|
(with-handlers ([exn:fail? (lambda (_) #f)])
|
||||||
|
(when (file-exists? path) (delete-file path))))
|
||||||
|
|
||||||
|
(define (convert-flac-to-opus input-path output-path kbps
|
||||||
|
#:progress-callback [progress-callback #f])
|
||||||
(define tmp-path (temp-output-path output-path))
|
(define tmp-path (temp-output-path output-path))
|
||||||
(ensure-parent-directory! tmp-path)
|
(ensure-parent-directory! tmp-path)
|
||||||
(define worker
|
(with-handlers ([exn:break?
|
||||||
(place ch
|
(lambda (e)
|
||||||
(define msg (place-channel-get ch))
|
(delete-file/quiet tmp-path)
|
||||||
(define in-file (list-ref msg 0))
|
(raise e))]
|
||||||
(define out-file (list-ref msg 1))
|
[exn:fail?
|
||||||
(define kbps (list-ref msg 2))
|
(lambda (e)
|
||||||
(with-handlers ([exn:fail? (lambda (e) (place-channel-put ch (list 'error (exn-message e))))])
|
(delete-file/quiet tmp-path)
|
||||||
(define-values (settings properties picture) (source-tags->settings in-file kbps))
|
(error 'convert-flac-to-opus
|
||||||
(define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode))
|
"conversion failed for ~a: ~a" input-path (exn-message e)))])
|
||||||
(define result (audio-encode in-file out-file settings #:encoder 'opus #:copy-tags? #f))
|
(define-values (settings properties picture)
|
||||||
(copy-all-tag-properties! out-file properties picture)
|
(source-tags->settings (path->string input-path) kbps))
|
||||||
(place-channel-put ch (list 'ok result)))))
|
(define audio-encode (dynamic-require 'racket-audio/audio-encoder 'audio-encode))
|
||||||
(place-channel-put worker (list (path->string input-path) (path->string tmp-path) kbps))
|
(define result
|
||||||
(define response (place-channel-get worker))
|
(audio-encode (path->string input-path)
|
||||||
(cond [(and (pair? response) (eq? (car response) 'ok))
|
(path->string tmp-path)
|
||||||
(ensure-parent-directory! output-path)
|
settings
|
||||||
(rename-file-or-directory tmp-path output-path #t)
|
#:encoder 'opus
|
||||||
(cadr response)]
|
#:copy-tags? #f
|
||||||
[else
|
#:progress-callback progress-callback))
|
||||||
(when (file-exists? tmp-path) (delete-file tmp-path))
|
(copy-all-tag-properties! (path->string tmp-path) properties picture)
|
||||||
(error 'convert-flac-to-opus "conversion failed for ~a: ~a" input-path
|
(ensure-parent-directory! output-path)
|
||||||
(if (and (pair? response) (pair? (cdr response))) (cadr response) response))]))
|
(rename-file-or-directory tmp-path output-path #t)
|
||||||
|
result))
|
||||||
|
|||||||
+2
-1
@@ -36,4 +36,5 @@
|
|||||||
[else acc]))))
|
[else acc]))))
|
||||||
|
|
||||||
(define (find-flac-files base-dir)
|
(define (find-flac-files base-dir)
|
||||||
(sort-paths (filter flac-path? (find-regular-files base-dir))))
|
(sort-paths (filter (lambda (p) (and (flac-path? p) (not (manager-temp-path? p))))
|
||||||
|
(find-regular-files base-dir))))
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
filesystem-path
|
filesystem-path
|
||||||
flac-path?
|
flac-path?
|
||||||
opus-path?
|
opus-path?
|
||||||
|
manager-temp-path?
|
||||||
directory-file-paths
|
directory-file-paths
|
||||||
replace-path-extension
|
replace-path-extension
|
||||||
ensure-parent-directory!
|
ensure-parent-directory!
|
||||||
@@ -112,6 +113,16 @@
|
|||||||
(define (file-exists?/quiet p)
|
(define (file-exists?/quiet p)
|
||||||
(with-handlers ([exn:fail? (lambda (_) #f)]) (file-exists? p)))
|
(with-handlers ([exn:fail? (lambda (_) #f)]) (file-exists? p)))
|
||||||
|
|
||||||
|
(define (path-file-name-string p)
|
||||||
|
(let-values ([(base name dir?) (split-path p)])
|
||||||
|
(and (path? name) (path->string name))))
|
||||||
|
|
||||||
|
(define (manager-temp-path? p)
|
||||||
|
(define name (path-file-name-string p))
|
||||||
|
(and name
|
||||||
|
(string-prefix? name ".")
|
||||||
|
(regexp-match? #rx"\\.tmp-[0-9.]+\\.(flac|opus)$" name)))
|
||||||
|
|
||||||
(define (flac-path? p)
|
(define (flac-path? p)
|
||||||
(and (file-exists?/quiet p) (extension-ci=? p ".flac")))
|
(and (file-exists?/quiet p) (extension-ci=? p ".flac")))
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ so it can share the same database with the 48 kHz manager.
|
|||||||
@section{FLAC 48 kHz manager}
|
@section{FLAC 48 kHz manager}
|
||||||
|
|
||||||
The tool @filepath{flac-48khz-manager.rkt} keeps a FLAC tree at a maximum sample
|
The tool @filepath{flac-48khz-manager.rkt} keeps a FLAC tree at a maximum sample
|
||||||
rate of 48 kHz. Files with a higher sample rate are converted in place through a
|
rate of 48 kHz. Files with a higher sample rate are converted synchronously by the batch process. The conversion path uses
|
||||||
worker place. The conversion path uses
|
|
||||||
@racketmodname[racket-audio/audio-encoder] dynamically, so the manager module can
|
@racketmodname[racket-audio/audio-encoder] dynamically, so the manager module can
|
||||||
still be compiled on systems where the native audio libraries are not available.
|
still be compiled on systems where the native audio libraries are not available.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user