Bing Speech API 与 Microsoft BotFramework 集成
Bing Speech API integrated with Microsofts BotFramework
我想我会尽可能详细地设置这个,希望有人对这种设置有一些经验。
前端: ASP.Net MVC Razer 网站。
- .Net Framework 4.6.1
后端: Bot-framework Web API (RESTful).
- .Net Framework 4.6
Back-Back-end: 我使用各种位于 Azure 的认知服务,但在这种情况下它只是 Bing 语音 API.
相关SDK:
- Microsoft.Bing.Speech(版本:2.0.2)
- Bond.Core.CSharp (版本: 8.0.0) ~ dependancy
- Bond.CSharp (版本: 8.0.0) ~ dependancy
- Bond.Runtime.CSharp (版本: 8.0.0) ~ dependancy
我在网站上使用 getUserMedia
根据一些 javascript 代码的请求记录用户的麦克风,这会创建一个 blob URL.
然后我将 blob url 作为 Attachment
中的 ContentUrl
传递给 Activity
.
当它到达 Bot 框架时,我会进行一些基本验证(与此问题无关),然后传递给自定义 Dialog<T>
.
这就是我正在努力获得Bing演讲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
获取流,而不是 FileStream
此方法在 Microsoft 示例代码中使用,因为 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,然后使用 Bing.Speech API 的转录功能将语音转换为文本,什么是最好的方法?我至少在朝着正确的方向前进吗?
奖金 如果您的回答与我已经在做的事情相关,则加分。
I'm using the WebClient to get the Stream, rather than the FileStream that this method uses in the Microsoft sample code because Filestream won't stream from URL's.
并非所有流都具有相同的功能。 FileStream 是一个 read/write 随机访问流。 NetworkStream 是只进、只读流。
因此,在将 .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
}
}
尽管 David 的回答绝对是一个很好的收获(因为我肯定会混淆流),但令人恼火的是,上面列出的问题的实际答案是对 Microsoft.Bing.Speech
api.
在 github 上从事 Bond.IO
项目的人员在较低版本和当前在 nuget 上列出的两个最新版本(7.0.1 和 8.0.0)之间引入了重大变化。
This was an intentional breaking change between 5.x and 6.x to enable
people outside of Microsoft to build and use strong-named signed Bond
assemblies.
Breaking change Bond assemblies are now strong-name signed with the bond.snk key in > the repository instead of with a Microsoft key. This allows anyone to produce compatible > assemblies, not just Microsoft. Official distribution of Bond will continue to be > >
Authenticode signed with a Microsoft certificate. Issue #414
The new public key for assemblies is now [Truncated a public key example]
Breaking change Bond assemblies now have assembly and file versions that correspond to their NuGet package version. Strong name
identities will now change release-over-release in line with the NuGet
package versions. Issue #325 1
这似乎意味着将 Microsoft.Bing.Speech
api 升级到最新版本 2.0.1 和 2.0.2(请记住,这两个是 nuget 上唯一可用的版本)只能安装 Bond.IO
7.0.1 或以上。然而,它们仍然包含对 Bond.IO
版本 1.0.0.0 的内部要求(或更明确地说,任何 7.0.1 之前的版本)。
同样值得强调的是,如果您手动安装针对 Microsoft.Bing.Speech
程序集和 Bond.IO
版本 4.2.1 程序集的旧版本的 Microsoft 示例项目的包,则上述代码有效没有问题。2
其中一位贡献者在 Microsoft Docs 页面之一上发表评论称 Microsoft.Bind.Speech 程序集即将贬值(如果他们将其标记为这样就好了,我我是对的。)3
总而言之, 对我上面的问题最接近的答案是,除非您想使用没有持续支持的过时程序集,否则不要费心使用 Microsoft.Bing.Speech
nuget 包。他们建议改用 Speech SDK
(尽管如果在 BotFramework WebAPI 中使用它,请准备好迎接艰苦的战斗,因为它也有一些自己的内部错误)4.
过去几天我一直在研究这个,所以我非常有信心这就是该库的当前状态。
1 Please see this issue against the Bond.IO Github
2 Comment on a similar question supporting this.
3 Found the GitHub issue that linked to the docs here
4 Current breaking error in a webAPI using the Speech SDK.
我想我会尽可能详细地设置这个,希望有人对这种设置有一些经验。
前端: ASP.Net MVC Razer 网站。
- .Net Framework 4.6.1
后端: Bot-framework Web API (RESTful).
- .Net Framework 4.6
Back-Back-end: 我使用各种位于 Azure 的认知服务,但在这种情况下它只是 Bing 语音 API.
相关SDK:
- Microsoft.Bing.Speech(版本:2.0.2)
- Bond.Core.CSharp (版本: 8.0.0) ~ dependancy
- Bond.CSharp (版本: 8.0.0) ~ dependancy
- Bond.Runtime.CSharp (版本: 8.0.0) ~ dependancy
我在网站上使用 getUserMedia
根据一些 javascript 代码的请求记录用户的麦克风,这会创建一个 blob URL.
然后我将 blob url 作为 Attachment
中的 ContentUrl
传递给 Activity
.
当它到达 Bot 框架时,我会进行一些基本验证(与此问题无关),然后传递给自定义 Dialog<T>
.
这就是我正在努力获得Bing演讲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
获取流,而不是 FileStream
此方法在 Microsoft 示例代码中使用,因为 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,然后使用 Bing.Speech API 的转录功能将语音转换为文本,什么是最好的方法?我至少在朝着正确的方向前进吗?
奖金 如果您的回答与我已经在做的事情相关,则加分。
I'm using the WebClient to get the Stream, rather than the FileStream that this method uses in the Microsoft sample code because Filestream won't stream from URL's.
并非所有流都具有相同的功能。 FileStream 是一个 read/write 随机访问流。 NetworkStream 是只进、只读流。
因此,在将 .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
}
}
尽管 David 的回答绝对是一个很好的收获(因为我肯定会混淆流),但令人恼火的是,上面列出的问题的实际答案是对 Microsoft.Bing.Speech
api.
在 github 上从事 Bond.IO
项目的人员在较低版本和当前在 nuget 上列出的两个最新版本(7.0.1 和 8.0.0)之间引入了重大变化。
This was an intentional breaking change between 5.x and 6.x to enable people outside of Microsoft to build and use strong-named signed Bond assemblies.
Breaking change Bond assemblies are now strong-name signed with the bond.snk key in > the repository instead of with a Microsoft key. This allows anyone to produce compatible > assemblies, not just Microsoft. Official distribution of Bond will continue to be > > Authenticode signed with a Microsoft certificate. Issue #414
The new public key for assemblies is now [Truncated a public key example]
Breaking change Bond assemblies now have assembly and file versions that correspond to their NuGet package version. Strong name identities will now change release-over-release in line with the NuGet package versions. Issue #325 1
这似乎意味着将 Microsoft.Bing.Speech
api 升级到最新版本 2.0.1 和 2.0.2(请记住,这两个是 nuget 上唯一可用的版本)只能安装 Bond.IO
7.0.1 或以上。然而,它们仍然包含对 Bond.IO
版本 1.0.0.0 的内部要求(或更明确地说,任何 7.0.1 之前的版本)。
同样值得强调的是,如果您手动安装针对 Microsoft.Bing.Speech
程序集和 Bond.IO
版本 4.2.1 程序集的旧版本的 Microsoft 示例项目的包,则上述代码有效没有问题。2
其中一位贡献者在 Microsoft Docs 页面之一上发表评论称 Microsoft.Bind.Speech 程序集即将贬值(如果他们将其标记为这样就好了,我我是对的。)3
总而言之, 对我上面的问题最接近的答案是,除非您想使用没有持续支持的过时程序集,否则不要费心使用 Microsoft.Bing.Speech
nuget 包。他们建议改用 Speech SDK
(尽管如果在 BotFramework WebAPI 中使用它,请准备好迎接艰苦的战斗,因为它也有一些自己的内部错误)4.
过去几天我一直在研究这个,所以我非常有信心这就是该库的当前状态。
1 Please see this issue against the Bond.IO Github
2 Comment on a similar question supporting this.
3 Found the GitHub issue that linked to the docs here
4 Current breaking error in a webAPI using the Speech SDK.