插件介绍

Flutter TPC Record 是一个基于 record 开发的音频录制插件,专为在鸿蒙系统上使用 Flutter 框架的开发者设计。该插件提供了简洁易用的 API,支持在鸿蒙设备上进行高质量的音频录制。

主要功能

  • 多种音频编码格式支持:包括 AAC-LC、AAC-ELD、AAC-HE 等多种音频编码格式
  • 灵活的录制配置:支持自定义采样率、比特率、声道数等参数
  • 实时振幅监听:可以实时获取录制音频的振幅信息,用于实现可视化效果
  • 录制状态管理:支持开始、暂停、恢复、停止等录制操作
  • 设备列表获取:可以获取设备上可用的音频输入设备
  • 权限管理:自动处理音频录制权限请求
  • 流录制支持:除了文件录制外,还支持直接获取录制的音频流数据

鸿蒙系统适配特点

  • 基于鸿蒙系统原生音频 API 实现,性能优异
  • 支持鸿蒙系统特有的音频录制功能
  • 与 Flutter 鸿蒙插件体系完美集成
  • 提供了完整的示例代码,方便开发者快速上手

安装与配置

安装方式

由于这是一个自定义修改版本,需要通过 Git 方式引入依赖。进入到 Flutter 工程目录并在 pubspec.yaml 中添加以下依赖:

...
dependencies:
  record:
    git:
      url: https://gitcode.com/openharmony-sig/fluttertpc_record.git
      path: record

...

添加依赖后,执行以下命令获取包:

flutter pub get

鸿蒙系统配置

在鸿蒙系统上使用该插件,需要确保工程已经配置了鸿蒙插件环境。具体配置步骤如下:

  1. 确保 Flutter 工程已经支持鸿蒙系统
  2. 插件会自动在鸿蒙系统上注册,无需额外配置
  3. 如果需要手动配置,可以查看 example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets 文件了解插件注册方式

权限配置

在使用音频录制功能前,需要确保应用已经获得了音频录制权限。插件会自动处理权限请求,但建议在应用的配置文件中明确声明所需权限:

<!-- 在鸿蒙系统的配置文件中添加以下权限 -->
<uses-permission android:name="ohos.permission.MICROPHONE"/>

API使用

导入包

在使用插件前,需要先导入包:

import 'package:record/record.dart';

创建AudioRecorder实例

首先需要创建AudioRecorder实例:

final audioRecorder = AudioRecorder();

权限检查

在开始录制前,建议先检查是否有音频录制权限:

if (await audioRecorder.hasPermission()) {
  // 有权限,可以开始录制
} else {
  // 没有权限,需要提示用户
}

开始录制

开始录制音频文件,需要指定输出路径和录制配置:

// 配置录制参数
const config = RecordConfig(
  encoder: AudioEncoder.aacLc, // 使用AAC-LC编码
  bitRate: 128000, // 比特率128kbps
  sampleRate: 44100, // 采样率44.1kHz
  numChannels: 2, // 双声道
);

// 开始录制到文件
await audioRecorder.start(config, path: '/path/to/output.mp3');

流录制

除了录制到文件,还可以直接获取音频流:

// 开始流录制
final stream = await audioRecorder.startStream(config);

// 监听流数据
stream.listen((data) {
  // 处理音频数据
});

暂停/恢复录制

可以暂停和恢复录制:

// 暂停录制
await audioRecorder.pause();

// 恢复录制
await audioRecorder.resume();

停止录制

停止录制并获取输出路径:

final path = await audioRecorder.stop();
if (path != null) {
  print('录制完成,文件路径:$path');
}

监听录制状态

可以监听录制状态的变化:

StreamSubscription<RecordState>? recordSub;

// 监听录制状态
recordSub = audioRecorder.onStateChanged().listen((recordState) {
  switch (recordState) {
    case RecordState.record:
      print('正在录制');
      break;
    case RecordState.pause:
      print('录制已暂停');
      break;
    case RecordState.stop:
      print('录制已停止');
      break;
  }
});

监听振幅变化

可以实时监听录制音频的振幅,用于实现可视化效果:

StreamSubscription<Amplitude>? amplitudeSub;

// 每300毫秒获取一次振幅
amplitudeSub = audioRecorder
    .onAmplitudeChanged(const Duration(milliseconds: 300))
    .listen((amplitude) {
  print('当前振幅:${amplitude.current},最大振幅:${amplitude.max}');
  // 可以使用振幅数据实现波形图等可视化效果
});

获取设备列表

可以获取设备上可用的音频输入设备:

final devices = await audioRecorder.listInputDevices();
devices.forEach((device) {
  print('设备ID:${device.id},设备名称:${device.label}');
});

检查编码器支持情况

可以检查特定编码器是否支持:

const encoder = AudioEncoder.aacLc;
final isSupported = await audioRecorder.isEncoderSupported(encoder);
print('${encoder.name} 编码器支持:$isSupported');

获取当前振幅

可以直接获取当前的振幅信息:

final amplitude = await audioRecorder.getAmplitude();
print('当前振幅:${amplitude.current},最大振幅:${amplitude.max}');

检查录制状态

可以检查当前的录制状态:

// 检查是否正在录制(包括暂停状态)
final isRecording = await audioRecorder.isRecording();

// 检查是否处于暂停状态
final isPaused = await audioRecorder.isPaused();

释放资源

使用完毕后,记得释放资源:

// 取消订阅
recordSub?.cancel();
amplitudeSub?.cancel();

// 释放资源
audioRecorder.dispose();

完整示例

