You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux平台Flutter语音助手:基于record包实现麦克风静音自动停止录制

基于record包实现Linux Flutter录音的静音检测自动停止方案

由于你只能使用record包,且需要通过振幅检测实现2秒静音自动停止录制,可通过以下步骤实现:

  • 利用record包的音频流回调获取原始PCM数据
    record包提供了onAudio回调,能在录制过程中实时获取未压缩的PCM音频数据——这是计算振幅的核心依据,压缩后的m4a文件大小无法反映音量变化,所以之前监控文件大小的方法无效。

  • 实现振幅计算逻辑
    从PCM数据中提取音频样本,计算当前帧的振幅峰值,以此判断是否处于静音状态。例如,将Uint8List格式的PCM数据转换为int16数组,遍历数组取绝对值的最大值作为当前振幅。

  • 静音计时与停止触发
    维护一个计时器,每当检测到振幅低于设定的静音阈值时启动计时;若期间检测到高于阈值的振幅,则重置计时器。当连续静音时间达到2秒时,调用stop()方法终止录制。

代码示例

import 'package:record/record.dart';
import 'dart:typed_data';
import 'dart:async';

class AudioRecorder {
  final AudioRecorder _recorder = AudioRecorder();
  Timer? _silenceTimer;
  // 静音阈值(需根据实际环境调试调整)
  final int _silenceThreshold = 1000;
  // 静音超时时间(2秒)
  final Duration _silenceTimeout = const Duration(seconds: 2);

  Future<void> startRecording() async {
    if (await _recorder.hasPermission()) {
      await _recorder.start(
        const RecordConfig(
          encoder: AudioEncoder.aacLc, // 对应m4a格式的编码器
          sampleRate: 16000,
          numChannels: 1,
        ),
        path: 'your_recording_path.m4a',
        onAudio: (Uint8List data) {
          // 计算当前音频帧的振幅
          int amplitude = _calculateAmplitude(data);
          
          if (amplitude < _silenceThreshold) {
            _startSilenceTimer();
          } else {
            _resetSilenceTimer();
          }
        },
      );
    }
  }

  int _calculateAmplitude(Uint8List pcmData) {
    // 适配16位单声道、小端格式的PCM数据
    int maxAmplitude = 0;
    for (int i = 0; i < pcmData.length; i += 2) {
      // 将两个字节转为int16格式的音频样本
      int sample = (pcmData[i + 1] << 8) | pcmData[i];
      // 处理有符号数
      if (sample >= 0x8000) {
        sample -= 0x10000;
      }
      int absSample = sample.abs();
      if (absSample > maxAmplitude) {
        maxAmplitude = absSample;
      }
    }
    return maxAmplitude;
  }

  void _startSilenceTimer() {
    if (_silenceTimer?.isActive != true) {
      _silenceTimer = Timer(_silenceTimeout, () async {
        await _recorder.stop();
        _silenceTimer?.cancel();
      });
    }
  }

  void _resetSilenceTimer() {
    _silenceTimer?.cancel();
  }

  Future<void> stopRecording() async {
    _resetSilenceTimer();
    await _recorder.stop();
  }
}

注意事项

  • 静音阈值_silenceThreshold需要根据你的使用场景调试,不同麦克风、环境噪音下数值差异较大。
  • 确保Linux平台上record包的权限配置正确,需提前申请麦克风访问权限。
  • PCM数据的格式(位深、声道数、端序)要和RecordConfig中的设置完全匹配,否则振幅计算会出错。

内容的提问来源于stack exchange,提问作者Leon J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 03:07:49