如何在ReplayKit Broadcast Extension录屏过程中获取麦克风状态
Great question! There are a couple of reliable ways to track whether the microphone is enabled or disabled during a screen recording with ReplayKit's Broadcast Extension. Here are the most practical approaches:
1. Detect via Microphone Sample Buffers
Since you're already handling audioMic sample buffers, this is the most direct method built into the extension's workflow:
- When the microphone is enabled, you'll receive regular
CMSampleBufferinstances of type.audioMicin yourprocessSampleBuffer(_:with:)method. - When it's disabled, these buffers will stop arriving entirely.
To make this robust (accounting for temporary gaps in buffers), you can add a timeout check:
import ReplayKit class SampleHandler: RPBroadcastSampleHandler { private var isMicEnabled = false private var micTimeoutTimer: Timer? override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) { switch sampleBufferType { case .audioMic: // Reset the timeout timer and mark mic as enabled isMicEnabled = true micTimeoutTimer?.invalidate() micTimeoutTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in self?.isMicEnabled = false } // Process your mic buffer here case .video, .audioApp: // Handle other buffer types @unknown default: break } } }
The 1-second timeout ensures you don't incorrectly mark the mic as disabled if there's a brief gap in buffers.
2. Sync State with Your Host App via App Groups
If you need the initial microphone state (before any buffers arrive) or want to sync with system-level permission changes, use App Groups to share state between your host app and the extension:
Step 1: Configure App Groups
First, enable an App Group for both your host app and Broadcast Extension in Xcode (under Signing & Capabilities > App Groups).
Step 2: Update State from the Host App
The host app can monitor microphone permissions and interruptions, then sync the state to a shared UserDefaults container:
import AVFoundation // In your host app's setup code func setupMicStateTracking() { // Sync initial permission state let sharedDefaults = UserDefaults(suiteName: "com.yourcompany.yourappgroup") switch AVAudioSession.sharedInstance().recordPermission { case .granted: sharedDefaults?.set(true, forKey: "isMicEnabled") case .denied, .undetermined: sharedDefaults?.set(false, forKey: "isMicEnabled") @unknown default: break } // Listen for microphone interruptions (e.g., phone calls) NotificationCenter.default.addObserver(forName: AVAudioSession.interruptionNotification, object: AVAudioSession.sharedInstance(), queue: .main) { notification in guard let userInfo = notification.userInfo, let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt, let type = AVAudioSession.InterruptionType(rawValue: typeValue) else { return } sharedDefaults?.set(type == .ended, forKey: "isMicEnabled") } }
Step 3: Monitor State in the Extension
In your Broadcast Extension, listen for changes to the shared UserDefaults:
class SampleHandler: RPBroadcastSampleHandler { private var isMicEnabled = false private let sharedDefaults = UserDefaults(suiteName: "com.yourcompany.yourappgroup") override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) { // Initialize with the current state isMicEnabled = sharedDefaults?.bool(forKey: "isMicEnabled") ?? false // Listen for future changes NotificationCenter.default.addObserver(forName: UserDefaults.didChangeNotification, object: sharedDefaults, queue: .main) { [weak self] _ in self?.isMicEnabled = self?.sharedDefaults?.bool(forKey: "isMicEnabled") ?? false } } }
Key Notes
- The sample buffer method is great for real-time tracking during recording, while the App Group method covers edge cases like initial state or system interruptions.
- Always test both scenarios: starting recording with mic disabled, and toggling mic state mid-recording.
内容的提问来源于stack exchange,提问作者Ankur Pachauri

