From ce5ec50254a57340d102240629e1b195ccf78d2c Mon Sep 17 00:00:00 2001 From: Beingpax Date: Sun, 11 May 2025 10:34:34 +0545 Subject: [PATCH] Respect system mute state when recording --- VoiceInk/MediaController.swift | 41 ++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/VoiceInk/MediaController.swift b/VoiceInk/MediaController.swift index de67e6e..2685e0e 100644 --- a/VoiceInk/MediaController.swift +++ b/VoiceInk/MediaController.swift @@ -2,11 +2,13 @@ import AppKit import Combine import Foundation import SwiftUI +import CoreAudio /// Controls system audio management during recording class MediaController: ObservableObject { static let shared = MediaController() private var didMuteAudio = false + private var wasAudioMutedBeforeRecording = false @Published var isSystemMuteEnabled: Bool = UserDefaults.standard.bool(forKey: "isSystemMuteEnabled") { didSet { @@ -21,10 +23,41 @@ class MediaController: ObservableObject { } } + /// Checks if the system audio is currently muted using AppleScript + private func isSystemAudioMuted() -> Bool { + let pipe = Pipe() + let task = Process() + task.launchPath = "/usr/bin/osascript" + task.arguments = ["-e", "output muted of (get volume settings)"] + task.standardOutput = pipe + + do { + try task.run() + task.waitUntilExit() + let data = pipe.fileHandleForReading.readDataToEndOfFile() + if let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) { + return output == "true" + } + } catch { + // Silently fail + } + + return false + } + /// Mutes system audio during recording func muteSystemAudio() async -> Bool { guard isSystemMuteEnabled else { return false } + // First check if audio is already muted + wasAudioMutedBeforeRecording = isSystemAudioMuted() + + // If already muted, no need to mute it again + if wasAudioMutedBeforeRecording { + return true + } + + // Otherwise mute the audio let success = executeAppleScript(command: "set volume with output muted") didMuteAudio = success return success @@ -32,9 +65,13 @@ class MediaController: ObservableObject { /// Restores system audio after recording func unmuteSystemAudio() async { - guard isSystemMuteEnabled, didMuteAudio else { return } + guard isSystemMuteEnabled else { return } + + // Only unmute if we actually muted it (and it wasn't already muted) + if didMuteAudio && !wasAudioMutedBeforeRecording { + _ = executeAppleScript(command: "set volume without output muted") + } - _ = executeAppleScript(command: "set volume without output muted") didMuteAudio = false }