如何解决如何从录音机流式传输音频并同时另存为音频文件?
在audioRecorder使用OkHttp录制时,我想将音频流传输到服务器。同时,我想将音频记录为Android设备本地的音频文件。
这是我尝试的方法:
我如何录制音频:
private void startRecordAudio() {
audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,SAMPLE_RATE,CHANNEL,AUDIO_FORMAT,BUFFER_SIZE);
audioRecorder.startRecording();
recordingProgress.set(true);
recordingThread = new Thread(new StreamRecordingRunnable(),"Stream Recording");
recordingThread.start();
}
然后在StreamRecordingRunnable()
中这样做:
private class StreamRecordingRunnable implements Runnable{
@Override
public void run() {
final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
RequestBody requestBody = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse("audio/raw;encoding=signed-integer;bits=16;rate=8000;endian=little;");
}
@Override
public void writeTo(@NonNull BufferedSink sink) throws IOException {
while(recordingProgress.get()){
int result = audioRecorder.read(buffer,BUFFER_SIZE);
if(result < 0){
Log.d(LOG_TAG," Some streaming error here");
}else{
Log.d(LOG_TAG," No problem here");
writeAudioDataToFile(); // Here I want to save the audio file before it send to server.
sink.write(buffer);
buffer.clear();
}
}
}
};
Request request = httpRequestBuilder.post(requestBody).build();
try(Response response = httpClient.newCall(request).execute()){
if(response.isSuccessful()){
Log.v("OKHTTP",response.body().string());
}else{
Log.d("http not successful",String.valueOf(response.body()));
}
}catch (IOException e){
Log.d("HTTP",e.getMessage());
}
}
}
完成上述所有代码后,我可以在录音机开始录音的同时发送音频文件。我可以在服务器中获取音频文件。
我现在要做的是:
制作一个writeAudioDataToFile()
函数,希望它可以将音频(将发送到服务器)存储到本地Android设备中的本地文件中。
这是我为writeAudioDataToFile()
尝试的内容,应该存储在名为audiotest12345.wav
的文件中:
int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2;
String filePath;
private void writeAudioDataToFile() {
// Write the output audio in byte
filePath = getExternalCacheDir().getAbsolutePath();
filePath += "/audiorecordtest12345.wav";
short sData[] = new short[BufferElements2Rec];
FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (recordingProgress.get()) {
// gets the voice output from microphone to byte format
audioRecorder.read(sData,BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData,BufferElements2Rec * BytesPerElement);
Log.d("file name",filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
结果:
但是,这样做不仅没有在本地保存文件,而且还无法发送到服务器。在那里,我也尝试过:
private class StreamRecordingRunnable implements Runnable{
@Override
public void run() {
writeAudioDataToFile();
final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
//..all the RequestBody and networking call same as above
}
}
如果我只执行1个操作就意味着仅保存文件或仅发送到服务器,则该代码有效。但是,当我同时执行此操作时,将无法正常工作。
然后我从audiotest12345.wav
签入了文件路径adb shell
,该文件存在,但是当使用mediaPlayer播放时,文件路径为空。
这应该是因为1台设备中只能有1支麦克风。但是我不知道该怎么做才能同时完成两个操作
因此这是我的问题:
-
如何从录音机保存音频文件并将其同时发送到服务器?
-
我现在想的是,应该保存
BufferedSink
值中的数据吗?但是我不知道该怎么做,因为我是Okio的BufferedSink
的新手,所以不太了解它的含义。 -
因此,请尽可能说明
BufferedSink
的用途
请为我指出正确的方向。预先感谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。