データストレージをアプリではなくアプリで処理して、音声を録音する例を見つけようとしていMediaRecorder
ます。ユースケースには、記録を内部ストレージに保存することや、記録を暗号化することが含まれます。
createPipe()
原則として、これはonによって作成されたパイプを使用して機能するはずParcelFileDescriptor
ですが、出力が正しくありません。
まず、これは、を使用して「自然に」記録し、外部ストレージの出力ファイルに直接書き込むサンプルプロジェクトです。このアプリは問題なく動作し、出力は、記録されたAndroidデバイスまたはLinuxボックスのVLCのいずれかで再生できます。MediaRecorder
MediaRecorder
これがこのプロジェクトの私のcreatePipe()
バリエーションです。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);
}
}
}
2番目のアプリを実行すると、16進エディターによる大まかな検査では、基本的に問題ないように見える出力ファイルが得られます。IOW、それはゼロバイトのファイルではないか、認識できないジブリッシュでいっぱいです。最初のアプリからの出力と同様の種類のジブリッシュでいっぱいです。ただし、AndroidもVLCも再生できません。
推測しなければならないのですが、パイプからの読み取りで何かを台無しにしていると思いますが、具体的にどこが間違っているのかわかりません。
助言がありますか?
前もって感謝します!