다음 기능으로 안드로이드에서 응용 프로그램을 개발하려고합니다 : 사용자가 전경에 다른 응용 프로그램을 가지고 있더라도 비디오 및 오디오를 자연스럽게 녹화하십시오. 일반적인 시나리오는 사용자가 앱을 열고 녹화를 시작한 다음 탐색 앱을 열거 나 전화를받는 것입니다. 내 앱에을 계속 녹음하고 싶습니다.안드로이드 - 백그라운드에서 비디오 녹화
주로 아래에 인용 될이 tutorial에서 영감을받은 몇 가지 코드를 조합했습니다. 나는 그러나 두 가지 문제를 발생했습니다 :
1. 나는 "집"키, 비디오 녹화 정지를 누르면,하지만 응용 프로그램을 다시 이동하면 소리가, 미리보기
2. 잘 때
내 질문 검은 색은된다
- 내 목표는 안드로이드에 수 있습니까?
- 무엇이 잘못 되었나요?
내 코드 :
public class GlobalState extends Application {
\t private boolean recording = false;
\t private boolean loggingEnabled = true;
\t private Camera serviceCamera = null;
\t private CameraPreview cameraPreview = null;
\t @Override
\t public void onCreate() {
\t \t try {
\t \t \t serviceCamera = Camera.open();
\t \t } catch (Exception e) {
\t \t }
\t \t super.onCreate();
\t }
\t public boolean isRecording() {
\t \t return recording;
\t }
\t public boolean isLoggingEnabled() {
\t \t return loggingEnabled;
\t }
\t public void setRecording(boolean recording) {
\t \t this.recording = recording;
\t }
\t public void setCamera(Camera serviceCamera) {
\t \t this.serviceCamera = serviceCamera;
\t }
\t public Camera getCamera() {
\t \t return serviceCamera;
\t }
\t public void setCameraPreview(CameraPreview cameraPreview) {
\t \t this.cameraPreview = cameraPreview;
\t }
\t public CameraPreview getCameraPreview() {
\t \t return this.cameraPreview;
\t }
}
public class CameraPreview extends SurfaceView implements
\t \t SurfaceHolder.Callback {
\t private SurfaceHolder mHolder;
\t private Camera mCamera;
\t private static final String TAG = "CameraPreview";
\t public CameraPreview(Context context, Camera camera) {
\t \t super(context);
\t \t mCamera = camera;
\t \t mHolder = getHolder();
\t \t mHolder.addCallback(this);
\t \t mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
\t }
\t public void surfaceCreated(SurfaceHolder holder) {
\t \t try {
\t \t \t mCamera.setPreviewDisplay(holder);
\t \t \t mCamera.startPreview();
\t \t } catch (IOException e) {
\t \t \t Log.d(TAG, "Error setting camera preview: " + e.getMessage());
\t \t }
\t }
\t public void surfaceDestroyed(SurfaceHolder holder) {
\t }
\t public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
\t \t if (mHolder.getSurface() == null) {
\t \t \t return;
\t \t }
\t \t try {
\t \t \t mCamera.stopPreview();
\t \t } catch (Exception e) {
\t \t }
\t \t try {
\t \t \t mCamera.setPreviewDisplay(mHolder);
\t \t \t mCamera.startPreview();
\t \t } catch (Exception e) {
\t \t \t Log.d(TAG, "Error starting camera preview: " + e.getMessage());
\t \t }
\t }
}
public class MainActivity extends Activity {
\t public String TAG = "DE-MainActivity";
\t ImageView mRecordView;
\t ImageView mMenuButtonView;
\t LinearLayout mMenuView;
\t TextView mVideosTextView;
\t TextView mSettingsTextView;
\t private Camera mCamera;
\t private CameraPreview mPreview;
\t GlobalState mAppState = null;
\t @Override
\t protected void onCreate(Bundle savedInstanceState) {
\t \t super.onCreate(savedInstanceState);
\t \t setContentView(R.layout.activity_main);
\t \t mAppState = (GlobalState) getApplicationContext();
\t \t if (mAppState.isLoggingEnabled()) {
\t \t \t Log.v(TAG, "Activity: onCreate");
\t \t }
\t \t mCamera = mAppState.getCamera();
\t \t if (mAppState.getCameraPreview() == null) {
\t \t \t mPreview = new CameraPreview(this, mCamera);
\t \t \t mAppState.setCameraPreview(mPreview);
\t \t }
\t \t FrameLayout preview = (FrameLayout) findViewById(R.id.fl_camera);
\t \t preview.addView(mPreview);
\t \t mMenuView = (LinearLayout) findViewById(R.id.ll_menu_list);
\t \t mVideosTextView = (TextView) findViewById(R.id.tv_menu_item_videos);
\t \t mSettingsTextView = (TextView) findViewById(R.id.tv_menu_item_settings);
\t \t mRecordView = (ImageView) findViewById(R.id.iv_record);
\t \t mRecordView.setImageResource(R.drawable.btn_not_recording);
\t \t mRecordView.setAlpha((float) 0.5);
\t \t mRecordView.bringToFront();
\t \t mRecordView.setOnClickListener(new View.OnClickListener() {
\t \t \t @Override
\t \t \t public void onClick(View v) {
\t \t \t \t if (!mAppState.isRecording()) {
\t \t \t \t \t mRecordView.setImageResource(R.drawable.btn_recording);
\t \t \t \t \t mRecordView.setAlpha((float) 0.3);
\t \t \t \t \t startService(new Intent(MainActivity.this,
\t \t \t \t \t \t \t RecorderService.class));
\t \t \t \t } else {
\t \t \t \t \t mRecordView.setImageResource(R.drawable.btn_not_recording);
\t \t \t \t \t mRecordView.setAlpha((float) 0.5);
\t \t \t \t \t stopService(new Intent(MainActivity.this,
\t \t \t \t \t \t \t RecorderService.class));
\t \t \t \t }
\t \t \t }
\t \t });
\t \t mMenuButtonView = (ImageView) findViewById(R.id.iv_menu);
\t \t mMenuButtonView.setImageResource(R.drawable.btn_menu);
\t \t mMenuButtonView.setAlpha((float) 0.5);
\t \t mMenuButtonView.bringToFront();
\t \t mMenuButtonView.setOnClickListener(new View.OnClickListener() {
\t \t \t @Override
\t \t \t public void onClick(View v) {
\t \t \t \t if (mMenuView.getVisibility() == View.VISIBLE) {
\t \t \t \t \t mMenuView.setVisibility(View.INVISIBLE);
\t \t \t \t } else {
\t \t \t \t \t mMenuView.setVisibility(View.VISIBLE);
\t \t \t \t }
\t \t \t }
\t \t });
\t \t mSettingsTextView.setOnClickListener(new View.OnClickListener() {
\t \t \t @Override
\t \t \t public void onClick(View v) {
\t \t \t \t if (mAppState.isLoggingEnabled())
\t \t \t \t \t Log.v(TAG, "settings clicked!");
\t \t \t }
\t \t });
\t \t mVideosTextView.setOnClickListener(new View.OnClickListener() {
\t \t \t @Override
\t \t \t public void onClick(View v) {
\t \t \t \t if (mAppState.isLoggingEnabled())
\t \t \t \t \t Log.v(TAG, "videos clicked!");
\t \t \t }
\t \t });
\t }
\t @Override
\t protected void onDestroy() {
\t \t if (mAppState.isLoggingEnabled())
\t \t \t Log.v(TAG, "APPLICATION EXIT!");
\t \t if (mCamera != null) {
\t \t \t mCamera.release(); // release the camera for other applications
\t \t \t mCamera = null;
\t \t }
\t \t super.onDestroy();
\t }
\t public boolean onCreateOptionsMenu(Menu menu) {
\t \t if (mMenuView.getVisibility() == View.VISIBLE) {
\t \t \t mMenuView.setVisibility(View.INVISIBLE);
\t \t } else {
\t \t \t mMenuView.setVisibility(View.VISIBLE);
\t \t }
\t \t return false;
\t }
}
public class RecorderService extends Service {
\t private static final String TAG = "RecorderService";
\t private static Camera mServiceCamera;
\t private MediaRecorder mMediaRecorder;
\t private GlobalState mAppState;
\t public static final int MEDIA_TYPE_IMAGE = 1;
\t public static final int MEDIA_TYPE_VIDEO = 2;
\t @Override
\t public void onCreate() {
\t \t mAppState = (GlobalState) getApplicationContext();
\t \t mServiceCamera = mAppState.getCamera();
\t \t if (mAppState.isLoggingEnabled())
\t \t \t Log.v(TAG, "onCreate");
\t }
\t @Override
\t public int onStartCommand(Intent intent, int flags, int startId) {
\t \t super.onStartCommand(intent, flags, startId);
\t \t if (!mAppState.isRecording()) {
\t \t \t if (prepareVideoRecorder()) {
\t \t \t \t mMediaRecorder.start();
\t \t \t \t mAppState.setRecording(true);
\t \t \t } else {
\t \t \t \t releaseMediaRecorder();
\t \t \t }
\t \t }
\t \t return 5;
\t }
\t @Override
\t public IBinder onBind(Intent intent) {
\t \t return null;
\t }
\t @Override
\t public void onDestroy() {
\t \t if (mAppState.isLoggingEnabled())
\t \t \t Log.v(TAG, "onDestroy");
\t \t // stop recording and release camera
\t \t mMediaRecorder.stop(); // stop the recording
\t \t releaseMediaRecorder(); // release the MediaRecorder object
\t \t mServiceCamera.lock(); // take camera access back from MediaRecorder
\t \t mAppState.setRecording(false);
\t \t super.onDestroy();
\t }
\t private void releaseMediaRecorder() {
\t \t if (mMediaRecorder != null) {
\t \t \t mMediaRecorder.reset(); // clear recorder configuration
\t \t \t mMediaRecorder.release(); // release the recorder object
\t \t \t mMediaRecorder = null;
\t \t }
\t }
\t /** Create a file Uri for saving an image or video */
\t private static Uri getOutputMediaFileUri(int type) {
\t \t return Uri.fromFile(getOutputMediaFile(type));
\t }
\t /** Create a File for saving an image or video */
\t private static File getOutputMediaFile(int type) {
\t \t File mediaStorageDir = new File(
\t \t \t \t Environment.getExternalStorageDirectory(), "DashEyeApp");
\t \t if (!mediaStorageDir.exists()) {
\t \t \t if (!mediaStorageDir.mkdirs()) {
\t \t \t \t Log.d("MyCameraApp", "failed to create directory");
\t \t \t \t return null;
\t \t \t }
\t \t }
\t \t String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
\t \t \t \t .format(new Date());
\t \t File mediaFile;
\t \t if (type == MEDIA_TYPE_IMAGE) {
\t \t \t mediaFile = new File(mediaStorageDir.getPath() + File.separator
\t \t \t \t \t + "IMG_" + timeStamp + ".jpg");
\t \t } else if (type == MEDIA_TYPE_VIDEO) {
\t \t \t mediaFile = new File(mediaStorageDir.getPath() + File.separator
\t \t \t \t \t + "VID_" + timeStamp + ".mp4");
\t \t } else {
\t \t \t return null;
\t \t }
\t \t return mediaFile;
\t }
\t private boolean prepareVideoRecorder() {
\t \t mMediaRecorder = new MediaRecorder();
\t \t mServiceCamera.unlock();
\t \t mMediaRecorder.setCamera(mServiceCamera);
\t \t mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
\t \t mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
\t \t mMediaRecorder.setProfile(CamcorderProfile
\t \t \t \t .get(CamcorderProfile.QUALITY_HIGH));
\t \t mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
\t \t \t \t .toString());
\t \t // Step 5: Set the preview output
\t \t // mMediaRecorder.setPreviewDisplay(mAppState.getCameraPreview().getHolder().getSurface());
\t \t try {
\t \t \t mMediaRecorder.prepare();
\t \t } catch (IllegalStateException e) {
\t \t \t Log.d(TAG,
\t \t \t \t \t "IllegalStateException preparing MediaRecorder: "
\t \t \t \t \t \t \t + e.getMessage());
\t \t \t releaseMediaRecorder();
\t \t \t return false;
\t \t } catch (IOException e) {
\t \t \t Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
\t \t \t releaseMediaRecorder();
\t \t \t return false;
\t \t }
\t \t return true;
\t }
}