【发布时间】:2012-10-05 09:19:45
【问题描述】:
我正在尝试制作一个录制音频的示例,数据存储由应用程序处理,而不是 MediaRecorder。用例包括将录音存储在内部存储器上或加密录音。
原则上,这应该使用createPipe() 在ParcelFileDescriptor 上创建的管道,但我得到的输出格式错误。
首先,here is a sample project 使用MediaRecorder“自然”记录,MediaRecorder 直接写入外部存储上的输出文件。这个应用程序运行良好,输出可以通过录制它的 Android 设备或我的 Linux 机器上的 VLC 播放。
Here is my createPipe() variation of this project。从一般的MediaRecorder配置来看(如setOutputFormat()),和第一个一样,所以代码大概是正确的。
但是,我通过以下方式提供输出:
recorder.setOutputFile(getStreamFd());
其中getStreamFd()使用createPipe(),产生一个后台线程从管道读取,并返回写入端供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 流到流复制例程,增强了刷新和同步输出文件的智能:
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,它不像是一个零字节的文件,或者充满了无法识别的乱码。它充满了与第一个应用程序的输出类似的乱码。但是,Android 和 VLC 都无法播放。
如果我不得不猜测,我会假设我在从管道读取时搞砸了,但我不确定具体哪里出错了。
有什么建议吗?
提前致谢!
【问题讨论】:
-
FWIW,我有一个关于使用
createPipe()和MediaPlayer的相关问题:stackoverflow.com/questions/12920429/… -
这个问题你解决了吗?
-
@Teocci:没有。Android O 的
ProxyFileDescriptorCallback可能在这里提供帮助,但仅限于 Android O 及更高版本。基本上,管道不会产生可搜索的流。 -
天啊,我有这个问题,因为我使用
MediaRecorder使用 RTP 协议流式传输视频。我尝试过使用 MediaCodec,但在 Android 中是否这么难。
标签: android android-mediarecorder