Отправка живого аудиофайла на REST-сервер с использованием HttpClient и PushStreamContent
Мне нужно для потоковой передачи аудиоданных с микрофона на REST-сервер.
Я работаю с собственным механизмом ASR, и мне нужно собирать данные, а затем передавать их в режиме реального времени за один вызов PostAsync. В Интернете я нашел статьи на PushStreamContent, но либо неправильно их использую, я не понимаю, что я Я делаю (или оба).
У меня есть MemoryStream с именем stream_memory, в который я постоянно записываю данные из основного потока и хочу прочитать их во время потоковой передачи и разместить их в реальном времени в одном сообщении. В приведенном ниже примере я также использую событие 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 и выводить данные по мере поступления звука.
Есть идеи?
1 ответ
Оказывается, причина, по которой ничего не было отправлено на сервер, связана с тем, как wireshark отображает результаты HTTP. Я ожидал, что, как только запрос будет отправлен, я сразу же увижу его в Wireshark. Однако wireshark показывает запрос только после его завершения, что означает, что он отображается далеко после того, как запрос начал потоковую передачу.
После того, как я понял это, я увидел данные, отправленные на сервер.