2013-06-10 13 views
6

Próbuję zbudować podstawową kamerę wideo, która pozwoli użytkownikowi szybko pobierać filmy, dotykając ekranu. Wydaje się to proste, jednak głównym problemem, który napotkam, jest to, że Android MediaRecorder nie pozwala na szybki start i ponowne uruchomienie bez awarii, jeśli użytkownik strzela, a następnie zatrzymuje się, a następnie szybko wznawia fotografowanie ponownie, zawsze się zawiesza. Nie jestem pewien, czy istnieje sposób, aby to naprawić bezpośrednio, dlatego też wymyśliłem inną metodę osiągnięcia tego przez próbę aby nagrać pojedynczy film, ale próbuje uzyskać pewną kontrolę nad tym, kiedy plik multimedialny faktycznie zapisuje do pliku. jednak nie udało mi się tego w pełni uruchomić przy użyciu FileDescriptor, poniżej wkleję mój oryginalny kod i moją metodę, której użyłem w drugiej próbie kontrolowania pisania, czy jest jakiś sposób na dostosowanie kodu w celu osiągnięcia tej funkcji pause im po? Każda pomoc będzie przejść długą drogę, dziękiStart programu MediaRecorder(), jeśli zostanie wywołany zbyt szybko

Moja pierwsza próba przy użyciu wspólnego sposobu ustalania plik do 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)); 
     } 

    } 

} 
} 

Tu jest moja metoda z użyciem deskryptora pliku, to nie działa, stworzone tylko plik ale nie pisać do niego:

//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(); 
} 
+1

czy udało ci się coś zrobić? Mam ten sam problem ... po wielokrotnym zatrzymaniu i uruchomieniu rejestratora multimediów, po pewnym czasie na starcie() otrzymuję kod błędu "start failed -2147483648" ... – Hitman

Odpowiedz

0

połączeń cameraView.setClickable (true) po prepareRecorder() i wywołać cameraView.setClickable (fałszywego) przed wywołaniem prepareRecorder() na AsynkTask

Powiązane problemy