我正在嘗試制定一個記錄音頻的例子,數據存儲由應用程序處理,而不是MediaRecorder
。使用情況包括將記錄存儲在內部存儲器上或加密記錄。任何人都有MediaRecorder使用ParcelFileDescriptor和createPipe()?
原則上,這應該使用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,我有一個關於在'MediaPlayer'中使用'createPipe()'的相關問題:http://stackoverflow.com/questions/12920429/anyone-have-mediaplayer-working-with-parcelfiledescriptor-and-createpipe – CommonsWare
你解決了這個問題嗎? – Teocci
@Teocci:不,Android O的'ProxyFileDescriptorCallback' *可能會在這裏有所幫助,但僅限於Android O及更高版本。基本上,管道不會產生可尋求的流。 – CommonsWare