Android MediaRecorder在纵向模式下捕获视频
我正在尝试制作自定义视频应用程序。我仅使用清单2.2(API 8)中的设置工作。 一切顺利,但我不明白为什么肖像模式视频和lanscape视频没有区别 为了检测设备改变的方向,我在surfaceChanged()中使用此代码 工作起来很有魅力。如果我旋转设备表面改变方向,调用surfaceChanged,其中相机设置为适当的DisplayRotation 问题是以后如何确定是在lanscape模式下还是在纵向模式下捕获视频。正如我得到的,所有的视频都是横向拍摄的。它不依赖于仅影响预览过程的setDisplayOrientation 在探索这个问题时,我注意到,如果使用标准摄像头应用程序,它会将特殊标记写入视频文件(见MediaInfo):旋转:90,用于拍摄人像视频 但MediaRecorder类没有 看来这就是问题所在。有人能解决这个问题吗?找到了! 事实上,你可以改变预览,你可以标记视频,但没有办法真正改变视频。。。(可能是速度问题或其他问题) 要旋转预览,请执行以下操作:Android MediaRecorder在纵向模式下捕获视频,android,video,orientation,mediarecorder,Android,Video,Orientation,Mediarecorder,我正在尝试制作自定义视频应用程序。我仅使用清单2.2(API 8)中的设置工作。 一切顺利,但我不明白为什么肖像模式视频和lanscape视频没有区别 为了检测设备改变的方向,我在surfaceChanged()中使用此代码 工作起来很有魅力。如果我旋转设备表面改变方向,调用surfaceChanged,其中相机设置为适当的DisplayRotation 问题是以后如何确定是在lanscape模式下还是在纵向模式下捕获视频。正如我得到的,所有的视频都是横向拍摄的。它不依赖于仅影响预览过程的set
recorder.setOrientationHint(90);
若要将视频标记为旋转90°,则手机将在阅读时自动旋转视频
所以你要做的就是
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();
希望有帮助;-) camera.setDisplayOrientation(90)不能在所有设备中工作。下面的解决方案在不同的设备上可以完美地工作,还可以处理marshmallow运行时权限 请参见设置摄影机旋转方法 现在准备好正确旋转的媒体录像机,以便以正确的方向播放录制的视频 mediaRecorder.setOrientationHint(CameraPreview.rotate) 专用布尔值prepareMediaRecorder(){
您可以下载完整的示例setOrientationHint仅适用于API 9。我也有同样的问题,但需要API 8的解决方案。我花了几个小时试图解决这个愚蠢的预览方向问题。非常感谢@Taiko!以下是对我有效的方法:在实现
SurfaceHolder.Cal的类的onCreate
方法中lback
我包括以下代码:mCamera=Camera.open();mCamera.setDisplayOrientation(90);mCamera.unlock();
后跟mediaRecorder=new mediaRecorder();mediaRecorder.setCamera(mCamera);
。效果很好!setOrientationHint没有帮助-视频是旋转的(请编辑此零件//创建曲面并启动相机预览,如果(mCamera==null){mCamera.setPreviewDisplay(holder);mCamera.startPreview();}它应该是mCamera!=null)
recorder.setOrientationHint(90);
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();
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) {
}
}
}
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;
}