[英]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.