Flutter 3.47 鸿蒙三方库适配实战:从 0 到 1 处理 just_waveform

音频 waveform 生成看起来像一个 Dart 工具,实际上通常依赖原生音频解码器或 C/C++ 音频处理库。迁移到鸿蒙时,要先确认原生解码链、文件格式和异步进度回调是否存在等价实现。

本文以 just_waveform 0.0.7 为例,记录 Flutter 3.47 鸿蒙适配过程:补齐 OHOS 插件注册和 MethodChannel,对暂时没有原生音频实现的 extract 接口返回明确的 UNSUPPORTED,并在 API 26 真机上验证平台限制。

一、最终效果

在这里插入图片描述

图 1:API 26 真机启动适配后的 Demo。

在这里插入图片描述

图 2:页面明确显示当前平台不支持音频 waveform 生成。

验证点真机结果
Flutter3.47.4-ohos-1.0.4
HarmonyOS7.0.0.105,API 26
HAPsigned HAP 构建通过
插件注册OHOS 插件可加载
waveform 生成返回 UNSUPPORTED
数据结论没有伪造 waveform 文件或进度

二、先看上游实现依赖

just_waveform 的核心入口是:

JustWaveform.extract(
  audioInFile: audioFile,
  waveOutFile: waveFile,
);

它返回 Stream。原生端负责音频解码和 waveform 文件生成,完成后再通过 MethodChannel 回调 onProgress,Dart 端收到 100% 后读取 waveform 文件头和采样数据。

完整链路是:

Flutter 页面
  -> JustWaveform.extract()
  -> MethodChannel('com.ryanheise.just_waveform')
  -> 原生音频解码器
  -> onProgress 回调
  -> Dart 读取 waveform 文件

这不是纯 Dart 工具。只生成 OHOS 目录、没有音频解码实现时,页面最多只能显示初始进度,不能称为完整 waveform 适配。

三、确定适配边界

本次完成四件事:

项目处理
OHOS 平台注册完成
MethodChannel完成
extract 方法返回明确 UNSUPPORTED
真机验证完成

本次没有完成:

  • OHOS 音频文件解码;
  • MP3、AAC 等格式采样读取;
  • audiowaveform 文件生成;
  • onProgress 真实进度回调;
  • waveform 二进制文件真机回读。

把范围写清楚很重要。返回随机数组或空 waveform,都会把“平台没有实现”误判成“音频没有有效采样”。

四、准备工具和设备

本文实际环境:

工具版本
Flutter OH3.47.4-ohos-1.0.4
Dart3.13.3
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 26
测试设备127.0.0.1:5555,HarmonyOS 7.0.0.105

没有 Flutter 鸿蒙环境时,先看 Flutter OH 环境搭建指南。

export PATH=/Users/von/Developer/flutter-oh-3.47.4/bin:$PATH
flutter --version
hdc list targets

五、拉取适配分支

本文使用的 AtomGit 信息:

git clone https://atomgit.com/oh-flutter/just_waveform.git
cd just_waveform
git switch feat/ohos_just_waveform_0.0.7
git log -1 --oneline

六、补充 OHOS 平台声明

在 pubspec.yaml 中增加:

flutter:
  plugin:
    platforms:
      android:
        pluginClass: JustWaveformPlugin
      ios:
        pluginClass: JustWaveformPlugin
      ohos:
        pluginClass: JustWaveformPlugin

入口文件:

import JustWaveformPlugin from './src/main/ets/components/plugin/JustWaveformPlugin';

export default JustWaveformPlugin;

这一步只说明 Flutter 可以加载插件,还没有解决原生音频处理。

七、核对 Dart 通道和方法名

Dart 端使用:

static final _channel =
    const MethodChannel('com.ryanheise.just_waveform');

extract 发送:

_channel.invokeMethod('extract', {
  'audioInPath': audioInFile.path,
  'waveOutPath': waveOutFile.path,
  'samplesPerPixel': zoom._samplesPerPixel,
  'pixelsPerSecond': zoom._pixelsPerSecond,
});

OHOS 端必须使用完全相同的 Channel 和方法名:

this.channel = new MethodChannel(
  binding.getBinaryMessenger(),
  'com.ryanheise.just_waveform',
);

处理 extract:

case 'extract':
  result.error(
    'UNSUPPORTED',
    'Waveform extraction is not implemented on OpenHarmony yet.',
    null,
  );
  return;

