ffmpeg support

This commit is contained in:
2026-04-28 15:04:12 +02:00
parent d78a0ae9ff
commit d55f52818d
33 changed files with 157 additions and 22 deletions
+61 -12
View File
@@ -2,6 +2,9 @@
(require "flac-decoder.rkt"
"mp3-decoder.rkt"
"ffmpeg-decoder.rkt"
"audio-sniffer.rkt"
"private/utils.rkt"
racket/contract
racket/string
racket/path
@@ -52,12 +55,38 @@
mp3-stop
'ao))
;; FFmpeg decodere
(hash-set! audio-readers
'ffmpeg
(make-audio-reader '("ogg" "oga" "opus"
"m4a" "mp4" "m4b"
"aac"
"wav"
"aiff" "aif" "aifc"
"wma"
"webm" "mkv" "mka")
ffmpeg-valid?
ffmpeg-open
ffmpeg-read
ffmpeg-seek
ffmpeg-stop
'ao))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Known extensions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define known-extensions
'("flac" "mp3"))
'("flac" ; FLAC decoder
"mp3" ; mp3 decoder
"ogg" "oga" "opus"
"m4a" "mp4" "m4b"
"aac"
"wav"
"aiff" "aif" "aifc"
"wma"
"webm" "mkv" "mka" ; FFMPEG decoder
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Register audio reader
@@ -92,7 +121,11 @@
(set! ext (format "~a" ext))
(when (string-prefix? ext ".")
(set! ext (substring ext 1)))
(not (null? (filter (λ (e) (string-ci=? ext e)) known-extensions)))
(if (not (null? (filter (λ (e) (string-ci=? ext e)) known-extensions)))
#t
(begin
(warn-sound "extension '~a' not in known-extensions '~a'" ext known-extensions)
#f))
)
(define/contract (audio-file-valid? file)
@@ -189,17 +222,33 @@
(define (right-reader? reader ext)
(not (null? (filter (λ (e) (string-ci=? ext e)) (audio-reader-exts reader)))))
(define reader-for-kind
(make-hash '((mp3 . ffmpeg) ; ffmpeg does a better job on gapless playback...
(flac . flac)
(ogg . ffmpeg)
(vorbis . ffmpeg)
(opus . ffmpeg)
(wav . ffmpeg)
(aiff . ffmpeg)
(mp4 . ffmpeg)
(aac . ffmpeg)
(alac . ffmpeg)
(ac3 . ffmpeg)
(ape . ffmpeg)
(wavpack . ffmpeg)
(wma . ffmpeg)
(matroska . ffmpeg))))
(define (find-reader audio-file)
(let* ((f (build-path audio-file))
(ext (substring (format "~a" (path-get-extension audio-file)) 1)))
(letrec ((f (λ (keys)
(if (null? keys)
#f
(let ((reader (hash-ref audio-readers (car keys))))
(if (right-reader? reader ext)
(list (car keys) reader)
(f (cdr keys))))))))
(f (hash-keys audio-readers))
; First try to sniff the format
(let ((format (audio-sniff-format/extension audio-file)))
(let ((reader-kind (hash-ref reader-for-kind format #f)))
(if (eq? reader-kind #f)
#f
(let ((reader (hash-ref audio-readers reader-kind)))
(list reader-kind reader))
)
)
)
)