簡體   English   中英

在Android中通過HTTP / 2進行POST流音頻

[英]POST Streaming Audio over HTTP/2 in Android

一些背景:

我正在嘗試在android應用程序上開發與語音相關的功能,用戶可以在其中使用語音進行搜索,並且服務器會在用戶講話時發送中間結果(依次更新UI),並在查詢完成后發送最終結果。 由於服務器僅接受HTTP / 2單套接字連接,而Android HTTPUrlConnection 尚不支持 HTTP / 2,因此我正在使用Retrofit2。

我已經看過了這個這個這個,但是每個示例都有固定長度的數據,或者可以事先確定大小……對於音頻搜索而言,情況並非如此。

這是我的POST方法:

  public interface Service{
    @Streaming
    @Multipart
    @POST("/api/1.0/voice/audio")
    Call<ResponseBody> post(
            @Part("configuration") RequestBody configuration,
            @Part ("audio") RequestBody audio);
}

該方法以以下方式發送配置文件(包含音頻參數-JSON結構)和流音頻。 (預期的POST請求)

Content-Type = multipart/form-data;boundary=----------------------------41464684449247792368259
//HEADERS
----------------------------414646844492477923682591
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name="configuration"
//JSON data structure with different audio parameters.
----------------------------414646844492477923682591
Content-Type: audio/wav; charset=utf-8
Content-Disposition: form-data; name="audio"
<audio_data>
----------------------------414646844492477923682591--

不太確定如何發送流(!!) <audio_data> 我嘗試使用Okio以這種方式為音頻創建多部分(來自: https : //github.com/square/okhttp/wiki/Recipes#post-streaming

public RequestBody createPartForAudio(final byte[] samples){
        RequestBody requestBody = new RequestBody() {
            @Override
            public MediaType contentType() {
                return MediaType.parse("audio/wav; charset=utf-8");
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                //Source source = null;
                sink.write(samples);        

            }
        };

        return requestBody;
    }

這當然沒有用。 這是繼續將音頻樣本寫入ResponseBody的正確方法嗎? 我到底應該在哪里調用Service.post(config, audio)方法,這樣我就不會在每次音頻緩沖區中有東西時都結束發布配置文件。

另外,由於必須繼續發送流音頻,因此如何保持相同的POST連接保持打開狀態,直到用戶停止講話才將其關閉?

我基本上是OkHttp和Okio的新手。 如果我錯過了任何內容或部分代碼不清楚,請讓我知道,我將上傳該代碼段。 謝謝。

您也許可以使用Pipe從音頻線程中產生數據並在網絡線程中使用它。

通過新創建的OkHttp配方

/**
 * This request body makes it possible for another
 * thread to stream data to the uploading request.
 * This is potentially useful for posting live event
 * streams like video capture. Callers should write
 * to {@code sink()} and close it to complete the post.
 */
static final class PipeBody extends RequestBody {
  private final Pipe pipe = new Pipe(8192);
  private final BufferedSink sink = Okio.buffer(pipe.sink());

  public BufferedSink sink() {
    return sink;
  }

  @Override public MediaType contentType() {
    ...
  }

  @Override public void writeTo(BufferedSink sink) throws IOException {
    sink.writeAll(pipe.source());
  }
}

如果您的數據可以連續寫入,則此方法最有效。 如果不能,那么最好用BlockingQueue<byte[]>或類似的方法做些類似的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM