
The Problem: Too Many Clicks to Switch Audio Inputs If you work with external audio interfaces (like Universal Audio) or virtual routing software (like BlackHole), switching audio devices on macOS usually means navigating through System Settings or clicking through the Control Center menu every single time. When jumping between record mode and monitoring, you want a single button on your Dock that toggles your setup instantly—complete with visual feedback and custom icons. The Solution: A Lightweight Dock App By combining the lightweight open-source tool `switchaudio-osx` with a short Zsh script wrapped in Automator, you can create a dedicated Dock button that toggles between **BlackHole** and your **hardware outputs**. ### Step 1: Install `switchaudio-osx` Open Terminal and install the utility using Homebrew: ```bash brew install switchaudio-osx ``` Step 2: Build the Script in Automator 1. Launch **Automator** on your Mac and create a **New Application**. 2. Add the **Run Shell Script** action. 3. Set the shell to `/bin/zsh`. 4. Paste the script below: ```zsh #!/bin/zsh export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" CURRENT_DEVICE=$(SwitchAudioSource -c) BLACKHOLE="BlackHole 2ch" UNIVERSAL_AUDIO="Universal Audio Thunderbolt" MAC_SPEAKERS="MacBook Pro Speakers" if [[ "$CURRENT_DEVICE" == *"$BLACKHOLE"* ]]; then if SwitchAudioSource -a | grep -q "$UNIVERSAL_AUDIO"; then SwitchAudioSource -s "$UNIVERSAL_AUDIO" afplay /System/Library/Sounds/Pop.aiff else SwitchAudioSource -s "$MAC_SPEAKERS" afplay /System/Library/Sounds/Pop.aiff fi else SwitchAudioSource -s "$BLACKHOLE" afplay /System/Library/Sounds/Tink.aiff fi ``` Step 3: Save & Add Custom Icon 1. Save the file as **Audio Switcher.app** inside your `/Applications` folder. 2. Right-click the app in Finder and select **Get Info** (`Cmd + I`). 3. Drag your custom icon image directly onto the small icon preview in the top-left corner. 4. Drag the app down into your **Mac Dock**. --- How It Works * **Automatic Failover:** If your audio interface (Universal Audio) is unplugged, it seamlessly falls back to your built-in Mac speakers. * **Audio Alerts:** Plays system sounds (`Tink` and `Pop`) to give instant audio confirmation of which profile is active. * **Zero Overhead:** Runs natively in the background without needing menu bar bloatware. Another script: # A One-Liner to Add "Convert to MP3 320kbps" to macOS Finder If you’re working with audio files on macOS, you’ve probably noticed that the built-in *Encode Selected Audio Files* Quick Action forces you into AAC (`.m4a`) or Apple Lossless. If you just want a standard 320kbps `.mp3` directly in your right-click menu—without downloading bloated converter apps—here is a production-ready script to install it. --- ### Prerequisites You only need `ffmpeg`. If you don't have it installed yet: ```bash brew install ffmpeg /bin/zsh -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh](https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh))" 2>/dev/null || true # 1. Detect environment and ensure FFmpeg is available if ! command -v ffmpeg &>/dev/null && ! [[ -f "/opt/homebrew/bin/ffmpeg" || -f "/usr/local/bin/ffmpeg" ]]; then echo "Installing FFmpeg via Homebrew..." if ! command -v brew &>/dev/null; then eval "$(/opt/homebrew/bin/brew shellenv 2>/dev/null || /usr/local/bin/brew shellenv 2>/dev/null)" fi brew install ffmpeg fi # 2. Define target pathing WORKFLOW_DIR="$HOME/Library/Services" WORKFLOW_PATH="$WORKFLOW_DIR/Convert to MP3 320.workflow" # 3. Clean stale instances and build bundle directories rm -rf "$WORKFLOW_PATH" 2>/dev/null mkdir -p "$WORKFLOW_PATH/Contents" # 4. Write Info.plist (Tells macOS Services about the bundle) cat << 'EOF' > "$WORKFLOW_PATH/Contents/Info.plist" <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "[http://www.apple.com/DTDs/PropertyList-1.0.dtd](http://www.apple.com/DTDs/PropertyList-1.0.dtd)"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleGetInfoString</key> <string>Convert to MP3 320</string> <key>CFBundleIdentifier</key> <string>com.user.action.ConvertToMP3320</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>Convert to MP3 320</string> <key>CFBundlePackageType</key> <string>BNDL</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>1.0</string> <key>NSServices</key> <array> <dict> <key>NSComponent</key> <string>Finder</string> <key>NSMenuItem</key> <dict> <key>default</key> <string>Convert to MP3 320</string> </dict> <key>NSMessage</key> <string>runWorkflowAsService</string> <key>NSSendFileTypes</key> <array> <string>public.item</string> </array> </dict> </array> </dict> </plist> EOF # 5. Write document.wflow (Execution logic with PATH auto-resolution) cat << 'EOF' > "$WORKFLOW_PATH/Contents/document.wflow" <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "[http://www.apple.com/DTDs/PropertyList-1.0.dtd](http://www.apple.com/DTDs/PropertyList-1.0.dtd)"> <plist version="1.0"> <dict> <key>AMApplicationBuild</key> <string>523</string> <key>AMApplicationVersion</key> <string>2.10</string> <key>AMDocumentVersion</key> <string>2</string> <key>actions</key> <array> <dict> <key>action</key> <dict> <key>AMActionVersion</key> <string>1.0.2</string> <key>AMParameterProperties</key> <dict> <key>COMMAND_STRING</key> <dict/> <key>CheckedForUserDefaultShell</key> <dict/> <key>inputMethod</key> <dict/> <key>shell</key> <dict/> <key>source</key> <dict/> </dict> <key>AMProvides</key> <dict> <key>Container</key> <string>List</string> <key>Types</key> <array> <string>com.apple.cocoa.path</string> </array> </dict> <key>ActionBundlePath</key> <string>/System/Library/Automator/Run Shell Script.action</string> <key>ActionName</key> <string>Run Shell Script</string> <key>ActionParameters</key> <dict> <key>COMMAND_STRING</key> <string># Ensure system & brew binary paths are searched export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" # Locate FFmpeg executable dynamically if command -v ffmpeg &>/dev/null; then FFMPEG="ffmpeg" elif [[ -f "/opt/homebrew/bin/ffmpeg" ]]; then FFMPEG="/opt/homebrew/bin/ffmpeg" elif [[ -f "/usr/local/bin/ffmpeg" ]]; then FFMPEG="/usr/local/bin/ffmpeg" fi for f in "$@"; do out_file="${f%.*}.mp3" "$FFMPEG" -i "$f" -vn -c:a libmp3lame -b:a 320k -ar 44100 -ac 2 "$out_file" -y done</string> <key>CheckedForUserDefaultShell</key> <true/> <key>inputMethod</key> <integer>1</integer> <key>shell</key> <string>/bin/zsh</string> <key>source</key> <string></string> </dict> <key>BundleIdentifier</key> <string>com.apple.RunShellScript</string> <key>CFBundleVersion</key> <string>1.0.2</string> <key>CanShowSelectedItemsWhenRun</key> <false/> <key>CanShowWhenRun</key> <true/> <key>Category</key> <array> <string>AMCategoryUtilities</string> </array> <key>Class Name</key> <string>RunShellScriptAction</string> <key>InputUUID</key> <string>8A9D87E6-4552-4C67-A1C8-9250D8CD52AB</string> <key>Keywords</key> <array> <string>Shell</string> <string>Script</string> <string>Command</string> <string>Run</string> <string>Unix</string> </array> <key>OutputUUID</key> <string>75C0FA9C-7FEE-4EA3-83E0-FDF52E633C1D</string> <key>UUID</key> <string>C5186A41-7A3D-4A2D-A480-F5E242B6A3BB</string> </dict> </dict> </array> <key>connectors</key> <dict/> <key>workflowMetaData</key> <dict> <key>applicationBundleID</key> <string>com.apple.finder</string> <key>applicationBundleIDsByPath</key> <dict> <key>/System/Library/CoreServices/Finder.app</key> <string>com.apple.finder</string> </dict> <key>applicationPath</key> <string>/System/Library/CoreServices/Finder.app</string> <key>applicationPaths</key> <array> <string>/System/Library/CoreServices/Finder.app</string> </array> <key>inputTypeIdentifier</key> <string>com.apple.Automator.fileSystemObject</string> <key>outputTypeIdentifier</key> <string>com.apple.Automator.nothing</string> <key>presentationMode</key> <integer>15</integer> <key>serviceApplicationBundleID</key> <string>com.apple.finder</string> <key>serviceApplicationPath</key> <string>/System/Library/CoreServices/Finder.app</string> <key>serviceInputTypeIdentifier</key> <string>com.apple.Automator.fileSystemObject</string> <key>serviceOutputTypeIdentifier</key> <string>com.apple.Automator.nothing</string> <key>serviceProcessesInput</key> <false/> <key>useAutomaticInputType</key> <false/> <key>workflowTypeIdentifier</key> <string>com.apple.Automator.servicesMenu</string> </dict> </dict> </plist> EOF # 6. Unquarantine bundle and re-index LaunchServices xattr -d com.apple.quarantine "$WORKFLOW_PATH" 2>/dev/null || true /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "$WORKFLOW_PATH" 2>/dev/null || true # 7. Restart Finder to load Quick Action menu item killall Finder 2>/dev/null echo "Setup Complete: 'Convert to MP3 320' Quick Action successfully installed."