***Edit: The more I look at this, the more I’m convinced that the issue is that the outputText NSTextField is not coded to update when the codecSelector NSPopupButton changes (or the codecSelector popup is not coded to force a change to outputText). So I suppose I need to change my question:
How do I compel a change in the outputText NSTextField so that it gets a new value from codecChosen variable when codecChosen is changed by a selection in the codecSelector NSPopupButton method?
My other question, regarding how to establish a default codec choice, remains, though of course that default choice also needs to register in the outputText NSTextField.
I’m trying to create a ffmpeg GUI that will allow users to convert their audiobooks to other formats
I have two text fields in my project. One of them is populated by the stringValue of the input file chosen. That part was relatively easy.
The output text field is a little tougher. If the user doesn’t select an alternate location or codec for their audiobook file, it defaults to the location and filename of the input book, and the default codec settings.
However, if the user chooses a different output directory, the field needs to:
- get the directory data from the output Browse button
- derive the filename from the input file (the user can edit that if they wish, but the default is the same filename as the input file)
- get the extension from the codec NSPopupBox.
It’s that last part I’m having issues with now.
In my variables, I declared this:
var codecChosen: String = ""
Then I set up my @IBAction like so:
@IBAction func codecSelector(_ sender: Any) {
let codecChoice = codecSelector.titleOfSelectedItem
if codecChoice == ".MP3 (Lossy)" {
codecChosen = ".mp3"
ffmpegCodecArg = "-c:a libmp3lame"
samplingSelector.isEnabled = true
bitrateSelector.isEnabled = true
vbrSwitch.isEnabled = true
qualitySelector.isEnabled = true
stereoSwitch.isEnabled = true
} else if codecChoice == "Flac" {
codecChosen = ".flac"
ffmpegCodecArg = "-c:a flac"
samplingSelector.isEnabled = false
bitrateSelector.isEnabled = false
vbrSwitch.isEnabled = false
qualitySelector.isEnabled = false
stereoSwitch.isEnabled = false
} else {
codecChosen = ".m4b"
ffmpegCodecArg = "-c copy"
samplingSelector.isEnabled = false
bitrateSelector.isEnabled = false
vbrSwitch.isEnabled = false
qualitySelector.isEnabled = false
stereoSwitch.isEnabled = false
}
ffmpegArguments.updateValue("\(ffmpegCodecArg)", forKey: "codecKey")
print(ffmpegArguments)
}
And my @IBAction for the outputBrowse button is set up to (one would hope) derive the file extension from the codecChosen variable, as follows:
// user has option to choose another output directory
@IBAction func outputBrowseClicked(_ sender: Any) {
let outputPanel = NSOpenPanel()
outputPanel.canChooseFiles = false
outputPanel.canChooseDirectories = true
outputPanel.allowsMultipleSelection = false
let userChoice = outputPanel.runModal()
switch userChoice{
case .OK :
if let outputDirectory = outputPanel.url {
if defaultUrl != nil {
let outputFile = defaultUrl.deletingPathExtension()
let outputFilename = outputFile.lastPathComponent
outputPath = outputDirectory.appendingPathComponent(outputFilename)
outputText.stringValue = outputPath.path + "\(codecChosen)"
ffmpegArguments.updateValue("outputText.stringValue", forKey: "outputTextKey")
}
case .cancel :
print("user cancelled")
default:
break
}
}
But for some reason, it’s not happening.
If I choose the codec from the dropdown FIRST, the outputText field (which is populated by outputText.stringValue = outputPath.path + "\(codecChosen)"
) will derive the correct extension, but it won’t change if I change my selection using the codec NSPopupButton.
.
If I don’t use the NSPopup selector first, the outputText field never gets the extension from the codecChosen
variable.
I’ve tried moving the methods related to populating the outputText NSTextField to a separate function instead of leaving them in the outputBrowse @IBAction, because right now it feels like I’m violating the DRY for several lines of code in the @inputBrowse and @outputBrowse actions, but I haven’t gotten that to work yet. But that’s outside the scope of this particular question.
My other issue specifically pertaining to the NSPopupButton is that it doesn’t actually seem to have a default selection. The it appears to, but even though it DISPLAYS the first item as a default, it doesn’t actually run the portion of the method as though that selection has been made. That should happen by default.
I’m not sure how to fix either of those issues. I’ve tried rearranging the order of the code in various ways, but that didn’t seem to make a difference in anything except the order in which my ffmpegArguments dictionary was printed when I checked it.
The NSPopup action is working perfectly in regards to adding the appropriate key/value pairs to the ffmpegArguments dictionary based on what is selected in the popup, but only if I actually select something. Again, it doesn’t register the first item by default.
I suspect this is all related to the order in which things are happening, but I just can’t figure out the proper way to structure it. Specifically, I need to know what command to use in order to get the NSTextField for the output file to update when a new codec is chosen in the NSPopupButton.