I'm try to make custom video app. Iwork using settings in manifest 2.2 only (API 8).
All goes well but I don't understand why portrait mode video does not differ from lanscape one.
To make detection of device changed orientation I use this code within surfaceChanged()
if (mCamera != null) {
Camera.Parameters p = mCamera.getParameters();
try {
mCamera.stopPreview();
} catch (Exception e) {
// TODO: handle exception
}
int previewWidth = 0;
int previewHeight = 0;
if (mPreviewSize != null) {
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
switch (rotation) {
case Surface.ROTATION_0:
previewWidth = mPreviewSize.height;
previewHeight = mPreviewSize.width;
mCamera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
mCamera.setDisplayOrientation(0);
break;
case Surface.ROTATION_180:
previewWidth = mPreviewSize.height;
previewHeight = mPreviewSize.width;
mCamera.setDisplayOrientation(270);
break;
case Surface.ROTATION_270:
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
mCamera.setDisplayOrientation(180);
break;
}
p.setPreviewSize(previewWidth, previewHeight);
mCamera.setParameters(p);
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Cannot start preview.", e);
}
}
Works like a charm. If I rotate device surface change orientation, calling surfaceChanged, where camera is set to appropriate DisplayRotation.
The question is how to determine later if the video captured either in lanscape mode or in portrait one. As I got all the videos are captured in landscape orientation. It does not depend of setDisplayOrientation which affect only preview process.
Also exploring the problem I noticed that if to use standard Camera app it writes special tag to video file (seen in MediaInfo): Rotation : 90 for the portrait captured videos.
But MediaRecorder class does not.
Seems that is the problem. Anybody got to solve this?
Found it ! Indeed, you can change the preview, you can tag the video, but there's no way to actually change the video... (maybe a speed issue or something)
camera.setDisplayOrientation(90);
To rotate the preview, then
recorder.setOrientationHint(90);
To tag the video as having a 90° rotation, then the phone will automatically rotate it when reading.
So all you have to do is
camera = Camera.open();
//Set preview with a 90° ortientation
camera.setDisplayOrientation(90);
camera.unlock();
holder = getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
recorder = new MediaRecorder();
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setOutputFile(getVideoFolder()+rnd.nextString()+".mp4");
recorder.setPreviewDisplay(holder.getSurface());
//Tags the video with a 90° angle in order to tell the phone how to display it
recorder.setOrientationHint(90);
if (recorder != null) {
try {
recorder.prepare();
} catch (IllegalStateException e) {
Log.e("IllegalStateException", e.toString());
} catch (IOException e) {
Log.e("IOException", e.toString());
}
}
recorder.start();
Hope it helps ;-)