fft_recorder_ui 1.0.2 copy "fft_recorder_ui: ^1.0.2" to clipboard
fft_recorder_ui: ^1.0.2 copied to clipboard

audio recorder + FFT bar visualizer Flutter package. Built on top of flutter_recorder.

example/lib/main.dart

import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:fft_recorder_ui/fft_recorder_ui.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(const RecorderExampleApp());
}

class RecorderExampleApp extends StatelessWidget {
  const RecorderExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FFT Recorder UI Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        useMaterial3: true,
      ),
      home: const RecorderExamplePage(),
    );
  }
}

class RecorderExamplePage extends StatefulWidget {
  const RecorderExamplePage({super.key});

  @override
  State<RecorderExamplePage> createState() => _RecorderExamplePageState();
}

class _RecorderExamplePageState extends State<RecorderExamplePage> {
  late final FftRecorderController _controller;
  StreamSubscription<List<double>>? _fftSubscription;
  List<double> _fftData = [];
  late final AudioPlayer _player;
  String? _lastSavedPath;

  @override
  void initState() {
    super.initState();
    _controller = FftRecorderController();
    _controller.requestMicPermission();
    _player = AudioPlayer();
    _fftSubscription = _controller.fftStream.listen((data) {
      if (!mounted) return;
      setState(() {
        _fftData = data;
      });
    });
  }

  @override
  void dispose() {
    _fftSubscription?.cancel();
    _player.dispose();
    _controller.dispose();
    super.dispose();
  }

  Future<void> _startRecording() async {
    final dir = await getApplicationDocumentsDirectory();
    final filePath = '${dir.path}/recording_${DateTime.now().millisecondsSinceEpoch}.wav';
    await _controller.startRecording(filePath: filePath);
    setState(() => _lastSavedPath = filePath);
  }

  Future<void> _playRecording(String path) async {
    await _player.stop();
    await _player.play(DeviceFileSource(path));
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(title: const Text('Recorder + Bar Visualizer')),

      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton(
                  onPressed: _lastSavedPath == null
                      ? null
                      : () {
                          _playRecording(_lastSavedPath!);
                        },
                  child: const Text('재생'),
                ),
                ElevatedButton(
                  onPressed: _controller.recordingStatus.value == RecordingStatus.recording
                      ? null
                      : _startRecording,
                  child: const Text('녹음 시작'),
                ),
                ElevatedButton(
                  onPressed: _controller.recordingStatus.value == RecordingStatus.recording
                      ? _controller.pauseRecording
                      : null,
                  child: const Text('일시정지'),
                ),
                ElevatedButton(
                  onPressed: _controller.recordingStatus.value == RecordingStatus.paused
                      ? _controller.resumeRecording
                      : null,
                  child: const Text('재개'),
                ),
                ElevatedButton(
                  onPressed: _controller.recordingStatus.value == RecordingStatus.idle
                      ? null
                      : () {
                          final path = _controller.stopRecording();
                          setState(() {
                            _lastSavedPath = path ?? _lastSavedPath;
                          });
                          final playPath = path ?? _lastSavedPath;
                          if (playPath != null) {
                            _playRecording(playPath);
                          }
                        },
                  child: const Text('정지'),
                ),
              ],
            ),
            const SizedBox(height: 12),
            if (_lastSavedPath != null)
              Align(
                alignment: Alignment.centerLeft,
                child: Text('Saved: $_lastSavedPath', style: theme.textTheme.bodySmall),
              ),
            const SizedBox(height: 16),
            Container(
              width: 170,
              height: 48,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: Colors.grey.shade900,
                borderRadius: BorderRadius.circular(12),
              ),
              padding: const EdgeInsets.all(12),
              child: BarVisualizer(
                data: _fftData,
                barColor: Colors.white,
                barCount: 9,
                barWidth: 5.33,
                maxHeight: 48,
                spacing: 8,
                emptyText: 'FFT 데이터 대기 중',
              ),
            ),
            const SizedBox(height: 16),
          ],
        ),
      ),
    );
  }
}
9
likes
0
points
362
downloads

Publisher

verified publishernaeileun.dev

Weekly Downloads

audio recorder + FFT bar visualizer Flutter package. Built on top of flutter_recorder.

Homepage

Topics

#audio #recorder #fft #visualization

License

unknown (license)

Dependencies

flutter, flutter_recorder, permission_handler

More

Packages that depend on fft_recorder_ui