目前我正在公司进行一些关于 VoIP 应用的研究。
我们想要以 amr 格式录制设备麦克风的声音,对其加密并将数据发送到我们的服务器,对方从服务器接收数据进行解密和播放。为了一些测试案例,我目前使用 MediaRecorder 来记录 amr 格式的声音。因为我想要持续地传输当前的声音,所以我无法使用文件来存储数据。因此,我创建了一个管道,并将其作为文件描述符给了 MediaRecorder 引用。
MediaRecorder mediaRecorder = createMediaRecorder();
//make a pipe containing a read and write parcelFd
try {
ParcelFileDescriptor[] fdPair = ParcelFileDescriptor.createPipe();
//get a handle to your read and write fd objects
ParcelFileDescriptor readFd = fdPair[0];
ParcelFileDescriptor writeFd = fdPair[1];
//set the output to the write side of this pipe
mediaRecorder.setOutputFile(writeFd.getFileDescriptor());
//next create an input stream to read from the read side of the pipe.
FileInputStream reader = new FileInputStream(readFd.getFileDescriptor());
FileOutputStream writer = new FileOutputStream(writeFd.getFileDescriptor());
//now to fill up a buffer with data, only do a simple read
byte[] buffer = new byte[BUFSIZE];
mediaRecorder.prepare();
//by starting the mediarecorder, it will write into the writeFD
mediaRecorder.start();
Log.i(LOG_TAG, "Start Recording");
while(_isRecording){
int length = 0;
while((length = reader.read(buffer)) > 0){
writer.write(buffer, 0, length);
_audioListener.onAudioRecorded(buffer, 0, length);
}
}
Log.i(LOG_TAG, "Stop Recording");
writer.flush();
writer.close();
reader.close();
tearDownMediaRecorder(mediaRecorder);
} catch (IOException e) {
e.printStackTrace();
}
AudioListener 将读取的字节发送到我的 Activity,在那里我持有一个 MediaPlayer 实例,它应该读取数据并播放。我知道这听起来没有多大意义,但这只是为了测试如何在 MediaPlayer 中读取管道的内容。所以这就是我的 Activity 所做的事情。
ParcelFileDescriptor[] fdPair = ParcelFileDescriptor.createPipe();
_readFd = fdPair[0];
// _writer = new FileOutputStream(_writeFd.getFileDescriptor());
_reader = new FileInputStream(_readFd.getFileDescriptor());
_mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
_mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.i(LOG_TAG, "Media-Player Completed.");
}
});
_mediaPlayer.setOnErrorListener(new OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(LOG_TAG, "Error-What: " + what);
return false;
}
});
_mediaPlayer.setDataSource(_readFd.getFileDescriptor());
Log.i(LOG_TAG, "Set Source of MediaPlayer");
_mediaPlayer.prepare();
_mediaPlayer.start();
}
System.arraycopy(buffer, 0, mAudioTxBuffer, 0, bytesRead);
// 把接收到的音频数据写入writer _writer.write(mAudioTxBuffer); // 从reader中读取音频数据并存储在mAudioTxBuffer中 _reader.read(mAudioTxBuffer);
目前,如果我想播放接收到的字节,MediaPlayer将抛出以下异常:
09-18 10:38:10.785: W/System.err(12136): java.io.IOException: setDataSourceFD failed.: status=0x80000000
我目前不确定是我的理解有误还是代码存在漏洞。
谢谢你的帮助。