Flutter中的离线语音识别:否Siri,否Google和否,不是STT

2021-02-19 23:50:32

我无需告诉您有关免提移动应用在21世纪的重要性。我要告诉您的是,将其添加到Flutter项目中比想象的要容易。 Picovoice最近发布了一系列Flutter软件包,使您可以在公园散步时将脱机语音命令添加到您的移动应用程序中。不,是认真的-做完之后,您将有时间在公园里散步。

在本教程中,我从去年无处不在的#flutterclock挑战中汲取了一些灵感,并创建了一个简单的时钟应用。 Clock应用程序是特定于域的语音控制的理想平台(即,它具有定义的命令和参数列表)。我们不需要时钟就可以理解英语的范围来为明天设置警报,我们当然也不需要将麦克风音频发送到空中的大型计算机来了解我们的意图-让我们保持简单和私人的。免提模式也是时钟应用程序的一个非常有用的补充。您可能想在双手占据厨房时设置计时器,或者在锻炼过程中启动秒表。

尽管我以Flutter Clock挑战为灵感,但我还是决定不以实际项目为起点,因为我不想使用太多代码,并且要添加很多代码。相反,我从头开始,想到了Android Clock应用程序。

UI非常简单:使用底部导航栏在三个不同的小部件之间切换。至于背后的代码,骨干网是一个定期功能,可更新我们的时钟并检查任何活动的警报和计时器。

现在我们有了一个简单的时钟应用程序,让我们继续前进,看看如何向其添加离线语音AI。对于此项目,我们将需要该应用程序理解一组命令,但我们还需要一个唤醒词来告知应用程序何时收听命令。 Picovoice Platform Flutter SDK将为我们提供所需的一切,因此,通过将其添加到项目的pubspec.yaml文件中进行导入。

接下来,我们将使用PicovoiceManager类捕获音频并将其传递到Picovoice平台。

这里需要解压缩两件事-在构造函数中,我们为PicovoiceManager提供了两个文件和两个回调。 keywordPath和_wakeWordCallback都与豪猪唤醒词引擎相关联-平台中始终侦听特定触发短语的部分。至于contextPath和_inferenceCallback,它们与Rhino语音转意图引擎有关,后者将尝试对唤醒字后面的命令进行解密。如果我们此时尝试启动该应用程序,由于缺少关键字和上下文文件,Picovoice将无法初始化-这是我们的下一个任务。现在,让我们转到Picovoice控制台,为我们的应用创建自定义唤醒词和命令上下文。

Picovoice控制台为我们提供了创建符合我们需求并在所需平台上工作的语音界面所需的所有工具。当前,您可以注册一个免费的个人帐户或开始试用该企业帐户的30天。在本教程中,我们将创建一个自定义命令上下文,该上下文可以工作并针对Android和iOS进行培训。

要创建自定义上下文,我们将单击Rhino选项卡,创建一个空上下文,然后使用内置编辑器来设计命令界面。我们的目标是创建一个简单的语法,供我们的时钟应用程序用来控制该应用程序。上下文将包含一组意图和位置。意图实际上是我们的命令短语-在我们的情况下,它们将包括诸如setTimer和setAlarm之类的项。另一方面,您可以将插槽视为变量。例如,我们的上下文将包含一个名为day的广告位,其值从“星期一”到“星期日”,“今天”和“明天”。在我们的上下文中,意图表达的示例如下:

括号中的单词是可选的,带有美元符号的文本是我们创建的广告位。

至于我们的口号,我们可以使用任何一种根据Apache 2.0许可免费向公众发布的Porcupine模型。您可以在豪猪Github存储库中找到这些免费的唤醒词文件。如果您想创建自定义唤醒词,则需要注册一个Enterprise控制台帐户。

现在我们有了所需的文件,我们可以将它们引入Flutter项目并开始为我们的应用启用语音功能。

在本文的前面,我们看到PicovoiceManager的构造函数采用了一个keywordPath和一个contextPath — keywordPath指的是豪猪模型文件的文件路径(.ppn文件扩展名),而contextPath指的是Rhino模型的文件路径。文件(.rhn文件扩展名)。现在我们有了这些必需的文件,我们将它们放入Flutter项目的asset文件夹中,并将它们作为资产添加到pubspec.yaml文件中。

传统上,非媒体资产很难在跨平台应用程序中加载,但是幸运的是Flutter拥有资产束,我们可以使用path_provider包从中读取并提取到本地目录中。现在,我们将从前面的_initPicovoice函数中添加此文件逻辑和一些平台检测:

如果您现在启动应用程序,PicocoiceManager将初始化并开始流式传输音频。如果您尝试说唤醒词,然后从上下文中的任何命令,您将看到它们打印到调试控制台。虽然这一切都很好,但我们需要这些语音控制实际控制现在的应用程序!

从我们的_wakecallback和_InferenceCallback中的打印命令,您可以开始制定我们要添加的代码,以解析我们将从PicociceManager接收的对象。好消息是,关键词是一个简单的切换开关,推动是一个结构化的地图对象,具有已知键,如下所示:

这与我们必须解析完全未知和非结构化的字符串的语音到文本方法的显着对比。填写这些功能后,我们有回调,看起来像以下内容:

如您所见,唤醒词回调只是将UI状态更改为侦听; Picovoice在内部管理豪猪和犀牛之间的交换机。在我们的应用程序的情况下,这将转动麦克风蓝,让用户知道他们可以向应用程序发出命令。

推断需要一些附加逻辑来将推理对象转换为命令。首先,我们检查推理引擎是否理解语音短语作为其上下文中存在的命令。如果据了解,我们需要确定要执行哪个目的,然后将插槽(即命令变量)传递给相关的应用程序方法。例如,_settimer函数拍摄插槽并将它们转换为定时器持续时间:

一旦我们填充了所有控制功能,我们应该具有完全免提和跨平台的颤动时钟,如以下视频所示:

希望你喜欢这个教程!随时浏览并重用此处的源代码。通过访问我们的网站,GitHub或Developer文档来了解有关Picocoice和我们技术的更多信息。