2014-10-13 3 views
0

다음 기능으로 안드로이드에서 응용 프로그램을 개발하려고합니다 : 사용자가 전경에 다른 응용 프로그램을 가지고 있더라도 비디오 및 오디오를 자연스럽게 녹화하십시오. 일반적인 시나리오는 사용자가 앱을 열고 녹화를 시작한 다음 탐색 앱을 열거 나 전화를받는 것입니다. 내 앱에을 계속 녹음하고 싶습니다.안드로이드 - 백그라운드에서 비디오 녹화

주로 아래에 인용 될이 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 } 
 
}
,312,

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 } 
 
}
나는 텍스트의 벽에 죄송 내가 크게 도움을 주셔서 감사합니다!

답변

0

그것은 안드로이드 미리보기가 파괴 가도록 을 좋아하지 않는 것으로 나타났다 (예를 들어, 사용자는 "홈"버튼을 칠 때) 그래서 비디오 녹화를 잘라냅니다.

이 문제를 해결하려면 WindowManager를 사용하여 오버레이를 설정하고 사용자가 "홈"버튼을 눌렀을 때 1x1 크기로 조정하십시오. 솔루션 here을 찾았습니다. cman에게 감사드립니다!

1
내 솔루션 괜찮

는 그것을 시도 :

서비스 안드로이드 :

import java.util.Calendar; 

import android.app.Service; 
import android.content.Context; 
import android.content.Intent; 
import android.graphics.PixelFormat; 
import android.hardware.Camera; 
import android.hardware.Camera.CameraInfo; 
import android.media.CamcorderProfile; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.view.Gravity; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.WindowManager; 
import android.view.WindowManager.LayoutParams; 

public class BackgroundVideoRecorder extends Service implements 
    SurfaceHolder.Callback { 

private WindowManager windowManager; 
private SurfaceView surfaceView; 
private Camera camera = null; 
private MediaRecorder mediaRecorder = null; 



int contTime = 0, duracaoGravacao = 30; //interval in seconds to record video 

private class thread implements Runnable { 
    public void run() { 

     contTime++; 

     if (contTime >= duracaoGravacao) { 
      StopService(); 
     } 

     tick_Handler.postDelayed(tick_thread, 1000); 
    } 
} 

Handler tick_Handler; 
thread tick_thread; 

Preferences pref; 

@Override 
public void onCreate() { 

    windowManager = (WindowManager) this 
      .getSystemService(Context.WINDOW_SERVICE); 
    surfaceView = new SurfaceView(this); 
    LayoutParams layoutParams = new WindowManager.LayoutParams(1, 1, 
      WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
      WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, 
      PixelFormat.TRANSLUCENT); 
    layoutParams.gravity = Gravity.LEFT | Gravity.TOP; 
    windowManager.addView(surfaceView, layoutParams); 

    surfaceView.getHolder().addCallback(this); 

    tick_Handler = new Handler(); 
    tick_thread = new thread(); 

    VIDEO_RECORDER_FOLDER = new _Path().getPathVideo(); 

} 

@Override 
public void onStart(Intent intent, int startId) { 

    tick_Handler.post(tick_thread); 

} 

// Method called right after Surface created (initializing and starting 
// MediaRecorder) 
@Override 
public void surfaceCreated(SurfaceHolder surfaceHolder) { 

    boolean found = false; 

    int i = 0; 

    try { 
     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; 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    if (found) { 
     camera = Camera.open(i); 
    } else { 
     camera = Camera.open(); 
    } 

    Calendar lCDateTime = Calendar.getInstance(); 

    String t = String.valueOf(lCDateTime.getTimeInMillis()); 

    nomeArquivo = "hire_me_now_" + t + ".mp4"; 

    nomeArquivo = nomeArquivo.replace(" ", "_").replace(":", "_") 
      .replace("-", "_"); 

    String caminhoArquivo = VIDEO_RECORDER_FOLDER + "/" + nomeArquivo; 

    mediaRecorder = new MediaRecorder(); 
    camera.unlock(); 

    mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 
    mediaRecorder.setCamera(camera); 
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
    mediaRecorder.setProfile(CamcorderProfile 
      .get(CamcorderProfile.QUALITY_QVGA)); 
    mediaRecorder.setVideoFrameRate(15); 

    mediaRecorder.setOutputFile(caminhoArquivo); 

    try { 
     mediaRecorder.prepare(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    mediaRecorder.start(); 
} 

// Stop recording and remove SurfaceView 
@Override 
public void onDestroy() { 

    mediaRecorder.stop(); 
    mediaRecorder.reset(); 
    mediaRecorder.release(); 

    camera.lock(); 
    camera.release(); 

    windowManager.removeView(surfaceView); 

} 

protected void StopService() { 
    try { 
     this.stopSelf(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

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

@Override 
public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

}