概念:flutter package 与flutter plugin

package

是用dart封装封装的的功能包,因此对Flutter框架具有依赖性,仅将其用于Flutter 例如fluro,http

plugin

一种专用的Dart包,其中包含用Dart代码编写的API,以及针对Android(使用Java或Kotlin)和/或针对iOS(使用ObjC或Swift)平台的特定实现。一个具体的例子是battery插件包。

本文介绍flutter 语音合成功能的插件包开发(相机、存储、以及依赖原生nativce组件的都需要包装为插件)

  • Flutter Application: Flutter应用
  • Flutter Plugin:Flutter插件
  • Flutter Package:纯Dart组件

flutter 语音合成

flutter 插件结构 ,ios 通过FlutterMethodChannel ,android通过MethodChannel与native通信

image.png

我们根据通过android 和ios 平台的包装分别实现android 的baidu 语音合成和阿里云的语音合成(相同都采用一种更合理。只为学习吧)

创建插件工程:android studio-newMoudle-flutter plugin (aliyunvoice)

image.png

image.png

目录介绍:

android:android native 相关依赖的百度sdk 的jar都放在响应的lib下,so文件放置到jni目录
examle:插件测试主工程
ios:编译后的ios可执行工程
android:android的工程文件
lib:可运行的flutter应用入口 实现插件的调用实现业务需求
ios:ios native 源文件。
android默认生成一个 AliyunVoicePlugin.java 其中getPlatformVersion是默认生成的参考示例
image.png

ios默认生成AliyunVoicePlugin.h 和 AliyunVoicePlugin.m (ios-classes下)
image.png

android插件实现

1 第三方库

添加baidu-tts-*.jar到lib下 复制so文件到jni目录下

2新建BaiduSdk.java 封装实现

image.pngpublic void speak(String current,boolean isLoop,boolean isPause,boolean isExit,boolean isResume) {

_ if (mSpeechSynthesizer == null) {
return;
}
this.current = current;
loop = isLoop;

  1. **if**(isExit){<br /> **mSpeechSynthesizer**.stop();<br /> **return**;<br /> }<br /> **if**(isPause){<br /> **mSpeechSynthesizer**.pause();<br /> **return**;<br /> }<br /> **if**(isResume){<br /> **mSpeechSynthesizer**.resume();<br /> **return**;<br /> }
  2. **int **result = **mSpeechSynthesizer**.speak(current);<br /> Log._i_(**"mainHandler"**, **"mSpeechSynthesizer.speak-->"**+result);<br /> checkResult(result, **"speak"**);<br />}

public void stop() {
int result = mSpeechSynthesizer.stop();
checkResult(result, “stop”);
}
public void pauseOrResume(boolean isPause) {
if(isPause){
mSpeechSynthesizer.pause();
return;
}else{
mSpeechSynthesizer.resume();
return;
}
}

public void release(){
if (mSpeechSynthesizer != null) {
mSpeechSynthesizer.stop();
mSpeechSynthesizer.release();
mSpeechSynthesizer = null;
}
}

3 AliyunVoicePlugin.java 根据调用方法和参数 完成功能方法实现

if (call.method.equals(“getPlatformVersion”)) {
result.success(“Android “ + android.os.Build.VERSION.RELEASE);
} else if (call.method.equals(“initTTS”)) {
BaiduSDK.getBaiduSDKIntance().initTTs(registrar.activity());
}else if (call.method.equals(“attach”)) {
BaiduSDK.getBaiduSDKIntance().attchActivity(registrar.activity());
} else if (call.method.equals(“speak”)) {
BaiduSDK.getBaiduSDKIntance().speak(call.argument(“content”).toString(),true,false,false,false);
}else if(call.method.equals(“release”)){
BaiduSDK.getBaiduSDKIntance().release();
}
else if(call.method.equals(“stop”)){
BaiduSDK.getBaiduSDKIntance().stop();
}
else if(call.method.equals(“pauseOrResume”)){
BaiduSDK.getBaiduSDKIntance().pauseOrResume(call.argument(“status”).equals(“pause”)?true:false);
}
else {
result.notImplemented();
}
call.method为flutter调用的方法名
call.argument为调用的方法参数
result.sucess()为方法返回值 (同步)

ios 插件实现

通过android studuo 提示的open ios in xcode 打开ios工程进行编辑开发
(android开发的小伙伴 要学习一下ios的基本语法和项目结构 相信自己可以的 为了统一的跨平台开发者的目标 花费2天时间 是值得的!)
这里也简短补补知识:
xcode工程
image.png

main.m 入口 然后使用AppDelegate代理
image.png
image.png
这里注册了AliyunVoivePlugin。

这时候按照阿里云官方文档来开发ios就行
https://help.aliyun.com/document_detail/84626.html?spm=a2c4g.11174283.3.6.7c747275NcR7tn
总体分为:

引入aliyunNlssdk.framework

问题1:framework not found
问题2 objecx arm64 或者 x86-64 not found
基本都是依赖库没有正确添加
因为我们是插件调用第三方 和 传统的工程调用第三方pod 还不太一样。如果出现AliyunVoicePlugin中无法调用识别依赖的阿里云framework 说明依赖不对 需要关联正确 以及 在examle -ios目录下执行 pod install
image.png

点击+添加 选择framewords 以及对应的文件 勾选后续的copy-ifneed 以及关联runner。基本可以解决问题

image.png

同理根据调用的方法method 和参数 实现对应的功能
Synthesizer 这个在阿里云sdk demo中可以找到。
分别修改完成
-(void)initTTS
-(void)startSynthesizer : (NSString)content
-(*void
)cancelSynthsizer{
[_synthesizerRequest cancel];
[_nlsAudioPlayer cleanup];
}

-(void)stop{
[self cancelSynthsizer];
}

android预览

normal video.mp4 (1.52MB) ios预览

20190927_174913.mp4 (23.42MB)

语音合成 百度支持的功能相对完善 但是 ios集成中还有些问题
aliyun 合成只是提供简单的合成播放和取消 没有暂停和resume
整体上插件开发流程大致这样 不完善的继续努力吧~