Reputation: 41
In short, I'm looking for a way to get the byte stream from the camera while recording video. The aim is to continuously record while saving certain portions of the current recording without stopping the actual recording process to access the output file. Is this even possible, or will I need to actually stop the recording and save it for it be playable?
I've seen projects and open source library's that allow live streaming from the camera to a server via a local socket and the ParcelFileDescriptor class, so I assume (maybe incorrectly) that the recorder byte stream must be accessible somehow.
Any suggestions or help would be greatly appreciated.
Upvotes: 4
Views: 3071
Reputation: 938
I had a similiar problem and wanted to record H264 in an MP4 file while accessing the H264 NAL units camera byte stream (redirect it to libRTMP). The following example helped alot (requires at least Android 4.3):
http://bigflake.com/mediacodec/ <- the CameraToMpegTest.java and "Android Breakout game recorder patch" examples
Basically, Androids MediaCodec class provides low level access to the device encoders/decoders. Take a look at the function drainEncoder() of the examples above:
Example:
int old_pos = encodedData.position();
encodedData.position(0);
byte[] encoded_array = new byte[encodedData.remaining()];
encodedData.get(encoded_array);
encodedData.position(old_pos);
Upvotes: 1
Reputation: 316
Set output file to FileDescriptor:
mRecorder.setOutputFile(getStreamFd());
Then use this function:
private FileDescriptor getStreamFd() {
ParcelFileDescriptor[] pipe = null;
try {
pipe = ParcelFileDescriptor.createPipe();
new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(pipe[0]),
new FileOutputStream(getOutputFile())).start();
} catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
}
return (pipe[1].getFileDescriptor());
}
private File getOutputFile() {
return (new File(Environment.getExternalStorageDirectory().getPath().toString() + "/YourDirectory/filename"));
}
New thread code:
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);
}
}
}
Don't forget to add persmissions to your manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Upvotes: 1