0

У меня есть функция, которая вызывает службу камеры, которая начинает запись в фоновом режиме с использованием передней камеры. Требование состоит в том, чтобы показать одно и то же видео, записанное на поверхности. Это моя деятельностьAndroid - Запись видео в фоновом режиме и одновременное отображение видеозаписи в режиме Surface View

public class StartTestActivity extends Activity implements 
    SurfaceHolder.Callback { 
private static final String TAG = "Recorder"; 
public static SurfaceView mSurfaceView; 
public static SurfaceHolder mSurfaceHolder; 
public static Camera mCamera; 
public static boolean mPreviewRunning; 
boolean found = false; 
int i; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.start_test); 

    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview); 
    mSurfaceHolder = mSurfaceView.getHolder(); 
    mSurfaceHolder.addCallback(this); 
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    Button btnStart = (Button) findViewById(R.id.button1); 

    btnStart.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      Intent intent = new Intent(StartTestActivity.this, 
        RecorderService.class); 
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      startService(intent); 
      finish(); 

     } 
    }); 

    Button btnStop = (Button) findViewById(R.id.button2); 
    btnStop.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      stopService(new Intent(StartTestActivity.this, 
        RecorderService.class)); 
     } 
    }); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 


} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 

} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 


} 


} 

и это моя служба

public class RecorderService extends Service { 
    private static final String TAG = "RecorderService"; 
    private SurfaceView mSurfaceView; 
    private SurfaceHolder mSurfaceHolder; 
    private static Camera mServiceCamera; 
    private boolean mRecordingStatus; 
    private MediaRecorder mMediaRecorder; 
    boolean found = false; 
    int i; 

    @Override 
    public void onCreate() { 

     mRecordingStatus = false; 

     mSurfaceView = StartTestActivity.mSurfaceView; 
     mSurfaceHolder = StartTestActivity.mSurfaceHolder; 
     // Getting front camera id in i 
     for (i = 0; i < Camera.getNumberOfCameras(); i++) { 
      Camera.CameraInfo newInfo = new Camera.CameraInfo(); 
      Camera.getCameraInfo(i, newInfo); 
      if (newInfo.facing == CameraInfo.CAMERA_FACING_FRONT) { 
       found = true; 
       break; 
      } 
     } 
     mServiceCamera = Camera.open(i); 
     super.onCreate(); 
     if (mRecordingStatus == false) 
      if (startRecording()) { 
       Intent intent = new Intent(getBaseContext(), 
         StartTestActivity.class); 
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
       getApplication().startActivity(intent); 
      } 

    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
     stopRecording(); 
     mRecordingStatus = false; 

     super.onDestroy(); 
    } 

    public boolean startRecording() { 
     try { 
      Toast.makeText(getBaseContext(), "Recording Started", 
        Toast.LENGTH_SHORT).show(); 

      Camera.Parameters params = mServiceCamera.getParameters(); 
      mServiceCamera.setParameters(params); 
      Camera.Parameters p = mServiceCamera.getParameters(); 

      final List<Size> listSize = p.getSupportedPreviewSizes(); 
      Size mPreviewSize = listSize.get(2); 
      Log.v(TAG, "use: width = " + mPreviewSize.width + " height = " 
        + mPreviewSize.height); 
      p.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
      p.setPreviewFormat(PixelFormat.YCbCr_420_SP); 
      mServiceCamera.setParameters(p); 

      try { 
       mServiceCamera.setPreviewDisplay(mSurfaceHolder); 
       mServiceCamera.startPreview(); 
      } catch (IOException e) { 
       Log.e(TAG, e.getMessage()); 
       e.printStackTrace(); 
      } 

      mServiceCamera.unlock(); 
      mMediaRecorder = new MediaRecorder(); 

      mMediaRecorder.setCamera(mServiceCamera); 

      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
      mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); 

      mMediaRecorder.setOutputFile(Environment 
        .getExternalStorageDirectory() + "/video.mp4"); 

      mMediaRecorder.setVideoFrameRate(30); 
      mMediaRecorder 
        .setVideoSize(mPreviewSize.width, mPreviewSize.height); 
      mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 

      mMediaRecorder.prepare(); 
      mMediaRecorder.start(); 

      mRecordingStatus = true; 

      return true; 
     } catch (IllegalStateException e) { 
      Log.d(TAG, e.getMessage()); 
      e.printStackTrace(); 
      return false; 
     } catch (IOException e) { 
      Log.d(TAG, e.getMessage()); 
      e.printStackTrace(); 
      return false; 
     } 
    } 

    public void stopRecording() { 
     Toast.makeText(getBaseContext(), "Recording Stopped", 
       Toast.LENGTH_SHORT).show(); 
     try { 
      mServiceCamera.reconnect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     mMediaRecorder.stop(); 
     mMediaRecorder.reset(); 

     mServiceCamera.stopPreview(); 
     mMediaRecorder.release(); 

     mServiceCamera.release(); 
     mServiceCamera = null; 
    } 
} 

