Próbuję opracować przykład nagrywania dźwięku, a pamięć danych jest obsługiwana przez aplikację, a nie MediaRecorder
. Przypadki użycia obejmują przechowywanie nagrania w pamięci wewnętrznej lub szyfrowanie nagrania.Ktoś ma MediaRecorder Praca z ParcelFileDescriptor i createPipe()?
W zasadzie to powinno działać przy użyciu rury utworzonej przez createPipe()
na ParcelFileDescriptor
, ale jestem coraz wyjście nieprawidłowy.
Najpierw here is a sample project który rejestruje „naturalnie” za pomocą MediaRecorder
z MediaRecorder
pisząc bezpośrednio do pliku wyjściowego na pamięci zewnętrznej. Ta aplikacja działa dobrze, a dane wyjściowe mogą być odtwarzane przez urządzenie z Androidem, które je nagrało lub VLC na moim komputerze z systemem Linux.
Here is my createPipe()
variation of this project. Z punktu widzenia ogólnej konfiguracji MediaRecorder
(np. setOutputFormat()
), jest taka sama jak pierwsza, więc kod jest prawdopodobnie poprawny.
Jestem jednak dostarczanie wyjście poprzez:
recorder.setOutputFile(getStreamFd());
Gdzie getStreamFd()
wykorzystuje createPipe()
, spawns wątek tła do czytania z rury, i zwraca się do końca pisania dla wykorzystania przez 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
to klasyczna procedura kopiowania strumieniowego do strumienia, wzbogacona o sprytne elementy do wypróżniania i synchronizowania pliku wyjściowego:
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);
}
}
}
Po uruchomieniu drugiej aplikacji otrzymuję plik wyjściowy, który w wyniku surowej inspekcji za pomocą edytora szesnastkowego wydaje się być w zasadzie prawidłowy. IOW, to nie jest plik zero-bajtowy lub jest wypełniony nierozpoznawalnym bełkotem. Jest wypełniony podobnym bełkotem, podobnie jak wyjście z pierwszej aplikacji. Jednak ani Android, ani VLC nie mogą go odtworzyć.
Gdybym miał zgadywać, to przypuszczam, że jestem przekręcane coś w czytaniu z rury, ale nie jestem pewien, gdzie specjalnie jadę źle.
Wszelkie sugestie?
Z góry dziękuję!
FWIW mam powiązane pytanie na temat używania 'createPipe()' 'MediaPlayer' z: http://stackoverflow.com/questions/12920429/anyone-have-mediaplayer-working-with-parcelfiledescriptor-and-createpipe – CommonsWare
Czy rozwiązałeś ten problem? – Teocci
@Teocci: Nie. "ProxyFileDescriptorCallback" Androida O * może * pomóc tutaj, ale tylko na Androidzie O i wyższym. Zasadniczo, rury nie dają widocznych strumieni. – CommonsWare