Flutter音频录制插件fl_recorder的使用

Flutter音频录制插件fl_recorder的使用

目前仅支持Android,未来将支持iOS。

在Flutter上使用麦克风录音和系统音频捕获,在Android中默认启用了前台服务,并在Android Q及以上版本添加了常驻消息通知。

使用

/// 初始化
void initialize() {
  FlRecorder().initialize(source: AudioSource.capture);
  FlRecorder().initialize(source: AudioSource.microphone);
}

/// 数据流
void onChanged() {
  FlRecorder().onChanged((AudioDescription audio) {
    debugPrint("毫秒数:${audio.milliseconds}");
  });
}

/// 开始录音
void startRecording() {
  FlRecorder().startRecording();
}

/// 停止录音
void stopRecording() {
  FlRecorder().stopRecording();
}

/// 释放资源
void dispose() {
  FlRecorder().dispose();
}

完整示例Demo

以下是一个完整的示例代码,展示了如何使用fl_recorder插件进行音频录制和播放。

import 'dart:typed_data';

import 'package:fl_extended/fl_extended.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:fl_recorder/fl_recorder.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MaterialApp(
      navigatorKey: FlExtended().navigatorKey,
      debugShowCheckedModeBanner: false,
      home: Scaffold(
          appBar: AppBar(title: const Text('FlRecorder 插件示例')),
          body: const Padding(
            padding: EdgeInsets.all(12),
            child: SingleChildScrollView(child: _App()),
          ))));
}

class _App extends StatefulWidget {
  const _App();

  [@override](/user/override)
  State<_App> createState() => _AppState();
}

class _AppState extends State<_App> {
  final recording = FlRecorder();
  List<int> byte = [];
  List<double> amplitude = [];

  String text = '';