когда услуга была запущена управление возвращается к StartTestActivity (который имеет начало и кнопки и SurfaceView остановки) и передняя камера начинает запись видео, я просто хочу, чтобы можно было отображать текущее видеозапись в виде поверхности (только часть экрана, из-за которой оставшаяся часть может иметь изображение или текст) в действии, чтобы пользователь мог видеть себя во время записи. Проблема, с которой я столкнулся, заключалась в том, что камера уже используется для записи, и, следовательно, она заблокирована, если кто-нибудь может предложить мне работу вокруг, это будет большой помощью. Спасибо.

ответ

2

попробовать это, он работал отлично для меня :)

мой класс активности

public class CameraRecorder extends Activity implements SurfaceHolder.Callback { 
private static final String TAG = "Recorder"; 
public static SurfaceView mSurfaceView; 
public static SurfaceHolder mSurfaceHolder; 
public static Camera mCamera ; 
public static boolean mPreviewRunning; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1); 
    mSurfaceHolder = mSurfaceView.getHolder(); 
    mSurfaceHolder.addCallback(this); 
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    Button btnStart = (Button) findViewById(R.id.StartService); 
    btnStart.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      Intent intent = new Intent(CameraRecorder.this, RecorderService.class); 
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      startService(intent); 
      finish(); 
     } 
    }); 

    Button btnStop = (Button) findViewById(R.id.StopService); 
    btnStop.setOnClickListener(new View.OnClickListener() 
    { 
     public void onClick(View v) 
     { 
      stopService(new Intent(CameraRecorder.this, RecorderService.class)); 
     } 
    }); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 

} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 

} 
} 

и мой класс обслуживания для записи видео в фоновом режиме

public class RecorderService extends Service { 
    private static final String TAG = "RecorderService"; 
    private SurfaceView mSurfaceView; 
    private SurfaceHolder mSurfaceHolder; 
    private static Camera mServiceCamera; 
    private boolean mRecordingStatus; 
    private MediaRecorder mMediaRecorder; 

    @Override 
    public void onCreate() { 
     mRecordingStatus = false; 
     //mServiceCamera = CameraRecorder.mCamera; 
     mServiceCamera = Camera.open(); 
     mSurfaceView = CameraRecorder.mSurfaceView; 
     mSurfaceHolder = CameraRecorder.mSurfaceHolder; 

     super.onCreate(); 
     if (mRecordingStatus == false) 
      startRecording(); 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
     stopRecording(); 
     mRecordingStatus = false; 

     super.onDestroy(); 
    } 

    public boolean startRecording(){ 
     try { 
      Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show(); 

      //mServiceCamera = Camera.open(); 
      Camera.Parameters params = mServiceCamera.getParameters(); 
      mServiceCamera.setParameters(params); 
      Camera.Parameters p = mServiceCamera.getParameters(); 

      final List<Size> listSize = p.getSupportedPreviewSizes(); 
      Size mPreviewSize = listSize.get(2); 
      Log.v(TAG, "use: width = " + mPreviewSize.width 
         + " height = " + mPreviewSize.height); 
      p.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 
      p.setPreviewFormat(PixelFormat.YCbCr_420_SP); 
      mServiceCamera.setParameters(p); 

      try { 
       mServiceCamera.setPreviewDisplay(mSurfaceHolder); 
       mServiceCamera.startPreview(); 
      } 
      catch (IOException e) { 
       Log.e(TAG, e.getMessage()); 
       e.printStackTrace(); 
      } 

      mServiceCamera.unlock(); 

      mMediaRecorder = new MediaRecorder(); 
      mMediaRecorder.setCamera(mServiceCamera); 
      mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
      mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
      mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 
      mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
      mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); 
      mMediaRecorder.setOutputFile("/sdcard/video.mp4"); 
      mMediaRecorder.setVideoFrameRate(30); 
      mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height); 
      mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 

      mMediaRecorder.prepare(); 
      mMediaRecorder.start(); 

      mRecordingStatus = true; 

      return true; 
     } catch (IllegalStateException e) { 
      Log.d(TAG, e.getMessage()); 
      e.printStackTrace(); 
      return false; 
     } catch (IOException e) { 
      Log.d(TAG, e.getMessage()); 
      e.printStackTrace(); 
      return false; 
     } 
    } 

    public void stopRecording() { 
     Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show(); 
     try { 
      mServiceCamera.reconnect(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     mMediaRecorder.stop(); 
     mMediaRecorder.reset(); 

     mServiceCamera.stopPreview(); 
     mMediaRecorder.release(); 

     mServiceCamera.release(); 
     mServiceCamera = null; 
    } 
} 

Это создаст файл video.mp4 в вашей SD-карте. надеюсь, это поможет вам друг :)

+0

мой код уже записывается в фоновом режиме, это не мой вопрос, я хочу иметь возможность одновременно отображать записывающее видео (видео в реальном времени) в режиме просмотра поверхности. – hayath

+0

Я начал службу, после чего я переключился на другое приложение, а затем переключился обратно, сервис отверстий, похоже, не работал. и если бы я нажал кнопку stopService, существовала бы остановка времени выполнения, как [здесь] (http://stackoverflow.com/questions/15833694/mediarecorder-stop-stop-failed-1007) –

+0

Android-студия lint: не размещайте классы контекста Android в статических полях; это утечка памяти (а также прерывает Instant Run). Статическое поле будет утечка контекстов. – t0m

Смежные вопросы