Flutter音频录制插件mc_flutter_recorder的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter音频录制插件mc_flutter_recorder的使用

mc_flutter_recorder 是一个用于在 Flutter 应用中进行音频录制的插件。它不仅支持基本的录音功能,还支持音频中断策略控制和其他异常处理。目前,该插件仅支持 WAV 格式。

使用方法

初始化和权限请求

在开始录音之前,你需要先请求麦克风权限,并初始化录音器。

import 'package:mc_flutter_recorder/mc_flutter_recorder.dart';
import 'package:permission_handler/permission_handler.dart';

final _mcRecorderPlugin = McFlutterRecorder();

// 请求麦克风权限
final granted = await Permission.microphone.isGranted;
if (!granted) {
  await Permission.microphone.request();
}

// 初始化录音器
_mcRecorderPlugin.init(RecorderConfig(
    filePath: path,
    sampleRate: 16000,
    channel: RecorderChannel.mono,
    pcmBitRate: PcmBitRate.pcm16Bit,
    period: const Duration(milliseconds: 100),
    interruptedBehavior: InterruptedBehavior.stop,
    freeDisk: 100,
));

开始、暂停、恢复和停止录音

你可以通过以下方法来控制录音过程:

// 开始录音
await _mcRecorderPlugin.start();

// 暂停录音
await _mcRecorderPlugin.pause();

// 恢复录音
await _mcRecorderPlugin.resume();

// 停止录音
await _mcRecorderPlugin.stop();

// 关闭录音器
await _mcRecorderPlugin.close();

监听录音状态、信息和错误

你可以监听录音的状态、信息和错误流来获取实时反馈。

_mcRecorderPlugin.recordStateStream.listen((state) {
  // 处理录音状态变化
});

_mcRecorderPlugin.recordInfoStream.listen((info) {
  // 处理录音信息
});

_mcRecorderPlugin.recordErrorStream.listen((error) {
  // 处理录音错误
});

示例代码

以下是完整的示例代码,展示了如何使用 mc_flutter_recorder 插件进行音频录制。

