I record a video using the below code and it records perfectly, but when it plays the video, it plays it upside down.
I tried settings mrec.setOrientationHint(180)
before mrec.prepare();
but it was useless. Any hints?
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
/**
* @author SANA HASSAN
*/
public class CameraSurfaceView extends Activity {
private Preview mPreview;
private MediaRecorder mrec = new MediaRecorder();
private int cameraId = 0;
private Camera mCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mPreview = new Preview(this);
setContentView(mPreview);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "Start");
menu.add(0, 1, 0, "Stop");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
try {
startRecording();
}
catch (Exception e) {
e.printStackTrace();
mrec.release();
}
break;
case 1:
mrec.stop();
mrec.release();
mrec = null;
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
protected void startRecording() throws IOException {
mrec = new MediaRecorder();
mrec.setCamera(mCamera);
mCamera.unlock();
File directory = new File(Environment.getExternalStorageDirectory()+"/NICUVideos");
directory.mkdirs();
mrec.setAudioSource( MediaRecorder.AudioSource.MIC);
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mrec.setOutputFile(Environment.getExternalStorageDirectory()+"/NICUVideos/"+System.currentTimeMillis()+".mp4");
mrec.setPreviewDisplay(mPreview.getHolder().getSurface());
mrec.setVideoSize(640, 480);
Method[] methods = mrec.getClass().getMethods();
for (Method method: methods){
try{
if(method.getName().equals("setAudioEncodingBitRate")){
method.invoke(mrec, 12200);
}
else if(method.getName().equals("setVideoEncodingBitRate")){
method.invoke(mrec, 800000);
}
else if(method.getName().equals("setAudioSamplingRate")){
method.invoke(mrec, 8000);
}
else if(method.getName().equals("setVideoFrameRate")){
method.invoke(mrec, 20);
}
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
}
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mrec.setMaxDuration(60000); // 60 seconds
mrec.setMaxFileSize(10000000); // Approximately 10 megabytes
mrec.prepare();
mrec.start();
}
protected void stopRecording() {
mrec.stop();
mrec.release();
mCamera.release();
}
class Preview extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
Activity activity;
Preview(Activity activity) {
super(activity);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
Camera.CameraInfo info=new Camera.CameraInfo();
for (int i=0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
mCamera=Camera.open(i);
cameraId = i;
}
}
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
setCameraDisplayOrientation(mCamera);
mCamera.startPreview();
}
public void setCameraDisplayOrientation(Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = CameraSurfaceView.this.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
Log.d(Vars.TAG, "Result = "+result);
camera.setDisplayOrientation(result);
}
}
}
Most often, when a webcam is showing your image upside down, it is due to a device driver that is incompatible with your computer's operating system. Updating or changing the driver is your best bet for getting your topsy-turvy world back in check.
While the video plays, tap the screen once to bring up the options menu, then tap Edit. Scroll through the options at the bottom and tap Crop. In the Crop section, tap the middle rotate icon to rotate the video—repeat this until the video is rotated to the right position.
First, open you upside down video in QuickTime. Then head to Edit menu. There you will see 4 options about rotation, i.e., Rotate Left, Rotate Right, Flip Horizontal, and Flip Vertical. Rotate Left and Rotate Right would be all that we need for fixing upside down videos.
Try restarting your phone, maybe it's just a glitch. Or try using a different camera app and make sure auto rotate is enabled. Also try going to Settings > Apps > All > Camera > Clear data. Let me know how it goes.
I know your issue,
Video use Media Recorder
from Camera
, so you need rotate Media Recorder
. use below codes should be fixed your issue.
/**
*
* @param mMediaRecorder
* @return
*/
public static MediaRecorder rotateBackVideo(MediaRecorder mMediaRecorder) {
/**
* Define Orientation of video in here,
* if in portrait mode, use value = 90,
* if in landscape mode, use value = 0
*/
switch (CustomCamera.current_orientation) {
case 0:
mMediaRecorder.setOrientationHint(90);
break;
case 90:
mMediaRecorder.setOrientationHint(180);
break;
case 180:
mMediaRecorder.setOrientationHint(270);
break;
case 270:
mMediaRecorder.setOrientationHint(0);
break;
}
return mMediaRecorder;
}
Should add before prepare()
method :
// Step 5: Set the preview output
/**
* Define Orientation of image in here,
* if in portrait mode, use value = 90,
* if in landscape mode, use value = 0
*/
CustomCamera.mMediaRecorder = Utils.rotateBackVideo(CustomCamera.mMediaRecorder);
CustomCamera.mMediaRecorder.setPreviewDisplay(mCameraPreview.getHolder().getSurface());
Thank you
This should be called before the mrec.prepare();
method
setOrientationHint(degrees);
Link
EDIT:
Try mCamera.setDisplayOrientation(degrees);
0 for landscape
90 for portrait
180 & 270 don't work very well and give weird results.
Some older players and encoders do not interpret this flag which is why the video plays upside down.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With