以下是一个完整的音频录制示例:

import 'package:flutter/material.dart';
import 'package:record/record.dart';

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

  
  State<AudioRecorderExample> createState() => _AudioRecorderExampleState();
}

class _AudioRecorderExampleState extends State<AudioRecorderExample> {
  late final AudioRecorder _audioRecorder;
  StreamSubscription<RecordState>? _recordSub;
  StreamSubscription<Amplitude>? _amplitudeSub;
  RecordState _recordState = RecordState.stop;
  Amplitude? _amplitude;
  String? _recordPath;

  
  void initState() {
    super.initState();
    _audioRecorder = AudioRecorder();

    // 监听录制状态
    _recordSub = _audioRecorder.onStateChanged().listen((state) {
      setState(() {
        _recordState = state;
      });
    });

    // 监听振幅变化
    _amplitudeSub = _audioRecorder
        .onAmplitudeChanged(const Duration(milliseconds: 300))
        .listen((amp) {
      setState(() {
        _amplitude = amp;
      });
    });
  }

  Future<void> _startRecording() async {
    if (await _audioRecorder.hasPermission()) {
      // 配置录制参数
      const config = RecordConfig(
        encoder: AudioEncoder.aacLc,
        bitRate: 128000,
        sampleRate: 44100,
        numChannels: 2,
      );

      // 开始录制
      await _audioRecorder.start(config, path: '/path/to/record.mp3');
    }
  }

  Future<void> _stopRecording() async {
    final path = await _audioRecorder.stop();
    if (path != null) {
      setState(() {
        _recordPath = path;
      });
    }
  }

  Future<void> _pauseRecording() async {
    await _audioRecorder.pause();
  }

  Future<void> _resumeRecording() async {
    await _audioRecorder.resume();
  }

  
  void dispose() {
    // 释放资源
    _recordSub?.cancel();
    _amplitudeSub?.cancel();
    _audioRecorder.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('音频录制示例')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 录制控制按钮
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButton(
                  icon: Icon(_recordState != RecordState.stop ? Icons.stop : Icons.mic),
                  onPressed: _recordState != RecordState.stop ? _stopRecording : _startRecording,
                ),
                if (_recordState != RecordState.stop) ...[
                  IconButton(
                    icon: Icon(_recordState == RecordState.pause ? Icons.play_arrow : Icons.pause),
                    onPressed: _recordState == RecordState.pause ? _resumeRecording : _pauseRecording,
                  ),
                ],
              ],
            ),

            // 振幅显示
            if (_amplitude != null) ...[
              const SizedBox(height: 20),
              Text('当前振幅:${_amplitude?.current.toStringAsFixed(2)}'),
              Text('最大振幅:${_amplitude?.max.toStringAsFixed(2)}'),
            ],

            // 录制文件路径
            if (_recordPath != null) ...[
              const SizedBox(height: 20),
              Text('录制文件:$_recordPath'),
            ],
          ],
        ),
      ),
    );
  }
}

鸿蒙系统适配

鸿蒙系统支持的功能

功能 支持状态
音频录制 ✅ 支持
多种编码格式 ✅ 支持(AAC-LC、AAC-ELD、AAC-HE)
自定义录制参数 ✅ 支持
实时振幅监听 ✅ 支持
录制状态管理 ✅ 支持
设备列表获取 ✅ 支持
权限管理 ✅ 支持
流录制支持 ✅ 支持

注意事项

  1. 录制配置:在鸿蒙系统上,建议使用AAC系列编码格式,这些格式在鸿蒙系统上有较好的支持
  2. 权限处理:鸿蒙系统对权限管理较为严格,建议在应用启动时主动请求权限
  3. 资源释放:在不需要录制时,记得及时调用dispose()方法释放资源,避免内存泄漏
  4. 文件路径:在鸿蒙系统上,建议使用path_provider插件获取应用的私有目录来存储录制文件

插件注册

在鸿蒙系统上,插件会自动注册,但如果需要手动注册,可以参考以下代码:

// 在GeneratedPluginRegistrant.ets文件中
import RecordOhosPlugin from 'record_ohos';

static registerWith(flutterEngine: FlutterEngine) {
  flutterEngine.getPlugins()?.add(new RecordOhosPlugin());
}

总结

Flutter TPC Record 是一个功能强大的音频录制插件,专为鸿蒙系统优化,提供了丰富的音频录制功能和灵活的配置选项。通过简单易用的API,开发者可以轻松在鸿蒙设备上实现高质量的音频录制功能。

主要优势

  • 易于使用:提供简洁的API,方便快速集成
  • 功能丰富:支持多种录制配置和功能
  • 性能优异:基于鸿蒙系统原生API实现,性能出色
  • 良好适配:专为鸿蒙系统优化,兼容性好
  • 完整示例:提供了完整的示例代码,方便学习和使用

社区支持

如果在使用过程中遇到问题,可以通过以下方式获取帮助:

  • 查看项目的GitHub仓库:https://gitcode.com/openharmony-sig/fluttertpc_record
  • 参考示例代码:https://gitcode.com/openharmony-sig/fluttertpc_record/tree/master/record/example

后续建议

  • 根据实际需求选择合适的录制参数,平衡音质和文件大小
  • 实现错误处理机制,提高应用的稳定性
  • 在UI上提供清晰的录制状态反馈,提升用户体验
  • 考虑实现音频文件的压缩和上传功能,满足更多场景需求

通过Flutter TPC Record插件,开发者可以快速在鸿蒙系统上实现专业的音频录制功能,为应用增添更多可能性。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