草庐IT

c# - 将 WAV 录制到 IBM Watson Speech-To-Text

coder 2024-06-03 原文

我正在尝试录制音频并立即将其发送到 IBM Watson Speech-To-Text 进行转录。我已经使用从磁盘加载的 WAV 文件测试了 Watson,并且成功了。另一方面,我还测试了从麦克风录音并将其存储到磁盘,效果也很好。

但是当我尝试使用 NAudio WaveIn 录制音频时,Watson 的结果是空的,就好像没有音频一样。

谁能对此有所启发,或者有人有一些想法?

private async void StartHere()
{
    var ws = new ClientWebSocket();
    ws.Options.Credentials = new NetworkCredential("*****", "*****");

    await ws.ConnectAsync(new Uri("wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_NarrowbandModel"), CancellationToken.None);

    Task.WaitAll(ws.SendAsync(openingMessage, WebSocketMessageType.Text, true, CancellationToken.None), HandleResults(ws));

    Record();
}

public void Record()
{
    var waveIn = new WaveInEvent
    {
        BufferMilliseconds = 50,
        DeviceNumber       = 0,
        WaveFormat         = format
    };

    waveIn.DataAvailable    += new EventHandler(WaveIn_DataAvailable);
    waveIn.RecordingStopped += new EventHandler(WaveIn_RecordingStopped);
    waveIn.StartRecording();
}

public void Stop() 
{
    await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
}

public void Close()
{
    ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None).Wait();
}

private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
    await ws.SendAsync(new ArraySegment(e.Buffer), WebSocketMessageType.Binary, true, CancellationToken.None);
}

private async Task HandleResults(ClientWebSocket ws)
{
    var buffer = new byte[1024];

    while (true)
    {
        var segment = new ArraySegment(buffer);
        var result = await ws.ReceiveAsync(segment, CancellationToken.None);

        if (result.MessageType == WebSocketMessageType.Close)
        {
            return;
        }

        int count = result.Count;
        while (!result.EndOfMessage)
        {
            if (count >= buffer.Length)
            {
                await ws.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "That's too long", CancellationToken.None);
                return;
            }

            segment = new ArraySegment(buffer, count, buffer.Length - count);
            result = await ws.ReceiveAsync(segment, CancellationToken.None);
            count += result.Count;
        }

        var message = Encoding.UTF8.GetString(buffer, 0, count);

        // you'll probably want to parse the JSON into a useful object here,
        // see ServiceState and IsDelimeter for a light-weight example of that.
        Console.WriteLine(message);

        if (IsDelimeter(message))
        {
            return;
        }
    }
}

private bool IsDelimeter(String json)
{
    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ServiceState));
    ServiceState obj = (ServiceState) ser.ReadObject(stream);

    return obj.state == "listening";
}

[DataContract]
internal class ServiceState
{
    [DataMember]
    public string state = "";
}


编辑:我也试过在开始录制之前发送 WAV“ header ”,像这样

    waveIn.DataAvailable    += new EventHandler(WaveIn_DataAvailable);
    waveIn.RecordingStopped += new EventHandler(WaveIn_RecordingStopped);

    /* Send WAV "header" first */
    using (var stream = new MemoryStream())
    {
        using (var writer = new BinaryWriter(stream, Encoding.UTF8))
        {
            writer.Write(Encoding.UTF8.GetBytes("RIFF"));
            writer.Write(0); // placeholder
            writer.Write(Encoding.UTF8.GetBytes("WAVE"));
            writer.Write(Encoding.UTF8.GetBytes("fmt "));

            format.Serialize(writer);

            if (format.Encoding != WaveFormatEncoding.Pcm && format.BitsPerSample != 0)
            {
                writer.Write(Encoding.UTF8.GetBytes("fact"));
                writer.Write(4);
                writer.Write(0);
            }

            writer.Write(Encoding.UTF8.GetBytes("data"));
            writer.Write(0);
            writer.Flush();
        }

        byte[] header = stream.ToArray();

        await ws.SendAsync(new ArraySegment(header), WebSocketMessageType.Binary, true, CancellationToken.None);
    }
    /* End WAV header */

    waveIn.StartRecording();

最佳答案

经过大约 20 小时的反复试验找到了解决方案,我创建了一个 GitHub Gist,因为它可能对其他人很方便。参见 https://gist.github.com/kboek/20476c2a03b5e9188edebaace74f9a07

关于c# - 将 WAV 录制到 IBM Watson Speech-To-Text,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45321876/

有关c# - 将 WAV 录制到 IBM Watson Speech-To-Text的更多相关文章

  1. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  2. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  3. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  4. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  5. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

  6. ruby - 无法覆盖 irb 中的 to_s - 2

    我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)

  7. ruby-on-rails - 错误 : Error installing pg: ERROR: Failed to build gem native extension - 2

    我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby​​'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe

  8. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  9. ruby-on-rails - Prawn PDF : I need to generate nested tables - 2

    我需要一个表,其中行实际上是2行表,一个嵌套表是..我怎样才能在Prawn中做到这一点?也许我需要延期..但哪一个? 最佳答案 现在支持子表:Prawn::Document.generate("subtable.pdf")do|pdf|subtable=pdf.make_table([["sub"],["table"]])pdf.table([[subtable,"original"]])end 关于ruby-on-rails-PrawnPDF:Ineedtogeneratenested

  10. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

随机推荐