I’m unable to spot where I’ve gone wrong in writing the code below, except that it’s probably somewhere in the insertCheckboxArguments
method.
What this should do is define the ffmpegArguments
array based on the conversionSelection
method, then insert additional arguments into the array based on whether one or both of two checkboxes is checked, and then pass the (maybe altered, maybe not) array into the ffmpegConvert
process to be used as the convertTask.arguments
.
The conversionSelection
method works fine. The ffmpegConvert
process works fine when used with the ffmpegArguments
array created by the conversionSelection
method. The print statements confirm that the getAudiobookDuration
method is working as it should be…
…but when I run these methods all together with the ‘insertCheckboxArguments’ method, the ffmpeg process runs, but it produces a file that is 0.0 seconds long. Basically, it’s just the audiobook cover and metadata without the audio.
Because I’m so new at this, I’m still…fuzzy…on when it’s appropriate to use function parameters and returns, so that may be what I’m missing to pull this all together. But every time I go back to the tutorials and documentation to read up on that again, it seems to make sense to me in the context of the tutorial, but I fail to make the leap to applying it to my own situation here.
I suppose I could add additional switches into the conversionSelection method in order to combine it with the insertCheckboxArguments argument, but that feels like cheating. And it would definitely get sloppy and repetitive. Surely there’s a cleaner way.
// select a conversion preset
func conversionSelection() {
if inputFileUrl != nil {
let conversionChoice = conversionOptionsPopup.indexOfSelectedItem
switch conversionChoice {
case 1 :
outputExtension = ".mp3"
ffmpegArguments = [
"-hide_banner",
"-i", "\(inputFilePath)",
"-c:a", "libmp3lame",
"\(outputTextDisplay.stringValue)"
]
case 2:
outputExtension = ".flac"
ffmpegArguments = [
"-hide_banner",
"-i", "\(inputFilePath)",
"-c:a", "flac",
"\(outputTextDisplay.stringValue)"
]
default :
outputExtension = ".m4b"
ffmpegArguments = [
"-hide_banner",
"-i", "\(inputFilePath)",
"-c", "copy",
"\(outputTextDisplay.stringValue)"
]
}
}
}
// get audiobook length in order to trim from the end
func getAudiobookDuration() {
let audioAsset = AVURLAsset.init(url: inputFileUrl!, options: nil)
audioAsset.loadValuesAsynchronously(forKeys: ["duration"]) {
var error: NSError? = nil
let status = audioAsset.statusOfValue(forKey: "duration", error: &error)
switch status {
case .loaded: // Sucessfully loaded. Continue processing.
let duration = audioAsset.duration
self.fileDuration = CMTimeGetSeconds(duration)
self.trimmedAudio = self.fileDuration - 4.2
print("Audio Duration is: \(self.fileDuration)")
print("TrimmedAudioDuration is: \(self.trimmedAudio)")
break
case .failed: break // Handle error
case .cancelled: break // Terminate processing
default: break // Handle all other cases
}
}
}
// check if verbosity checkbox is marked, if so, add verbosity argument
// check if trimming checkbox is marked, if so, add trimming argument
// if both are marked, add both
func insertCheckboxArguments() {
conversionSelection()
getAudiobookDuration()
let verbositySelector = ffmpegVerboseLogCheckbox.state
let trimEndSelector = trimInOutClipsCheckbox.state
switch verbositySelector {
case .on :
switch trimEndSelector {
case .off :
ffmpegArguments.insert(contentsOf: ["-v", "verbose"], at: 1) // verbosity on, end trim off
default :
ffmpegArguments.insert(contentsOf: ["-v", "verbose"], at: 1) // both on
ffmpegArguments.insert(contentsOf: ["-ss", "00:00:02.000", "-t", "\(trimmedAudio)"], at: 3)
}
default :
switch trimEndSelector {
case .off : // neither on
break
default : // end trim on
ffmpegArguments.insert(contentsOf: ["-ss", "00:00:02.000", "-t", "\(trimmedAudio)"], at: 1)
}
}
}
// MARK: ffmpeg code
func ffmpegConvert() {
insertCheckboxArguments()
guard let launchPath = Bundle.main.path(forResource: "ffmpeg", ofType: "") else { return }
do {
let convertTask: Process = Process()
convertTask.launchPath = launchPath
convertTask.arguments = ffmpegArguments
convertTask.standardInput = FileHandle.nullDevice
convertTask.launch()
convertTask.waitUntilExit()
}
}