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
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 ;-)
camera.setDisplayOrientation(90) does not work in all devices. Following solution work perfectly in different devices and also handling marshmallow runtime permission.
See setCameraRotation method
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public static int rotate;
private Context mContext;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mContext = context;
}
public void surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
stopPreview();
// set preview size and make any resize, rotate or
// reformatting changes here
setCamera(camera);
// start preview with new settings
startPreview();
}
public void stopPreview(){
try {
if(mCamera != null)
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
e.printStackTrace();
}
}
public void startPreview(){
try {
if(mCamera != null) {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}else{
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " );
}
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
/**
* add camera orientation and display rotation according to screen landscape or portrait
*/
setCameraRotation();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if(mCamera != null){
mCamera.release();
}
}
public void setCameraRotation() {
try {
Camera.CameraInfo camInfo = new Camera.CameraInfo();
if (VideoCaptureActivity.cameraId == 0)
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, camInfo);
else
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, camInfo);
int cameraRotationOffset = camInfo.orientation;
// ...
Camera.Parameters parameters = mCamera.getParameters();
int rotation = ((Activity)mContext).getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break; // Natural orientation
case Surface.ROTATION_90:
degrees = 90;
break; // Landscape left
case Surface.ROTATION_180:
degrees = 180;
break;// Upside down
case Surface.ROTATION_270:
degrees = 270;
break;// Landscape right
}
int displayRotation;
if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
displayRotation = (cameraRotationOffset + degrees) % 360;
displayRotation = (360 - displayRotation) % 360; // compensate
// the
// mirror
} else { // back-facing
displayRotation = (cameraRotationOffset - degrees + 360) % 360;
}
mCamera.setDisplayOrientation(displayRotation);
if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
rotate = (360 + cameraRotationOffset + degrees) % 360;
} else {
rotate = (360 + cameraRotationOffset - degrees) % 360;
}
parameters.set("orientation", "portrait");
parameters.setRotation(rotate);
mCamera.setParameters(parameters);
} catch (Exception e) {
}
}
}
Now prepare media recorder with correct rotation so that recorded video play in right orientation.
mediaRecorder.setOrientationHint(CameraPreview.rotate);
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOrientationHint(CameraPreview.rotate);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFile(filePath);
mediaRecorder.setMaxDuration(15000); // Set max duration 15 sec.
mediaRecorder.setMaxFileSize(10000000); // Set max file size 1M
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
You can download complete sample https://github.com/umesh-kushwaha/Android_Video_Recording_portrait