SurfaceViewに常にカメラのプレビューを表示したい
タイトル通り、SurfaceViewに対してApplication起動と同時にカメラを起動し、常にプレビューを表示し続けたいのですが、録画機能を持たせるために、MediaRecorderを用いています。
Androidを初めて2ヶ月ちょっとなので何もわかっていないのですが、感覚として、
Camera APIを用いる場合とMediaRecorder APIを用いる場合とでは、向き不向きがあるような気がしています。現状のコードでは、改善したい点が複数あるので改善のためにお力添えをお願いします。
改善したい点
①起動時から常にカメラ映像をSurfaceViewに表示していたい(録画終了後も)
②カメラの取得する映像をインカメラ(サブカメラ?)から取得したい
③オートフォーカス機能を実装し、常にオートフォーカスをしていたい
②、③はCamera APIに依るところが大きいサンプルは複数見つけましたが、何とか改善したいです。よろしくお願いします。
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{
static MediaRecorder mRecorder;
static Camera mCamera;
static SurfaceHolder mHolder;
Button button1;
TextView text1;
SurfaceView mSurfaceView1;
static boolean isRecording = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRecorder =new MediaRecorder();
setContentView(R.layout.activity_main);
initRecorder();
mSurfaceView1 =(SurfaceView)findViewById(R.id.surfaceView1);
button1 =(Button)findViewById(R.id.button1);
text1 =(TextView)findViewById(R.id.textView1);
text1.setText("Now Standing By...");
mHolder =mSurfaceView1.getHolder();
mHolder.addCallback(this);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
mRecorder.stop();
isRecording = false;
initRecorder();
prepareRecorder();
text1.setText("Stop Recording");
button1.setText("Rec●");
} else {
text1.setText("Now Recording");
isRecording = true;
mRecorder.start();
button1.setText("Stop Rec");
}
}
});
}
public Camera getCameraInstance() {
mCamera = null;
try {
mCamera = Camera.open(1);
} catch (Exception e) {
e.printStackTrace();
}
return mCamera;
}
private void initRecorder() {
mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
String timeStamp =new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File pathExternalPublicDir= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM+File.separator+"VID_"+timeStamp+".mp4");
String dir =pathExternalPublicDir.getPath();
mRecorder.setOutputFile(dir);
mRecorder.setMaxDuration(60 * 1000);
mRecorder.setMaxFileSize(50 * 1000 * 1000);
}
private void prepareRecorder(){
mRecorder.setPreviewDisplay(mHolder.getSurface());
try {
mRecorder.prepare();
}catch(IllegalStateException e){
e.printStackTrace();
finish();
}catch(IOException e){
e.printStackTrace();
finish();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
try {
Camera.Parameters params = mCamera.getParameters();
List<String> focusList = params.getSupportedFocusModes();
for (int i = 0; i < focusList.size(); i++) {
Log.d("CameraFocusMode:", focusList.get(i));
}
params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
mCamera.setParameters(params);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.autoFocus(mAutoFocusListener);
}catch(Exception e){e.printStackTrace();}
}
private Camera.AutoFocusCallback mAutoFocusListener = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
camera.takePicture(null, null, null);
}
};
@Override
public void surfaceChanged(SurfaceHolder holder,int format,int w,int h){
}
@Override
public void surfaceDestroyed(SurfaceHolder holder){
if(isRecording){
mRecorder.stop();
isRecording=false;
}
mRecorder.release();
finish();
}
(一部抜粋)