Отправка живого аудио файла на REST-сервер с использованием HttpClient и PushStreamContent - PullRequest
0 голосов
/ 12 ноября 2018

Мне нужно для потоковой передачи аудиоданных с микрофона на 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 Ответ

0 голосов
/ 20 ноября 2018

Оказывается, причина того, что ничего не было отправлено на сервер, связана с тем, как wireshark отображает результаты HTTP.Я ожидал, что, как только запрос будет отправлен, я сразу же увижу его в Wireshark.Однако wireshark показывает запрос только после его завершения, что означает, что он отображается далеко после того, как запрос начал потоковую передачу.

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

...