Отправка живого аудиофайла на 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 показывает запрос только после его завершения, что означает, что он отображается далеко после того, как запрос начал потоковую передачу.

После того, как я понял это, я увидел данные, отправленные на сервер.

Другие вопросы по тегам