flutter如何实现录音并显示fft动画

在Flutter中如何实现录音功能并实时显示FFT频谱动画?目前我已经尝试使用audioplayerssound_stream插件进行录音,但无法获取到音频的原始数据用于FFT计算。请问有哪些推荐的方法或插件可以同时实现录音和频谱分析?最好能够提供具体的代码示例或实现思路,特别是在处理实时音频数据和可视化方面的方案。

2 回复

使用Flutter录音并显示FFT动画,步骤如下:

  1. 录音:使用flutter_sound库录制音频,获取PCM数据。
  2. FFT处理:通过fft库(如dart_fft)将音频数据转换为频域数据。
  3. 动画绘制:使用CustomPaint绘制频谱柱状图或波形,结合AnimationController实现动态效果。

示例代码片段:

// 录音与FFT处理
final data = await flutterSound.startRecorder();
final fftResult = FFT.transform(data);

// 绘制动画
CustomPaint(
  painter: FFTPainter(fftResult, animation.value),
)

更多关于flutter如何实现录音并显示fft动画的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现录音并显示FFT动画,可以通过以下步骤完成:

1. 添加依赖

pubspec.yaml 中添加:

dependencies:
  flutter_sound: ^X.X.X  # 录音
  mic_stream: ^X.X.X     # 实时音频流
  charts_flutter: ^X.X.X # 图表显示(可选)

运行 flutter pub get

2. 录音和FFT处理

使用 mic_stream 获取实时音频数据,进行FFT计算:

import 'dart:math';
import 'package:mic_stream/mic_stream.dart';

class AudioRecorder {
  Stream<List<int>>? _audioStream;
  
  void startRecording() {
    _audioStream = MicStream.microphone(
      sampleRate: 44100,
      audioFormat: AudioFormat.PCM_16BIT,
    );
  }

  List<double> computeFFT(List<int> audioData) {
    // 转换为浮点数
    List<double> samples = audioData.map((e) => e.toDouble()).toList();
    
    // 应用窗函数(例如汉宁窗)
    for (int i = 0; i < samples.length; i++) {
      samples[i] *= 0.5 * (1 - cos(2 * pi * i / (samples.length - 1)));
    }
    
    // 执行FFT(简化版,实际需使用完整FFT算法)
    List<double> fftResult = [];
    for (int k = 0; k < samples.length ~/ 2; k++) {
      double real = 0.0;
      double imag = 0.0;
      for (int n = 0; n < samples.length; n++) {
        real += samples[n] * cos(2 * pi * k * n / samples.length);
        imag -= samples[n] * sin(2 * pi * k * n / samples.length);
      }
      fftResult.add(sqrt(real * real + imag * imag));
    }
    return fftResult;
  }
}

3. 构建动画UI

使用 StreamBuilder 实时更新波形:

import 'package:flutter/material.dart';

class FFTScreen extends StatefulWidget {
  @override
  _FFTScreenState createState() => _FFTScreenState();
}

class _FFTScreenState extends State<FFTScreen> {
  final AudioRecorder _recorder = AudioRecorder();

  @override
  void initState() {
    super.initState();
    _recorder.startRecording();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<List<int>>(
        stream: _recorder._audioStream,
        builder: (context, snapshot) {
          if (!snapshot.hasData) return CircularProgressIndicator();
          
          List<double> fftData = _recorder.computeFFT(snapshot.data!);
          return CustomPaint(
            painter: FFTPainter(fftData),
            size: Size.infinite,
          );
        },
      ),
    );
  }
}

class FFTPainter extends CustomPainter {
  final List<double> fftData;
  
  FFTPainter(this.fftData);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = 2.0;

    double width = size.width / fftData.length;
    for (int i = 0; i < fftData.length; i++) {
      double x = i * width;
      double height = fftData[i] * 100; // 缩放系数
      canvas.drawLine(
        Offset(x, size.height),
        Offset(x, size.height - height),
        paint,
      );
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

4. 权限配置

Android:在 AndroidManifest.xml 添加:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

iOS:在 Info.plist 添加:

<key>NSMicrophoneUsageDescription</key>
<string>需要麦克风权限进行录音</string>

注意事项:

  1. 实际FFT计算建议使用 fft 包(如 dart:math 复数计算或第三方库)
  2. 调整采样率和缓冲区大小平衡性能
  3. 使用 AnimationController 可实现更流畅的动画效果

此方案提供了基础实现框架,可根据需求优化FFT算法和可视化效果。

回到顶部