Flutter嵌入式JavaScript引擎插件rhino_flutter的使用
Flutter嵌入式JavaScript引擎插件rhino_flutter的使用
Rhino Speech-to-Intent引擎
由加拿大温哥华的Picovoice制作。
Rhino是Picovoice的Speech-to-Intent引擎。它可以直接从给定上下文内的口语命令中推断出意图,并实时返回结果。例如,给定一个口语命令“Can I have a small double-shot espresso?”(我可以要一杯小杯双份意式浓缩咖啡吗?),Rhino会推断用户想要点一杯饮料,并发出以下推理结果:
{
"type": "espresso",
"size": "small",
"numberOfShots": "2"
}
Rhino的特点包括:
- 准确性高
- 使用在现实世界环境中训练的深度神经网络。
- 紧凑且计算效率高,非常适合物联网应用。
- 自服务。开发人员和设计师可以使用Picovoice控制台训练自定义模型。
兼容性
该绑定适用于运行在以下平台上的Flutter 2.8.1+:
- Android 5.0+ (API 21+)
- iOS 13.0+
安装
首先,你需要在系统上安装Flutter SDK。安装完成后,你可以运行flutter doctor
来确定是否有其他缺失的要求。
要将Rhino插件添加到你的应用项目中,你可以在pub.yaml文件中引用它:
dependencies:
rhino_flutter: ^<版本号>
如果你更喜欢克隆仓库并在本地使用,首先运行copy_resources.sh
(注意:在Windows上,需要Git Bash或其他bash shell,否则你必须手动将库复制到项目中)。然后你可以引用本地绑定位置:
dependencies:
rhino_flutter:
path: /路径/到/rhino/flutter/绑定
AccessKey
Rhino初始化时需要有效的Picovoice AccessKey
。AccessKey
作为你在使用Rhino SDK时的凭证。你可以免费获得AccessKey
。务必保密你的AccessKey
。
注册或登录到Picovoice控制台以获取你的AccessKey
。
权限
要启用硬件麦克风的录音功能,你必须确保在iOS和Android上都启用了正确的权限。
在iOS上,打开你的Info.plist文件并添加以下行:
<key>NSMicrophoneUsageDescription</key>
<string>[权限说明]</string>
在Android上,打开你的AndroidManifest.xml文件并添加以下行:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
注意:当为iOS发布归档时,你可能需要更改项目的构建设置,以防止Rhino库被剥离。为此,在XCode中打开Runner项目并将部署设置中的Strip Style更改为’非全局符号’。
使用
该模块为你提供了两种级别的API供选择,具体取决于你的需求。
高级API
RhinoManager
提供了一个高级API,处理音频录制。这是快速开始的最简单方式。
RhinoManager.create
构造函数将使用传递给它的上下文文件创建一个RhinoManager实例。
import 'package:rhino/rhino_manager.dart';
import 'package:rhino/rhino_error.dart';
final String accessKey = '{ACCESS_KEY}'; // 从Picovoice控制台(https://console.picovoice.ai/)获得的AccessKey
void createRhinoManager() async {
try {
_rhinoManager = await RhinoManager.create(
'/路径/到/上下文文件.rhn',
_inferenceCallback);
} on RhinoException catch (err) {
// 处理Rhino初始化错误
}
}
注意:调用是异步的,因此应该在一个异步块中使用try/catch。
inferenceCallback
参数是一个函数,当你需要执行Rhino做出推理时调用该函数。该函数应接受一个代表推理结果的RhinoInference
实例。
void _inferenceCallback(RhinoInference inference) {
if(inference.isUnderstood!){
String intent = inference.intent!
Map<String, String> slots = inference.slots!
// 添加代码根据推断的意图和槽值采取行动
}
else {
// 添加代码处理不支持的命令
}
}
Rhino接受以下可选参数:
sensitivity
: 覆盖默认的推理敏感度。processErrorCallback
: 如果在处理音频时遇到问题,则调用此回调。endpointDurationSec
: 设置语音命令后的静音时间。requireEndpoint
: 表示Rhino是否应在返回推理之前等待静默。
final String accessKey = '{ACCESS_KEY}'; // 从Picovoice控制台(https://console.picovoice.ai/)获得的AccessKey
_rhinoManager = await RhinoManager.create(
accessCallback
'/路径/到/上下文文件.rhn',
_inferenceCallback,
modelPath: '路径/到/模型文件.pv',
sensitivity: 0.75,
endpointDurationSec: 1.5,
requireEndpoint: false,
processErrorCallback: _errorCallback);
void _errorCallback(PvError error){
// 处理错误
}
一旦你实例化了RhinoManager,你可以通过调用process()
函数开始音频捕获和意图推理。
一旦通过推理回调返回推理结果,音频捕获停止并且Rhino重置。
try {
await _rhinoManager.process();
} on RhinoException catch (ex) {
// 处理音频异常
}
一旦你的应用程序不再使用RhinoManager,确保显式地释放分配给它的资源:
await _rhinoManager.delete();
无需处理音频捕获即可启用RhinoManager的推理。
这是因为它使用我们的flutter_voice_processor
插件来捕获音频帧并自动将其传递给语音到意图引擎。
低级API
Rhino
提供对推理引擎的低级访问,适合那些希望将语音到意图集成到现有音频处理管道中的用户。
通过向其静态构造函数create
传递上下文文件来创建Rhino
:
import 'package:rhino/rhino_manager.dart';
import 'package:rhino/rhino_error.dart';
final String accessKey = '{ACCESS_KEY}'; // 从Picovoice控制台(https://console.picovoice.ai/)获得的AccessKey
void createRhino() async {
try {
_rhino = await Rhino.create(accessKey, '/路径/到/上下文文件.rhn');
} on PvError catch (err) {
// 处理Rhino初始化错误
}
}
要向Rhino发送音频数据,必须将其帧传递给它的process
函数。
每次调用process
都会返回一个包含以下变量的RhinoInference
实例:
isFinalized
- 如果Rhino已做出推理,则为true,否则为false。isUnderstood
- 如果isFinalized
为false,则为null,否则如果Rhino基于上下文理解听到的内容,则为true,否则为false。intent
- 如果isUnderstood
不为真,则为null,否则为推断出的意图名称。slots
- 如果isUnderstood
不为真,则为null,否则为推断出的槽键和值的字典。
List<int> buffer = getAudioFrame();
try {
RhinoInference inference = await _rhino.process(buffer);
if (inference.isFinalized) {
if (inference.isUnderstood!) {
String intent = inference.intent!;
Map<String, String> = inference.slots!;
// 添加代码根据推断的意图和槽值采取行动
}
}
} on RhinoException catch (error) {
// 处理错误
}
为了使process
正确工作,音频数据必须符合Picovoice所需的音频格式。
所需的音频格式可以通过调用.sampleRate
获取所需采样率,通过调用.frameLength
获取所需帧大小。
音频必须是单声道且16位线性编码。
最后,一旦不再需要语音到意图引擎,确保显式释放分配给Rhino的资源:
_rhino.delete();
自定义上下文集成
要在你的Flutter应用中添加自定义上下文,首先将.rhn文件添加到项目目录中的assets文件夹。然后在你的pubspec.yaml
中添加它们:
flutter:
assets:
- assets/上下文.rhn
然后你可以直接将它传递给Rhino的create
构造函数:
final String accessKey = '{ACCESS_KEY}'; // 从Picovoice控制台(https://console.picovoice.ai/)获得的AccessKey
String contextAsset = 'assets/上下文.rhn';
try {
_rhino = await Rhino.create(accessKey, contextAsset);
} on RhinoException catch (err) {
// 处理Rhino初始化错误
}
更多关于Flutter嵌入式JavaScript引擎插件rhino_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter嵌入式JavaScript引擎插件rhino_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
rhino_flutter
是一个 Flutter 插件,允许开发者将 JavaScript 引擎 Rhino 嵌入到 Flutter 应用中。Rhino 是一个由 Mozilla 开发的 JavaScript 引擎,通常用于 Java 应用中执行 JavaScript 代码。通过 rhino_flutter
插件,开发者可以在 Flutter 应用中执行 JavaScript 代码,从而实现跨平台的脚本功能。
使用 rhino_flutter
的步骤
-
添加依赖 首先,你需要在
pubspec.yaml
文件中添加rhino_flutter
插件的依赖。dependencies: flutter: sdk: flutter rhino_flutter: ^1.0.0 # 请根据实际版本号填写
-
安装依赖 运行
flutter pub get
来安装依赖。flutter pub get
-
导入插件 在你的 Dart 文件中导入
rhino_flutter
插件。import 'package:rhino_flutter/rhino_flutter.dart';
-
初始化 Rhino 引擎 在使用 Rhino 引擎之前,你需要先初始化它。
void main() async { WidgetsFlutterBinding.ensureInitialized(); await RhinoFlutter.init(); runApp(MyApp()); }
-
执行 JavaScript 代码 你可以使用
RhinoFlutter.eval
方法来执行 JavaScript 代码。void executeJavaScript() async { String jsCode = ''' function add(a, b) { return a + b; } add(2, 3); '''; var result = await RhinoFlutter.eval(jsCode); print('Result: $result'); // 输出: Result: 5 }
-
处理 JavaScript 和 Dart 之间的通信 你可以通过
RhinoFlutter
插件在 JavaScript 和 Dart 之间传递数据。通常,你可以将数据作为参数传递给 JavaScript 函数,或者从 JavaScript 函数中返回值。void communicateWithJavaScript() async { String jsCode = ''' function greet(name) { return "Hello, " + name + "!"; } '''; await RhinoFlutter.eval(jsCode); var result = await RhinoFlutter.callFunction('greet', ['World']); print('Result: $result'); // 输出: Result: Hello, World! }
-
异常处理 在执行 JavaScript 代码时,可能会遇到异常。你可以使用
try-catch
块来捕获并处理这些异常。void handleJavaScriptError() async { String jsCode = ''' undefinedFunction(); '''; try { await RhinoFlutter.eval(jsCode); } catch (e) { print('JavaScript Error: $e'); } }
示例应用
以下是一个简单的 Flutter 应用,展示如何使用 rhino_flutter
插件执行 JavaScript 代码。
import 'package:flutter/material.dart';
import 'package:rhino_flutter/rhino_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await RhinoFlutter.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Rhino Flutter Example')),
body: Center(
child: ElevatedButton(
onPressed: executeJavaScript,
child: Text('Execute JavaScript'),
),
),
),
);
}
void executeJavaScript() async {
String jsCode = '''
function add(a, b) {
return a + b;
}
add(2, 3);
''';
var result = await RhinoFlutter.eval(jsCode);
print('Result: $result'); // 输出: Result: 5
}
}