  [@override](/user/override)
  void initState() {
    super.initState();
    addPostFrameCallback((_) {
      recording.onChanged((AudioDescribe audio) {
        byte.addAll(audio.byte);
        amplitude.addAll(audio.toAmplitude);
        text = ("正在录制:${recording.isRecording}\n"
            "毫秒数:${Duration(milliseconds: audio.milliseconds)}\n"
            "字节数:${byte.length}\n"
            "振幅:${amplitude.length}");
        debugPrint(text);
        if (mounted) setState(() {});
      });
      recording.onStateChanged((bool isRecording) {
        debugPrint("是否正在录制:$isRecording");
      });
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(children: [
      Container(
          height: 140,
          width: double.infinity,
          alignment: Alignment.center,
          padding: const EdgeInsets.all(10),
          decoration: BoxDecoration(
              shape: BoxShape.rectangle,
              color: Colors.black12.withValues(alpha: 0.1)),
          child: Text(text)),
      Wrap(runSpacing: 10, spacing: 10, children: [
        ElevatedText(
            text: '请求忽略电池优化',
            onPressed: () async {
              final result = await recording.requestIgnoreBatteryOptimizations();
              text = "请求忽略电池优化 : $result";
              setState(() {});
            }),
        ElevatedText(
            text: '初始化(AudioSource.capture)',
            onPressed: () async {
              final result = await recording.initialize(source: AudioSource.capture);
              text = "初始化(AudioSource.capture) : $result";
              setState(() {});
            }),
        ElevatedText(
            text: '初始化(AudioSource.microphone)',
            onPressed: () async {
              final result = await recording.initialize(source: AudioSource.microphone);
              text = "初始化(AudioSource.microphone) : $result";
              setState(() {});
            }),
        ElevatedText(
            text: '开始录制',
            onPressed: () async {
              final result = await recording.startRecording();
              text = "开始录制 : $result";
              debugPrint(text);
              setState(() {});
            }),
        ElevatedText(
            text: '停止录制',
            onPressed: () async {
              final result = await recording.stopRecording();
              text = "停止录制 : $result";
              debugPrint(text);
              setState(() {});
            }),
        ElevatedText(
            text: '释放资源',
            onPressed: () async {
              final result = await recording.dispose();
              text = "释放资源 : $result";
              setState(() {});
            }),
        ElevatedText(text: '播放录音数据', onPressed: playRecordData),
      ])
    ]);
  }

  final player = FlutterSoundPlayer();

  void playRecordData() async {
    if (byte.isEmpty) {
      showToast('请先录制数据');
      return;
    }
    showToast('开始播放录音');
    await player.openPlayer();
    player.startPlayer(
        codec: Codec.pcm16,
        fromDataBuffer: Uint8List.fromList(byte),
        whenFinished: () {
          showToast('播放完毕');
          player.stopPlayer();
          player.dispositionStream();
        });
  }
}

class Partition extends StatelessWidget {
  const Partition(this.title, {super.key, this.onTap});

  final String title;
  final GestureTapCallback? onTap;

  [@override](/user/override)
  Widget build(BuildContext context) => Universal(
      onTap: onTap,
      width: double.infinity,
      color: Colors.grey.withValues(alpha: 0.2),
      alignment: Alignment.center,
      padding: const EdgeInsets.symmetric(vertical: 10),
      margin: const EdgeInsets.symmetric(vertical: 20),
      child: BText(title, fontWeight: FontWeight.bold));
}

class ElevatedText extends StatelessWidget {
  const ElevatedText({super.key, required this.text, required this.onPressed});

  final String text;
  final VoidCallback onPressed;

  [@override](/user/override)
  Widget build(BuildContext context) =>
      ElevatedButton(onPressed: onPressed, child: Text(text));
}

更多关于Flutter音频录制插件fl_recorder的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter音频录制插件fl_recorder的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


fl_recorder 是一个用于在 Flutter 应用中录制音频的插件。该插件提供了简单的 API,允许你在应用中轻松地开始、暂停、恢复和停止音频录制。以下是如何在 Flutter 项目中使用 fl_recorder 插件的详细步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 fl_recorder 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  fl_recorder: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 初始化 FlRecorder

在需要使用 fl_recorder 的地方,首先需要初始化 FlRecorder 对象:

import 'package:fl_recorder/fl_recorder.dart';

final flRecorder = FlRecorder();

3. 请求录音权限

在开始录音之前,你需要请求录音权限。可以使用 permission_handler 插件来请求权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestRecordingPermission() async {
  final status = await Permission.microphone.request();
  if (status != PermissionStatus.granted) {
    throw RecordingPermissionException('Microphone permission not granted');
  }
}

4. 开始录音

你可以使用 start 方法来开始录音:

Future<void> startRecording() async {
  await requestRecordingPermission();
  await flRecorder.start();
}

5. 暂停和恢复录音

你可以使用 pauseresume 方法来暂停和恢复录音:

Future<void> pauseRecording() async {
  await flRecorder.pause();
}

Future<void> resumeRecording() async {
  await flRecorder.resume();
}

6. 停止录音并保存

你可以使用 stop 方法来停止录音并保存录音文件:

Future<String?> stopRecording() async {
  final path = await flRecorder.stop();
  return path; // 返回录音文件的路径
}

7. 监听录音状态

你可以通过 onStateChanged 流来监听录音状态的变化:

flRecorder.onStateChanged.listen((state) {
  print('Recording state changed to: $state');
});

8. 完整示例

以下是一个完整的示例,展示了如何使用 fl_recorder 插件进行音频录制:

import 'package:flutter/material.dart';
import 'package:fl_recorder/fl_recorder.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AudioRecorderDemo(),
    );
  }
}

class AudioRecorderDemo extends StatefulWidget {
  [@override](/user/override)
  _AudioRecorderDemoState createState() => _AudioRecorderDemoState();
}

class _AudioRecorderDemoState extends State<AudioRecorderDemo> {
  final flRecorder = FlRecorder();
  String? _recordingPath;

  Future<void> requestRecordingPermission() async {
    final status = await Permission.microphone.request();
    if (status != PermissionStatus.granted) {
      throw Exception('Microphone permission not granted');
    }
  }

  Future<void> startRecording() async {
    await requestRecordingPermission();
    await flRecorder.start();
  }

  Future<void> pauseRecording() async {
    await flRecorder.pause();
  }

  Future<void> resumeRecording() async {
    await flRecorder.resume();
  }

  Future<void> stopRecording() async {
    final path = await flRecorder.stop();
    setState(() {
      _recordingPath = path;
    });
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    flRecorder.onStateChanged.listen((state) {
      print('Recording state changed to: $state');
    });
  }

  [@override](/user/override)
  void dispose() {
    flRecorder.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Audio Recorder'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: startRecording,
              child: Text('Start Recording'),
            ),
            ElevatedButton(
              onPressed: pauseRecording,
              child: Text('Pause Recording'),
            ),
            ElevatedButton(
              onPressed: resumeRecording,
              child: Text('Resume Recording'),
            ),
            ElevatedButton(
              onPressed: stopRecording,
              child: Text('Stop Recording'),
            ),
            if (_recordingPath != null)
              Text('Recording saved at: $_recordingPath'),
          ],
        ),
      ),
    );
  }
}
回到顶部