我想我会尽可能详细地设置这个,希望有人对这种设置有一些经验。
前端:ASP.Net MVC Razer网站。
- .Net Framework 4.6.1
后端:Bot-framework Web API (RESTful)。
- .Net Framework 4.6
后端:我使用各种位于 Azure 的认知服务,但在本例中,它只是必应语音 API。
相关软件开发工具包:
- Microsoft.必应语音(版本:2.0.2)
- Bond.Core.CSharp (版本: 8.0.0) ~依赖
- Bond.CSharp (版本: 8.0.0) ~依赖
- Bond.Runtime.CSharp (版本: 8.0.0) ~依赖
我正在使用网站中的getUserMedia
根据某些 JavaScript 代码的请求记录用户的麦克风,这会创建一个 blob URL。
然后,我将 blob 网址作为Attachment
中的ContentUrl
传递给Activity
。
当这遇到机器人框架时,我会做一些基本的验证(与这个问题无关),然后传递给自定义Dialog<T>
。
这就是我正在努力让必应语音 API 做我想做的事的地方。
我从Dialog<T>
中使用此方法:
public async Task Run(string audioFile, string locale, Uri serviceUrl)
{
// create the preferences object
var preferences = new Preferences(locale, serviceUrl, new CognitiveServicesAuthorizationProvider(subscriptionKey));
using (var speechClient = new SpeechClient(preferences))
{
speechClient.SubscribeToPartialResult(this.OnPartialResult);
speechClient.SubscribeToRecognitionResult(this.OnRecognitionResult);
using (WebClient webClient = new WebClient())
{
using (Stream stream = webClient.OpenRead(audioFile))
{
var deviceMetadata = new DeviceMetadata(DeviceType.Near, DeviceFamily.Desktop, NetworkType.Ethernet, OsName.Windows, "1607", "Dell", "T3600");
var applicationMetadata = new ApplicationMetadata("SampleApp", "1.0.0");
var requestMetadata = new RequestMetadata(Guid.NewGuid(), deviceMetadata, applicationMetadata, "SampleAppService");
try
{
await speechClient.RecognizeAsync(new SpeechInput(stream, requestMetadata), this.cts.Token).ConfigureAwait(false);
}
catch (Exception genEx)
{
// Was just using this try/catch for debugging reasons
}
}
}
}
}
我正在使用WebClient
来获取 Stream,而不是此方法在Microsoft示例代码中使用的FileStream
,因为Filestream
不会从 URL 流式传输。
目前存在的问题:
当命中此行时:
await speechClient.RecognizeAsync(new SpeechInput(stream, requestMetadata), this.cts.Token).ConfigureAwait(false);
它抛出有关 Bond.IO 的错误
.dll融合日志:
我正在使用Microsoft Bot Framework Emulator
在本地进行调试,这就是您将看到本地文件路径的原因。
=== Pre-bind state information ===
LOG: DisplayName = Bond.IO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
(Fully-specified)
LOG: Appbase = file:///[project folder]
LOG: Initial PrivatePath = bin
Calling assembly : Microsoft.Bing.Speech, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file:web.config
LOG: Using host configuration file: aspnet.config
LOG: Using machine configuration file from machine.config.
LOG: Post-policy reference: Bond.IO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Attempting download of new URL file:///C:/Users/[USER]/AppData/Local/Temp/Temporary ASP.NET Files/vs/0f4bb63f/ca796715/Bond.IO.DLL.
LOG: Attempting download of new URL file:///C:/Users/[USER]/AppData/Local/Temp/Temporary ASP.NET Files/vs/0f4bb63f/ca796715/Bond.IO/Bond.IO.DLL.
LOG: Attempting download of new URL file:///C:/[USER]/[PROJECT PATH]/bin/Bond.IO.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
奇怪的是,如果我将 bing api 回滚到 2.0.1 并手动插入旧版本的 Bond.IO 包(版本 4.0.1),这是示例项目中安装的内容,它不会引发此错误,它会抛出其他错误。
我真正在问什么:
如果只想将.wav音频文件发送到我的 API,然后使用必应语音 API 的听录功能将语音转换为文本,最好的方法是什么?我至少走在正确的方向上。
奖励积分,如果你的答案与我已经这样做的方式有关。
我正在使用WebClient来获取Stream,而不是此方法在Microsoft示例代码中使用的FileStream,因为Filestream不会从URL流式传输。
并非所有流都具有相同的功能。 文件流是一个读/写随机访问流。 网络流是只进、只读流。
因此,在将.wav传递给 API 之前,先将其缓冲到 MemoryStream。
using (Stream stream = webClient.OpenRead(audioFile))
{
var ms = new MemoryStream();
stream.CopyTo(ms);
ms.Position = 0;
var deviceMetadata = new DeviceMetadata(DeviceType.Near, DeviceFamily.Desktop, NetworkType.Ethernet, OsName.Windows, "1607", "Dell", "T3600");
var applicationMetadata = new ApplicationMetadata("SampleApp", "1.0.0");
var requestMetadata = new RequestMetadata(Guid.NewGuid(), deviceMetadata, applicationMetadata, "SampleAppService");
try
{
await speechClient.RecognizeAsync(new SpeechInput(ms, requestMetadata), this.cts.Token).ConfigureAwait(false);
}
catch (Exception genEx)
{
// Was just using this try/catch for debugging reasons
}
}
尽管大卫的回答绝对是一个很好的收获(因为我肯定混淆了流),但令人讨厌的是,上面列出的问题的实际答案是对Microsoft.Bing.Speech
API的有限支持之一。
在 github 上从事Bond.IO
项目的人员在较低版本和当前在 nuget 上列出的两个最新版本(7.0.1 和 8.0.0)之间引入了重大更改。
这是 5.x 和 6.x 之间的有意中断性更改,以启用 Microsoft以外的人来构建和使用强名称签名债券 组件。
中断性变更 绑定程序集现在在存储库>使用 bond.snk 密钥而不是Microsoft密钥进行强名称签名。这允许任何人生产兼容的>组件,而不仅仅是Microsoft。债券的官方分配将继续>> 使用Microsoft证书签名的验证码。问题 #414
程序集的新公钥现在为[截断公钥示例]
中断性变更 绑定程序集现在具有与其 NuGet 包版本对应的程序集和文件版本。强名称 标识现在将根据 NuGet 更改发布-过度发布 包版本。问题 #3251
这似乎意味着将Microsoft.Bing.Speech
API 升级到最新版本 2.0.1 和 2.0.2(请记住,这是 nuget 上唯一可用的两个)只能安装 7.0.1 或更高版本Bond.IO
。但是,它们仍然包含Bond.IO
版本 1.0.0.0(或更明确地说是 7.0.1 之前的任何内部版本)的内部要求。
还值得强调的是,如果您手动安装来自 Microsoft 示例项目的包,这些包面向旧版本的Microsoft.Bing.Speech
程序集和Bond.IO
版本 4.2.1 程序集,则上述代码可以正常工作。阿拉伯数字
其中一位贡献者在Microsoft Docs页面上也有评论说Microsoft.Bind.Speech程序集即将被贬值(如果他们这样标记就好了,对吗。3
总而言之,对我上面问题最接近的答案是,除非您想使用没有持续支持的过时程序集,否则不要打扰使用Microsoft.Bing.Speech
nuget 包。他们建议改用Speech SDK
(尽管如果在 BotFramework WebAPI 中使用它,请准备好进行一场艰苦的战斗,因为它也有一些自己的内部错误)4。
我在过去的几天里一直在研究这个问题,所以我非常有信心这是该库的当前状态。
1请针对 Bond.IO Github 查看此问题
2评论支持这一点的类似问题。
3查看本页底部的封闭评论,"周网"的回复建议使用最新的语音 SDK。
3在此处找到链接到文档的 GitHub 问题
4使用语音 SDK 的 Web API 中的当前中断错误。