Swift屏幕录制时如何检测静音/取消静音状态
ReplayKit 屏幕录制时静音/取消静音状态检测方案
RPSystemBroadcastPickerView 本身没有公开API可以直接读取当前录屏的静音状态,你需要在Broadcast Extension的音视频处理回调链路中完成状态检测,具体实现如下:
- 核心检测逻辑放在Broadcast Extension的音频采集回调中
系统录屏控制条上的麦克风静音按钮触发后,麦克风采集链路返回的音频采样数据会全部为0,你可以在processSampleBuffer:withType:回调中通过计算音频电平判断静音状态,参考实现:- (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType { // 仅处理麦克风音频类型的采样数据,如果需要检测App内音频静音可加上RPSampleBufferTypeAudioApp判断 if (sampleBufferType != RPSampleBufferTypeAudioMic) { // 其他类型的视频、App音频buffer走原有处理逻辑即可 return; } CMBlockBufferRef audioBlockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer); if (!audioBlockBuffer) return; size_t bufferLength = 0; char *audioData = NULL; CMBlockBufferGetDataPointer(audioBlockBuffer, 0, NULL, &bufferLength, &audioData); SInt16 *samples = (SInt16 *)audioData; NSUInteger totalSamples = bufferLength / sizeof(SInt16); long totalAmplitude = 0; for (NSUInteger idx = 0; idx < totalSamples; idx++) { totalAmplitude += abs(samples[idx]); } NSInteger averageAmplitude = totalAmplitude / totalSamples; // 阈值可根据业务场景微调,低于阈值即可判定为静音状态 BOOL isMicMuted = averageAmplitude < 8; // 后续做状态同步逻辑 } - 跨进程同步状态到主App
Broadcast Extension和主App属于独立进程,检测到静音状态变化后,你可以通过开启App Group能力后的共享NSUserDefaults,或者跨进程消息通道把状态实时传递给主App即可。
注意事项:不要尝试通过遍历子视图、读取私有属性的方式获取
RPSystemBroadcastPickerView的静音按钮状态,这类实现会在App Store审核时被直接拒绝。如果对检测性能有要求,可以把电平计算的频率控制在每0.3-0.5秒一次,不需要对每一个音频帧都做计算,不会影响状态判断的实时性。
内容的提问来源于stack exchange,提问作者Andrei Yakugov
相关产品推荐
相关产品推荐

