Sto provando a costruire un camcorder di base che permetta all'utente di fare video rapidamente toccando lo schermo, questo sembrava semplice ma il problema principale che ho incontrato è che Android MediaRecorder non consente l'avvio rapido e il riavvio senza crash, se l'utente spara e poi si ferma e riprende rapidamente lo scatto si blocca sempre Im non sono sicuro se c'è un modo per risolvere direttamente questo quindi ho anche escogitato un altro metodo per raggiungere questo tentativo per registrare un singolo video ma cercando di ottenere un certo controllo su quando il mediaRecorder scrive effettivamente sul file. tuttavia non ero in grado di farlo funzionare completamente con FileDescriptor, di seguito incollerò il mio codice originale e il mio metodo che ho usato nel secondo tentativo di controllo della scrittura, c'è un modo per regolare entrambi i codici per ottenere quella funzionalità di pausa dopo? qualsiasi aiuto andrà un lungo cammino grazieMediaRecorder start() fallisce se chiamato troppo velocemente
Il mio primo tentativo con il modo comune di impostazione di un file da setOutPutFile():
public class MainActivity extends Activity implements SurfaceHolder.Callback {
public static final String LOGTAG = "VIDEOCAPTURE";
private MediaRecorder recorder;
private SurfaceHolder holder;
private CamcorderProfile camcorderProfile;
private Camera camera;
boolean recording = false;
boolean usecamera = true;
boolean previewRunning = false;
double timer = 0;
ProgressBar pb;
boolean neverEnd;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
setContentView(R.layout.activity_main);
pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setProgress(0);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
recording = true;
new recordVideo().execute();
Log.v(LOGTAG, "Recording Started");
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
recording = false;
return true;
}
return false;
}
});
}
private void prepareRecorder() {
recorder = new MediaRecorder();
recorder.setPreviewDisplay(holder.getSurface());
if (usecamera) {
camera.unlock();
recorder.setCamera(camera);
}
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setProfile(camcorderProfile);
Calendar calendarTime = Calendar.getInstance();
//initial attempt using a file path with setoutputfile
File file = new File(Environment.getExternalStorageDirectory(),
String.valueOf(calendarTime.getTimeInMillis()) + ".mp4");
if (camcorderProfile.fileFormat == MediaRecorder.OutputFormat.THREE_GPP) {
recorder.setOutputFile(file.getAbsolutePath());
} else if (camcorderProfile.fileFormat == MediaRecorder.OutputFormat.MPEG_4) {
recorder.setOutputFile(file.getAbsolutePath());
} else {
recorder.setOutputFile(file.getAbsolutePath());
}
// recorder.setMaxDuration(50000); // 50 seconds
// recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
boolean initialized = false;
while (!initialized) {
try {
recorder.prepare();
initialized = true;
} catch (IllegalStateException e) {
e.printStackTrace();
// finish();
initialized = false;
} catch (IOException e) {
e.printStackTrace();
// finish();
initialized = false;
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v(LOGTAG, "surfaceCreated");
if (usecamera) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
} catch (IOException e) {
Log.e(LOGTAG, e.getMessage());
e.printStackTrace();
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.v(LOGTAG, "surfaceChanged");
if (!recording && usecamera) {
if (previewRunning) {
camera.stopPreview();
}
try {
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(camcorderProfile.videoFrameWidth,
camcorderProfile.videoFrameHeight);
p.setPreviewFrameRate(camcorderProfile.videoFrameRate);
camera.setParameters(p);
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
} catch (IOException e) {
Log.e(LOGTAG, e.getMessage());
e.printStackTrace();
}
prepareRecorder();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v(LOGTAG, "surfaceDestroyed");
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
if (usecamera) {
previewRunning = false;
// camera.lock();
camera.release();
}
finish();
}
private class recordVideo extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
recorder.start();
while (recording) {
Thread.sleep(100);
publishProgress();
}
recorder.stop();
recorder.release();
recorder = null;
// recorder.release();
Log.v(LOGTAG, "Recording Stopped");
// Let's prepareRecorder so we can record again
prepareRecorder();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
if (recording) {
timer += 0.1;
pb.setProgress((int) (timer * 10));
}
}
}
}
Ecco il mio metodo che utilizza FileDescriptor, questo non ha funzionato, creato solo un file, ma non ha ancora scrivere ad esso:
//Pass it into setOutputFile() like this
recorder.setOutputFile(getStreamFd());
private FileDescriptor getStreamFd() {
ParcelFileDescriptor pipe = null;
try {
Calendar calendarTime = Calendar.getInstance();
File file = new File(Environment.getExternalStorageDirectory(),
String.valueOf(calendarTime.getTimeInMillis()) + ".mp4");
pipe = ParcelFileDescriptor.open(file,
ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_APPEND
| ParcelFileDescriptor.MODE_WORLD_WRITEABLE);
byte[] buf = new byte[1024];
int len;
FileOutputStream out = new FileOutputStream(FileDescriptor.out);
InputStream is = new FileInputStream(FileDescriptor.in);
while (usecamera) {
if(recordng){
out.write(buf, 0, len);
}
}
is.close();
out.close();
} catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
}
return pipe.getFileDescriptor();
}
sei riuscito a fare qualcosa? Ho lo stesso problema ... dopo aver ripetutamente fermato e avviato il registratore multimediale, dopo un po 'di tempo all'avvio() viene visualizzato il codice di errore "start failed -2147483648" ... – Hitman