使用 HttpClient 和 PushStreamContent 将实时音频文件发送到 REST 服务器

Sending live audio file to REST server using HttpClient and PushStreamContent

我需要将音频数据从麦克风流式传输到 REST 服务器。

我正在使用专有的 ASR 引擎,需要收集数据然后在对 PostAsync 的单次调用中实时流式传输 在网上查找,我找到了有关 PushStreamContent 的文章,但要么我没有正确使用它,要么我不明白我在做什么(或两者都不知道)。

我有一个名为 stream_memory 的 MemoryStream,我不断地从主线程向其写入数据,我想在数据流式传输时读取它,并且 post post。在下面的示例中,我还使用事件 stream_data_event 和对象锁来防止多个线程同时写入 MemoryStream。我每次读取内存流时都会清除内存流,因为之后我不需要数据。

这是我的代码片段 运行 在它自己的线程中:

http_client = new HttpClient();
http_client.http_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
http_client.DefaultRequestHeaders.TryAddWithoutValidation("Accept-Language", "en-us");
http_client.DefaultRequestHeaders.TransferEncodingChunked = true;
HttpContent content = new System.Net.Http.PushStreamContent(async (stream, httpContent, transportContext) =>
            {
                while (stream_data_event.WaitOne())
                {

                    lock (main_window.stream_memory_lock)
                    {
                        stream_data_event.Reset();
                        long write_position = main_window.stream_memory.Position;
                        main_window.stream_memory.Seek(0, SeekOrigin.Begin);
                        main_window.stream_memory.CopyTo(stream, (int)write_position);
                        main_window.stream_memory.Position = 0;
                    }
                }
            });
content.Headers.TryAddWithoutValidation("Content-Type", "audio/L16;rate=8000");
string request_uri = String.Format("/v1/speech:recognize");

HttpResponseMessage response = await http_client.PostAsync(request_uri, content);
string http_result = await response.Content.ReadAsStringAsync();

对 PostAsync 的调用按预期调用了 PushStreamContent 的代码。 但是,只要我在 while 循环中,就不会向服务器发送任何内容(在 wireshark 上检查过)。 如果我在调试器中手动退出循环并在流上调用关闭,则 PostAsync 存在但没有任何内容发送到服务器。

我需要有一种方法可以在 PostAsync 中继续流式传输信息,并在音频到达时输出数据。

有什么想法吗?

事实证明,没有向服务器发送任何内容的原因与 wireshark 显示 HTTP 结果的方式有关。 我的期望是一旦请求被发送,我会立即在 wireshark 中看到它。但是,wireshark 仅在请求完成后才显示请求,这意味着它会在请求开始流式传输之后很久才显示。

意识到这一点后,我可以看到发送到服务器的数据。