import 'package:flutter/material.dart';
import 'package:mc_flutter_recorder/mc_flutter_recorder.dart';
import 'package:mc_flutter_recorder/recorder_config.dart';
import 'package:mc_flutter_recorder/recorder_exception.dart';
import 'dart:async';
import 'package:mc_flutter_recorder/recorder_info.dart';
import 'package:mc_flutter_recorder/recorder_state.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _mcRecorderPlugin = McFlutterRecorder();

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('MCFlutterRecorder'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              StreamBuilder<RecorderInfo>(
                stream: _mcRecorderPlugin.recordInfoStream,
                builder: (context, snapshot) {
                  var db = snapshot.data?.db ?? 0;
                  return Text("duration: ${snapshot.data?.duration}\ndb: ${db.roundToDouble()}");
                },
              ),
              StreamBuilder<RecorderState>(
                stream: _mcRecorderPlugin.recordStateStream,
                builder: (context, snapshot) {
                  return Text("state: ${snapshot.data?.name}");
                },
              ),
              ErrorWidget(stream: _mcRecorderPlugin.recordErrorStream),
              Wrap(
                children: [
                  TextButton(
                      onPressed: () async {
                        final granted = await Permission.microphone.isGranted;
                        if (!granted) {
                          await Permission.microphone.request();
                        }
                      },
                      child: const Text("请求权限")),
                  TextButton(
                      onPressed: () async {
                        final dir = (await getApplicationDocumentsDirectory()).path;
                        final path = '$dir/example.wav';
                        setState(() {
                          _mcRecorderPlugin.init(RecorderConfig(
                            filePath: path,
                            sampleRate: 16000,
                            channel: RecorderChannel.mono,
                            pcmBitRate: PcmBitRate.pcm16Bit,
                            period: const Duration(milliseconds: 100),
                            interruptedBehavior: InterruptedBehavior.stop,
                            freeDisk: 100,
                          ));
                        });
                      },
                      child: const Text("初始化")),
                  TextButton(
                      onPressed: () {
                        setState(() {
                          _mcRecorderPlugin.start();
                        });
                      },
                      child: const Text("开始")),
                  TextButton(
                      onPressed: () {
                        setState(() {
                          _mcRecorderPlugin.pause();
                        });
                      },
                      child: const Text("暂停")),
                  TextButton(
                      onPressed: () {
                        setState(() {
                          _mcRecorderPlugin.resume();
                        });
                      },
                      child: const Text("恢复")),
                  TextButton(
                      onPressed: () {
                        setState(() {
                          _mcRecorderPlugin.stop();
                        });
                      },
                      child: const Text("停止")),
                  TextButton(
                      onPressed: () {
                        setState(() {
                          _mcRecorderPlugin.close();
                        });
                      },
                      child: const Text("关闭")),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class ErrorWidget extends StatefulWidget {
  final Stream<RecorderException> stream;

  const ErrorWidget({Key? key, required this.stream}) : super(key: key);

  @override
  State<ErrorWidget> createState() => _ErrorWidgetState();
}

class _ErrorWidgetState extends State<ErrorWidget> {
  StreamSubscription? _streamSubscription;

  @override
  void initState() {
    super.initState();
    _streamSubscription?.cancel();
    _streamSubscription = null;
    _streamSubscription = widget.stream.listen((event) {
      final msg = "error type: ${event.errorType}, message: ${event.message}";
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
    });
  }

  @override
  void dispose() {
    _streamSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const SizedBox.shrink();
  }
}

Android 配置

确保在 android/app/build.gradle 文件中设置 compileSdkVersion 为 33:

android {
    compileSdkVersion 33
}

iOS 配置

Info.plist 文件中添加麦克风权限描述:

<key>NSMicrophoneUsageDescription</key>
<string>可以使用您的麦克风吗?</string>

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

1 回复

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


当然,以下是如何在Flutter项目中使用mc_flutter_recorder插件进行音频录制的示例代码。这个插件允许你在Flutter应用中实现音频录制功能。

首先,确保你已经在pubspec.yaml文件中添加了mc_flutter_recorder依赖:

dependencies:
  flutter:
    sdk: flutter
  mc_flutter_recorder: ^最新版本号 # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

1. 导入插件

在你的Dart文件中导入mc_flutter_recorder

import 'package:mc_flutter_recorder/mc_flutter_recorder.dart';

2. 配置权限

AndroidManifest.xml中添加录音权限:

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

在iOS项目中,你需要在Info.plist中添加以下权限请求:

<key>NSMicrophoneUsageDescription</key>
<string>App需要访问麦克风来录制音频</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App需要访问照片库来保存音频文件</string>

3. 请求权限

在你的Flutter应用中请求必要的权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestPermissions() async {
  Map<Permission, PermissionStatus> statuses = await Permission.request([
    Permission.microphone,
    Permission.storage,
  ]);

  if (statuses[Permission.microphone] != PermissionStatus.granted ||
      statuses[Permission.storage] != PermissionStatus.granted) {
    // 处理权限未授予的情况
  }
}

4. 初始化并启动录制

在你的Flutter组件中,初始化McFlutterRecorder并启动录制:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AudioRecorderScreen(),
    );
  }
}

class AudioRecorderScreen extends StatefulWidget {
  @override
  _AudioRecorderScreenState createState() => _AudioRecorderScreenState();
}

class _AudioRecorderScreenState extends State<AudioRecorderScreen> {
  late McFlutterRecorder mcFlutterRecorder;
  bool isRecording = false;

  @override
  void initState() {
    super.initState();
    mcFlutterRecorder = McFlutterRecorder();
    requestPermissions();
  }

  Future<void> startRecording() async {
    setState(() {
      isRecording = true;
    });

    String? filePath = await mcFlutterRecorder.startRecorder(
      filePath: 'your_desired_path_here', // 设置录音文件保存路径
      audioSource: AudioSource.mic,
      audioFormat: AudioFormat.mpeg4aac,
      encoderSpecificConfig: Map(),
      outputFormat: OutputFormat.threeGpp,
    );

    if (filePath != null) {
      print('Recording started. File path: $filePath');
    } else {
      print('Failed to start recording.');
    }
  }

  Future<void> stopRecording() async {
    setState(() {
      isRecording = false;
    });

    String? filePath = await mcFlutterRecorder.stopRecorder();

    if (filePath != null) {
      print('Recording stopped. File path: $filePath');
    } else {
      print('Failed to stop recording.');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Audio Recorder'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: isRecording ? stopRecording : startRecording,
              child: Text(isRecording ? 'Stop Recording' : 'Start Recording'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 路径管理:确保你提供的路径是有效的,并且应用有权限写入该路径。
  2. 错误处理:在实际应用中,你需要添加更多的错误处理逻辑,比如处理录音失败的情况。
  3. 权限请求结果:在请求权限后,根据用户的选择进行相应的处理。

这个示例展示了如何使用mc_flutter_recorder插件进行基本的音频录制操作。你可以根据实际需求进行进一步的扩展和优化。

回到顶部