C# Bing语音API与Microsofts BotFramework集成

C# Bing语音API与Microsofts BotFramework集成,c#,botframework,speech-to-text,microsoft-cognitive,bing-speech,C#,Botframework,Speech To Text,Microsoft Cognitive,Bing Speech,我想我会尽可能详细地阐述这一点,希望有人对这种设置有一定的经验 前端:ASP.Net MVC Razer网站 .Net Framework 4.6.1 后端:机器人框架Web API(RESTful) .Net Framework 4.6 后端:我使用各种Azure定位认知服务,但在这种情况下,它只是Bing语音API 相关SDK: Microsoft.Bing.Speech(版本:2.0.2) Bond.Core.CSharp(版本:8.0.0)~依赖性 Bond.CSharp(版

我想我会尽可能详细地阐述这一点,希望有人对这种设置有一定的经验

前端:ASP.Net MVC Razer网站

  • .Net Framework 4.6.1
后端:机器人框架Web API(RESTful)

  • .Net Framework 4.6
后端:我使用各种Azure定位认知服务,但在这种情况下,它只是Bing语音API

相关SDK:

  • Microsoft.Bing.Speech(版本: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 url作为
附件中的
ContentUrl
传递给
活动

当这个问题出现在Bot框架中时,我会进行一些基本的验证(与此问题无关),然后传递到一个自定义的
对话框

这就是我努力让Bing语音API实现我想要的功能的地方

我在
对话框中使用此方法:

我使用
WebClient
获取流,而不是此方法在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,然后使用Bing.Speech API的转录功能将语音转换为文本,那么最好的方法是什么?我至少走对了方向

奖金如果你的答案与我的表现相关,则得分

我使用WebClient来获取流,而不是此方法在Microsoft示例代码中使用的文件流,因为文件流不会从URL流

并非所有流都具有相同的功能。FileStream是一种读/写随机访问流。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
        }
    }
我使用WebClient来获取流,而不是此方法在Microsoft示例代码中使用的文件流,因为文件流不会从URL流

并非所有流都具有相同的功能。FileStream是一种读/写随机访问流。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)之间引入了突破性的变化

这是一个故意破坏5.x和6.x之间的更改,以启用 Microsoft以外的人构建和使用强名称签名债券 装配


打破更改绑定程序集现在是使用存储库中的Bond.snk密钥而不是Microsoft密钥签名的强名称。这允许任何人生成兼容的>程序集,而不仅仅是Microsoft。债券的正式发行将继续>> 使用Microsoft证书签名的Authenticode。问题#414


程序集的新公钥现在是[截断公钥示例]

打破更改绑定程序集现在具有与其NuGet包版本相对应的程序集和文件版本。强名称 身份现在将随着NuGet的发布而改变 软件包版本。问题#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示例项目中的软件包,这些软件包的目标是
microsoft.Bing.Speech
程序集和
Bond.IO
4.2.1版程序集的较旧版本,则上述代码可以正常工作。2

还有一位贡献者在其中一个Microsoft文档页面上评论说,Microsoft.Bind.Speech程序集正在贬值(如果他们这样标记会更好,对吗?)

总之,对于我上面的问题,最接近的答案是,除非您想使用没有持续支持的过时程序集,否则就不要麻烦使用
Microsoft.Bing.Speech
nuget软件包。他们建议改为使用
Speech SDK
(尽管如果在BotFramework WebAPI中使用它,则要做好准备,因为它本身也有一些内部错误)4