Make MP3Gain options configurable
This commit is contained in:
@@ -426,17 +426,59 @@ struct SDCardCleaner {
|
||||
}
|
||||
|
||||
struct MP3GainNormalizer {
|
||||
struct Options {
|
||||
enum GainMode: Hashable {
|
||||
case track
|
||||
case album
|
||||
}
|
||||
|
||||
let gainMode: GainMode
|
||||
let preventClipping: Bool
|
||||
let dbOffset: String
|
||||
|
||||
var arguments: [String] {
|
||||
var result: [String] = []
|
||||
|
||||
switch gainMode {
|
||||
case .track:
|
||||
result.append("-r")
|
||||
case .album:
|
||||
result.append("-a")
|
||||
}
|
||||
|
||||
if preventClipping {
|
||||
result.append("-k")
|
||||
}
|
||||
|
||||
let trimmedOffset = dbOffset.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if !trimmedOffset.isEmpty {
|
||||
result.append(contentsOf: ["-d", trimmedOffset.replacingOccurrences(of: ",", with: ".")])
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
var commandDescription: String {
|
||||
(["mp3gain"] + arguments).joined(separator: " ")
|
||||
}
|
||||
}
|
||||
|
||||
private let fileManager: FileManager
|
||||
|
||||
init(fileManager: FileManager) {
|
||||
self.fileManager = fileManager
|
||||
}
|
||||
|
||||
func normalize(rootURL: URL) -> [ExportMessage] {
|
||||
func normalize(rootURL: URL, options: Options) -> [ExportMessage] {
|
||||
guard let mp3gainURL = mp3gainExecutableURL() else {
|
||||
return [.error("mp3gain wurde nicht gefunden. Erwartet z. B. /opt/homebrew/bin/mp3gain.")]
|
||||
}
|
||||
|
||||
let validationMessages = validate(options: options)
|
||||
if !validationMessages.isEmpty {
|
||||
return validationMessages
|
||||
}
|
||||
|
||||
do {
|
||||
let mp3Files = try MP3FileFinder(fileManager: fileManager).mp3Files(in: rootURL)
|
||||
guard !mp3Files.isEmpty else {
|
||||
@@ -447,7 +489,7 @@ struct MP3GainNormalizer {
|
||||
var processed = 0
|
||||
|
||||
for batch in mp3Files.chunked(into: 50) {
|
||||
let result = runMP3Gain(executableURL: mp3gainURL, files: batch)
|
||||
let result = runMP3Gain(executableURL: mp3gainURL, options: options, files: batch)
|
||||
messages.append(contentsOf: result.messages)
|
||||
if result.success {
|
||||
processed += batch.count
|
||||
@@ -461,10 +503,27 @@ struct MP3GainNormalizer {
|
||||
}
|
||||
}
|
||||
|
||||
private func runMP3Gain(executableURL: URL, files: [URL]) -> (success: Bool, messages: [ExportMessage]) {
|
||||
private func validate(options: Options) -> [ExportMessage] {
|
||||
let trimmedOffset = options.dbOffset.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !trimmedOffset.isEmpty else {
|
||||
return []
|
||||
}
|
||||
|
||||
guard Double(trimmedOffset.replacingOccurrences(of: ",", with: ".")) != nil else {
|
||||
return [.error("dB-Offset muss eine Zahl sein, z. B. 4 oder -2.5.")]
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
private func runMP3Gain(
|
||||
executableURL: URL,
|
||||
options: Options,
|
||||
files: [URL]
|
||||
) -> (success: Bool, messages: [ExportMessage]) {
|
||||
let process = Process()
|
||||
process.executableURL = executableURL
|
||||
process.arguments = ["-r", "-k", "-d", "4"] + files.map { $0.path(percentEncoded: false) }
|
||||
process.arguments = options.arguments + files.map { $0.path(percentEncoded: false) }
|
||||
|
||||
let outputPipe = Pipe()
|
||||
let errorPipe = Pipe()
|
||||
|
||||
Reference in New Issue
Block a user