Я пытаюсь выработать пример записи звука, при этом хранилище данных обрабатывается приложением, а не MediaRecorder
. Варианты использования включают хранение записи на внутренней памяти или шифрование записи.
В принципе, это должно работать, используя канал, созданный createPipe()
на ParcelFileDescriptor
, но я получаю неверный вывод.
Во-первых, вот пример проекта, который записывает "естественно" с помощью MediaRecorder
, при этом MediaRecorder
записывается непосредственно в выходной файл на внешнее хранилище. Это приложение работает отлично, и выход может воспроизводиться либо устройством Android, либо записанным, либо VLC на моем Linux-боксе.
Вот мой вариант 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);
}
}
}
Когда я запускаю второе приложение, я получаю выходной файл, который, путем грубой проверки через шестнадцатеричный редактор, кажется, в основном ОК. IOW, это не нравится файл с нулевым байтом или заполняется неузнаваемой тарабарщиной. Он заполнен подобным тиснением, как и выход из первого приложения. Тем не менее, ни Android, ни VLC не могут его воспроизвести.
Если бы я должен был догадаться, я бы предположил, что я что-то вникаю в чтение из трубы, но я не уверен, где конкретно я ошибаюсь.
Любые предложения?
Спасибо заранее!