0

我想我会尽可能详细地设置这个,希望有人对这种设置有一些经验。

前端: ASP.Net MVC Razer 网站。

  • .Net 框架 4.6.1

后端: Bot 框架 Web API (RESTful)。

  • .Net 框架 4.6

后端:我使用各种位于 Azure 的认知服务,但在这种情况下,它只是 Bing Speech API。

相关SDK:

  • Microsoft.Bing.Speech(版本:2.0.2)
    • Bond.Core.CSharp(版本:8.0.0)~依赖
    • Bond.CSharp (Version: 8.0.0) ~依赖
    • Bond.Runtime.CSharp (Version: 8.0.0) ~依赖

getUserMedia在网站上使用一些 javascript 代码的请求来记录用户麦克风,这会创建一个 blob URL。

然后我将 blob url 作为 inContentUrl传递AttachmentActivity.

当这遇到 Bot 框架时,我会进行一些基本验证(与此问题无关),然后传递给自定义Dialog<T>.

这就是我努力让 Bing Speech 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 的转录功能将语音转换为文本,那么最好的方法是什么?我是否至少朝着正确的方向前进。

如果您的答案与我已经在做的事情有关,则可以加分

4

2 回答 2

3

我使用 WebClient 来获取 Stream,而不是 Microsoft 示例代码中此方法使用的 FileStream,因为 Filestream 不会从 URL 流式传输。

并非所有 Streams 都具有相同的功能。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
        }
    }
于 2018-07-29T17:06:05.310 回答
0

尽管 David 的回答绝对是一个很好的选择(因为我肯定会混淆流),但令人讨厌的是,上面列出的问题的实际答案是对Microsoft.Bing.Speechapi 的有限支持之一。

在 github上的项目工作人员Bond.IO介绍了较低版本和当前在 nuget 上列出的两个最新版本(7.0.1 和 8.0.0)之间的重大变化。

这是 5.x 和 6.x 之间有意的重大更改,以使 Microsoft 以外的人员能够构建和使用强名称签名的 Bond 程序集。


重大更改 Bond 程序集现在使用 > 存储库中的 bond.snk 键进行强名称签名,而不是使用 Microsoft 键。这允许任何人生产兼容的 > 程序集,而不仅仅是 Microsoft。Bond 的官方分发将继续 > > 使用 Microsoft 证书签名的 Authenticode。问题 #414


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

重大更改 Bond 程序集现在具有与其 NuGet 包版本相对应的程序集和文件版本。强名称标识现在将根据 NuGet 包版本更改发布版本。问题 #325 1

这似乎意味着将Microsoft.Bing.Speechapi 升级到最新版本 2.0.1 和 2.0.2(请记住,这是 nuget 上仅有的两个)只能安装Bond.IO7.0.1 或更高版本。Bond.IO但是,它们仍然包含对版本 1.0.0.0 (或更明确地说是 7.0.1 之前的任何构建)的内部要求。

还值得强调的是,如果您从 microsoft 示例项目中手动安装针对旧版本的Microsoft.Bing.Speech程序集和Bond.IO版本 4.2.1 程序集的包,则上述代码可以正常工作。2

一位贡献者在 Microsoft Docs 页面上也有评论说,Microsoft.Bind.Speech 程序集即将贬值(如果他们这样标记它会很好,对吗。)3

总而言之,与我上面的问题最接近的答案是,除非您想使用没有持续支持的过时程序集,否则不要费心使用Microsoft.Bing.Speechnuget 包。他们建议使用4Speech SDK来代替(尽管如果在 BotFramework WebAPI 中使用它,因为它也有一些内部错误,所以要为一场艰苦的战斗做好准备)。

最近几天我一直在研究这个,所以我非常有信心这是该库的当前状态。


1 请在 Bond.IO Github 上查看这个问题

2 评论支持这一点的类似问题。

3 查看本页底部已关闭的评论,'Zhouwangzw' 的回复建议使用最新的 Speech SDK。

3 在这里找到链接到文档的 GitHub 问题

4 使用语音 SDK 的 webAPI 中的当前中断错误。

于 2018-07-31T07:56:01.840 回答