问题描述
我试图找出记录音频的例子,与数据存储由应用程序来处理,而不是 MediaRecorder
。使用案例包括储存在内部存储器中的记录或加密的记录。
I am trying to work out an example of recording audio, with the data storage being handled by the app, not MediaRecorder
. Use cases include storing the recording on internal storage or encrypting the recording.
在原则上,这应该利用创建了一个管道createPipe()
在 ParcelFileDescriptor
,但我正在逐渐畸形的输出。
In principle, this should work using a pipe created by createPipe()
on ParcelFileDescriptor
, but I am getting malformed output.
首先,这里是一个示例项目中的记录自然地使用 MediaRecorder
,与 MediaRecorder
直接写入到外部存储的输出文件。这个程序工作得很好,并且输出可以通过Android设备的记录,或VLC在我的Linux机器上播放。
First, here is a sample project that records "naturally" using MediaRecorder
, with MediaRecorder
writing directly to an output file on external storage. This app works just fine, and the output can be played either by the Android device the recorded it or VLC on my Linux box.
这是我的 createPipe()
变化这个项目的。从一般的角度看 MediaRecorder
配置(例如, setOutputFormat()
),它是作为第一个相同,所以这code是presumably正确的。
Here is my createPipe()
variation of this project. From the standpoint of general MediaRecorder
configuration (e.g., setOutputFormat()
), it is the same as the first, so that code is presumably correct.
不过,我通过提供输出:
However, I am supplying the output via:
recorder.setOutputFile(getStreamFd());
其中, getStreamFd()
使用 createPipe()
,产生一个后台线程从管道中读取,并返回书写端,供 MediaRecorder
:
Where getStreamFd()
uses createPipe()
, spawns a background thread to read from the pipe, and returns the writing end for use by MediaRecorder
:
private FileDescriptor getStreamFd() {
ParcelFileDescriptor[] pipe=null;
try {
pipe=ParcelFileDescriptor.createPipe();
new TransferThread(new AutoCloseInputStream(pipe[0]),
new FileOutputStream(getOutputFile())).start();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
}
return(pipe[1].getFileDescriptor());
}
TransferThread
是一个经典的 java.io
流来流拷贝过程,增强与智慧冲洗和同步输出文件:
TransferThread
is a classic java.io
stream-to-stream copy routine, augmented with smarts to flush and sync the output file:
static class TransferThread extends Thread {
InputStream in;
FileOutputStream out;
TransferThread(InputStream in, FileOutputStream out) {
this.in=in;
this.out=out;
}
@Override
public void run() {
byte[] buf=new byte[8192];
int len;
try {
while ((len=in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.getFD().sync();
out.close();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(),
"Exception transferring file", e);
}
}
}
当我运行第二个应用程序,我得到的是,经由十六进制编辑器粗检查,似乎基本上是确定的输出文件。 IOW,它不喜欢它是一个零字节文件,或充满了无法识别的乱码。它填充有相类似乱码如从第一个应用程序的输出。然而,无论是安卓还是VLC可以玩。
When I run the second app, I get an output file that, by crude inspection via a hex editor, seems basically OK. IOW, it's not like it's a zero-byte file, or is filled with unrecognizable gibberish. It is filled with a similar sort of gibberish as is the output from the first app. However, neither Android nor VLC can play it.
如果我猜的话,我会presume,我把事情搞砸的东西从管道读,但我不知道具体在哪里我会错了。
If I had to guess, I would presume that I am screwing up something in reading from the pipe, but I am not sure where specifically I am going wrong.
有什么建议?
在此先感谢!
推荐答案
我猜想这是关系到我的回答您的其他问题。Anyone有MediaPlayer的工作与ParcelFileDescriptor和createPipe()?
I would guess this is related to my answer to your other question.Anyone Have MediaPlayer Working with ParcelFileDescriptor and createPipe()?
也许当MediaRecorder将寻求写报头信息,在管道关闭。
Probably when the MediaRecorder will seek to write the Header information, the pipe is closed.
如果您使用的:
recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
的记录工作得很好,因为它不会有标题信息,只原始音频
The record works fine, because it will not have a header information, only raw audio.
这篇关于任何人有MediaRecorder工作与ParcelFileDescriptor和createPipe()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!