如果 Channel 写成 just_waveform,Dart 就会收到 MissingPluginException。适配时不能根据仓库名猜 Channel,要从 Dart 源码读取真实值。

八、为什么返回错误比空数据可靠

Dart 的 extract 先发送 0% 进度,再等待原生 onProgress。如果 OHOS 端直接返回空结果:

  • 页面可能一直显示 0%;
  • 业务可能误认为音频没有声音;
  • wave 文件可能不存在;
  • 后续 parse 会出现文件错误。

适配层返回 PlatformException 后,业务可以明确降级:

try {
  await for (final progress in JustWaveform.extract(
    audioInFile: input,
    waveOutFile: output,
  )) {
    // 处理进度
  }
} catch (error) {
  // 当前平台不支持或原生解码失败
}

错误码固定为 UNSUPPORTED,业务可以隐藏 waveform、显示静态封面,或切换服务端预计算结果。

九、创建最小 Demo

Demo 页面显示当前平台边界:

String _status = '当前平台不支持';
String _detail =
    'OHOS 端需要接入音频解码与 waveform 生成能力';

页面仍保留 extract 调用代码,方便后续接入原生音频实现:

Future<void> _extract() async {
  final directory = await getTemporaryDirectory();
  final input = File(directory.path + '/demo.mp3');
  final output = File(directory.path + '/demo.wave');

  try {
    await for (final progress in JustWaveform.extract(
      audioInFile: input,
      waveOutFile: output,
    )) {
      // 更新进度
    }
  } catch (error) {
    // 显示 PlatformException
  }
}

本次 Demo 不把不存在的 mp3 写入设备,也不生成假 waveform。

十、构建、签名和安装

flutter pub get
flutter analyze
cd example
flutter test
flutter build hap --debug --no-codesign

配置 DevEco 调试签名后:

flutter build hap --debug
hdc list targets
hdc install -r build/ohos/hap/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.example.flutter_oh_demo

本文使用 signed HAP 在 API 26 真机启动页面。签名证书和密码没有提交。

十一、真机验证

真机启动后,页面显示“当前平台不支持”和“OHOS 端需要接入音频解码与 waveform 生成能力”。

这个结果证明:

  1. Flutter 页面和 OHOS 宿主能够正常运行;
  2. just_waveform 的 OHOS 插件已经注册;
  3. 插件没有误报 waveform 已经生成;
  4. 当前适配边界在页面中可见。

如果要完成真正的 waveform 能力,还需要补充 OHOS 音频解码实现,再增加音频文件、进度回调、wave 文件格式和采样数据真机测试。

十二、常见问题

Q1:为什么不返回一组空 waveform

空 waveform 会把“平台没有实现”误判成“音频没有有效采样”。适配层应该返回明确错误。

Q2:为什么页面不自动加载 mp3

本文只验证平台适配边界,不把音频资源、解码器和 waveform 算法混在一个 Demo 中。接入真实实现时,再加入经过授权的音频样本。

Q3:为什么不直接复用 Android 的 audiowaveform 库

Android 的 native library、构建配置和 ABI 不能直接在 OHOS 中运行。需要重新确认 C/C++ 依赖、OHOS NDK 构建和 Flutter FFI 或 MethodChannel 边界。

Q4:返回 UNSUPPORTED 算适配完成吗

本文完成的是 OHOS 插件注册、通道契约和准确的平台限制返回。完整音频 waveform 能力仍是后续原生实现任务,不能把 HAP 构建通过写成音频解码已完成。

十三、复现命令

git clone https://atomgit.com/oh-flutter/just_waveform.git
cd just_waveform
git switch feat/ohos_just_waveform_0.0.7
export PATH=/Users/von/Developer/flutter-oh-3.47.4/bin:$PATH
flutter pub get
flutter analyze
cd example
flutter test
flutter build hap --debug --no-codesign

十四、总结

just_waveform 的适配重点是识别原生音频处理边界。Flutter 3.47 鸿蒙端已经能够加载插件、建立 MethodChannel 并返回明确的 UNSUPPORTED 结果,但音频解码和 waveform 生成仍需要独立的 OHOS 原生实现。对于新手来说,先把“已完成”和“未完成”分开,是比伪造一条成功进度更可靠的适配方式。

十五、参考资料与仓库地址

本文适配仓库

上游和包信息

Flutter 和鸿蒙资料

欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