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



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

我使用的是一个专有的ASR引擎,需要收集数据,然后在对PostAsync的一次调用中实时流式传输在网上,我发现了PushStreamContent上的文章,但要么我没有正确使用它,要么我不明白自己在做什么(或者两者都有(。

我有一个名为stream_memory的MemoryStream,我不断地从主线程向其写入数据,我想在数据流传输时读取它,并在单个帖子中实时发布它。在下面的示例中,我还使用事件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上检查(。如果我在调试器中手动退出循环并对流调用close,PostAsync存在,但不会向服务器发送任何内容。

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

有什么想法吗?

事实证明,没有向服务器发送任何消息的原因与wireshark显示HTTP结果的方式有关。我的期望是,一旦请求发出,我会立即在wireshark上看到它。然而,wireshark只在请求完成后才显示该请求,这意味着它在请求开始流式传输后很久才会显示。

在我意识到这一点之后,我可以通过发送到服务器的数据来查看。

最新更新