gpt4 book ai didi

Android MediaRecorder 纵横比不正确

转载 作者:搜寻专家 更新时间:2023-11-01 08:52:14 25 4
gpt4 key购买 nike

我的 Android 应用程序中的 MediaRecorder 的宽高比有问题。我特别遇到三星 Galaxy S II 的问题,与普通相机相比,它的摄像机似乎放大了(这是我在手机上使用默认相机应用程序时注意到的一种行为)。

在这个视频中,当我从使用相机切换到使用 MediaRecorder 时,您可以看到长宽比是如何拉伸(stretch)的:

https://www.youtube.com/watch?v=U8vCwiNjCPU

在下面的截图中:

相机纵横比(正确):

Camera aspect ratio

视频纵横比(不正确):

Video aspect ratio

如何确保视频预览的宽高比正确?

这是我的代码:

CustomCamera Activity :

public class CustomCamera extends SherlockActivity {

private boolean prepareVideoRecorder() {
Log.d(TAG, "in prepareVideoRecorder()");
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if (camera == null)
{
camera = getCameraInstance();
}

if (recorder == null){
recorder = new MediaRecorder();
}

//Have to stop preview before starting to record
camera.stopPreview();
// Step 1: Unlock and set camera to MediaRecorder
camera.unlock();
recorder.setCamera(camera);

// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

// Step 4: Set output file
recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath());

// No limit. Don't forget to check the space on disk.
recorder.setMaxDuration(50000);
recorder.setVideoFrameRate(30);
recorder.setVideoEncodingBitRate(3000000);
recorder.setAudioEncodingBitRate(8000);

// Step 5: Set the preview output
recorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());

//Setting the camera's orientation
int degree = 0;
// do not rotate image, just put rotation info in
switch (mOrientation) {
case ORIENTATION_LANDSCAPE_INVERTED:
degree = 180;
break;
case ORIENTATION_PORTRAIT_NORMAL:
degree = 90;
break;
case ORIENTATION_LANDSCAPE_NORMAL:
degree = 0;
break;
case ORIENTATION_PORTRAIT_INVERTED:
degree = 270;
break;
}

recorder.setOrientationHint(degree);

// Step 6: Prepare configured MediaRecorder
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
e.printStackTrace();
return false;
}
//Everything went successfully
return true;
}


}

/**
* Method used to set the camera preview's parameters to match the
* phone's width and set the height accordingly to assure that there are
* no aspect ratio issues.
*/
private void setHolderParameters() {
Log.d(TAG, "setting camera layout parameters");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;

Size mPreviewSize = CameraPreview.getOptimalPreviewSize(camera.getParameters().getSupportedPreviewSizes(), width, height);
double ratio = ((double)mPreviewSize.width)/mPreviewSize.height;

FrameLayout.LayoutParams previewParams = new FrameLayout.LayoutParams(width, (int)(width*ratio));

cameraPreview.setLayoutParams(previewParams);
}

/**
* Open the camera asynchronously to reduce the lag when opening
* activity
*/
public void openCameraAsync(){
new AsyncTask<Object, Object, Object>(){
@Override
protected Object doInBackground(Object... arg0) {
if (!isFinishing()){
//Resuming camera and display when resuming
if(camera == null){
Log.d(TAG, "Resuming with a null camera");
camera = getCameraInstance();
}
}
return null;
}

@Override
protected void onPostExecute(Object result){
setHolderParameters();
cameraPreview.setCamera(camera);

//Calling surface created so that the preview of the camera is correct
cameraPreview.surfaceCreated(cameraPreview.getHolder());
}
}.execute();
}

CameraPreview.java:

public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
Log.d(TAG, "getOptimalPreviewSize");
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w/h;

if (sizes==null) return null;

Size optimalSize = null;

double minDiff = Double.MAX_VALUE;

int targetHeight = h;

// Find size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}

if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
Log.d(TAG, "targetRatio: " + targetRatio);
Log.d(TAG, "optimalSize: " + optimalSize);
return optimalSize;
}

public void setRecorder(MediaRecorder recorder){
this.recorder = recorder;
}

最佳答案

正在设置任何 Camera.Parameters ?您需要使用 setPreviewSize(int width, int height)并将其设置为视频的宽度和高度。

在你的MediaRecorder ,您可能还需要使用 setVideoSize(int,int)并(再次)设置为视频的大小。

我遇到了与您相同的问题,要获得视频的正确纵横比,布局大小、相机预览大小和 MediaRecorder 大小应具有相同的纵横比。当其中之一关闭时,通常会发生错误。

关于Android MediaRecorder 纵横比不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22105251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com