簡體   English   中英

HttpUrlConnection - Android - 並行寫入輸出和讀取輸入

[英]HttpUrlConnection - Android - Write Output and Read Input in parallel

親愛的 Android 高級開發者 :)

我想開發一個應用程序,它以實時轉錄模式從麥克風錄制音頻並將注冊數據發送到 Speech To Text Web 服務。

所以我需要發出一個 HTTP 請求並保持這個請求以連續發送音頻數據並並行檢索轉錄結果。

我真的可以使用curl之類的工具來使用 API,但我真的很失望不能在 Java 中做到這一點。

你可以找到我在課堂上嘗試做的總結。 我正在嘗試使用 HttpUrlConnection,我不知道這是否是正確的方法。

我的問題如下:我可以在錄制時發送音頻,但是,一旦我激活readInputStream方法以並行讀取響應,連接就會關閉。

響應的標頭包含Transfer-Encoding: chunked

有一個更好的方法嗎?

謝謝你。

/* list of import hidden */

public class RecordAndStream {
    int SAMPLE_RATE = 8000;
    boolean record;
    URL url;
    HttpURLConnection httpURLConnection;
    InputStreamReader inputStreamReader;
    OutputStream outputStream;

    public void readInputStream() {
        try {
            InputStream inputStream = null;
            inputStream = new BufferedInputStream(this.httpURLConnection.getInputStream());
            this.inputStreamReader = new InputStreamReader(inputStream);

            int data = 0;
            data = this.inputStreamReader.read();
            String xml_result = "";
            while (data != -1) {
                xml_result += String.valueOf((char) data);
                data = this.inputStreamReader.read();
            }
            Log.d("LOG", "inputStreamReader=\n" + xml_result);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void sendAudioStream() {
        int bufferSize = AudioRecord.getMinBufferSize(this.SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        @SuppressLint("MissingPermission")
        AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
                this.SAMPLE_RATE,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                bufferSize);

        audioRecord.startRecording();
        short[] audioBuffer = new short[8192];
        while (this.record) {
            int numberOfShort = audioRecord.read(audioBuffer, 0, audioBuffer.length);
            ByteBuffer bfSTT = ByteBuffer.allocate(numberOfShort * 2);
            bfSTT.order(ByteOrder.LITTLE_ENDIAN);
            for (int z = 0; z < numberOfShort; z++) {
                bfSTT.putShort(audioBuffer[z]);
            }
            try {
                this.outputStream.write(bfSTT.array());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try {
            this.outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

        audioRecord.stop();
        audioRecord.release();

        this.httpURLConnection.disconnect();
    }


    public void stopRecord() {
        this.record = false;
    }

    public void startRecord() {
        this.record = true;
        // declaration d'une url
        try {
            this.url = new URL("https://sercice_url_to_call");
        } catch (MalformedURLException e) {
            Log.e("LOG", "MalformedURLException");
        }
        this.httpURLConnection = null;
        try {
            this.httpURLConnection = (HttpURLConnection) this.url.openConnection();
            this.httpURLConnection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString("xxx:YYY".getBytes(), Base64.NO_WRAP));
            this.httpURLConnection.setUseCaches(false);
            this.httpURLConnection.setRequestMethod("POST");
            this.httpURLConnection.setRequestProperty("Content-Type", "");
            this.httpURLConnection.setRequestProperty("Accept", "*/*");
            this.httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            this.httpURLConnection.setRequestProperty("Transfer-Encoding", "chunked");
            this.httpURLConnection.setRequestProperty("Expect", "100-continue");
            this.httpURLConnection.setRequestProperty("Accept-Encoding", "gzip");
        } catch (ProtocolException e) {
            Log.e("LOG", "ProtocolException");
        } catch (IOException e) {
            Log.e("LOG", "IOException");
        }

        try {
            //to tell the connection object that we will be wrting some data on the server and then will fetch the output result
            //this.httpURLConnection.setDoOutput(true);
            this.httpURLConnection.setDoOutput(true);
            this.httpURLConnection.setDoInput(true);
            // this is used for just in case we don't know about the data size associated with our request
            this.httpURLConnection.setChunkedStreamingMode(8192);
            // to write tha data in our request
            this.outputStream = new BufferedOutputStream(this.httpURLConnection.getOutputStream());
            // to read the data in the response

            new Thread((new Runnable() {
                protected RecordAndStream ref;

                public Runnable init(RecordAndStream ref) {
                    this.ref = ref;
                    return this;
                }

                @Override
                public void run() {
                    this.ref.readInputStream();
                }
            }).init(this)).start();

            sendAudioStream();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在測試了來自 Apache 基金會的 OkHttp 或 HttpClient 等幾種解決方案后,我沒有找到任何現成的解決方案。 所以我直接在一個簡單的Socket的Buffer中管理了自己的http層。 它工作得很好,我在流中接收時在流中發送。

暫無
暫無

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

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