我正在构建一个简单的记录器应用程序。我想在开始记录时动态调整SurfaceView的大小。例如,当用户在设置活动中预先将视频分辨率设置为4:3的比例并点击'开始录制'按钮时,我希望SurfaceView将它的宽度和高度更改为4:3的比例。所以当按下录制按钮时,SurfaceView会改变它的大小。android-如何动态调整SurfaceView的大小?
当应用程序没有录制任何东西时,我可以调整SurfaceView的大小,但是当我在录制开始之前尝试更改它时,它调整了视图的大小,但录制没有正确完成(录制完成时它会引发stopFailed错误。)
我希望我的应用能够调整SurfaceView的大小,然后开始记录。在用户按下录制按钮之前!
这是我的代码。
MainActivity.java
private boolean prepRecorder() {
mRecorder = new MediaRecorder();
CamcorderProfile profile = getCurrentProfile();
Camera.Parameters parameters = mCamera.getParameters();
parameters = setContinuesFocusMode(parameters);
Camera.Size desiredSize = null, optimalPreviewSize = null;
if (mVideoSizeIndex != -1) {
List supportedVidSizes = parameters.getSupportedVideoSizes();
if (mVideoSizeIndex < supportedVidSizes.size()) {
desiredSize = supportedVidSizes.get(mVideoSizeIndex);
optimalPreviewSize = mSurface.getOptimalPreviewSize(
parameters.getSupportedPreviewSizes(), desiredSize.width, desiredSize.height);
Point screenSize = getScreenSize();
mSurface.resizePreview(optimalPreviewSize.width, optimalPreviewSize.height, screenSize.x, screenSize.y);
parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
}
} else {
parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
}
mCamera.setParameters(parameters);
mCamera.unlock();
mRecorder.setCamera(mCamera);
mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setProfile(profile);
mRecorder.setPreviewDisplay(mSurface.getHolder().getSurface());
mVideoPath = getMediaPath();
if (mVideoPath != null) {
mRecorder.setOutputFile(mVideoPath);
} else {
return false;
}
if (desiredSize != null) {
mRecorder.setVideoSize(desiredSize.width, desiredSize.height);
} else {
mRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
}
// Orientation adjustment stuff.....
mTrackerThread = new VideoFileTrackerThread(new Handler(), this, mVideoPath);
mTrackerThread.start();
mTrackerThread.prepareHandler();
mTrackerThread.triggerHandler();
try {
mRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
VideoSurfaceView.java
public void resizePreview(int desiredWidth, int desiredHeight, int screenWidth, int screenHeight) {
float videoProportion = (float) desiredWidth/(float) desiredHeight;
float screenProportion = (float) screenWidth/screenHeight;
ViewGroup.LayoutParams lp = this.getLayoutParams();
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) ((float) screenWidth/videoProportion);
} else {
lp.width = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
this.setLayoutParams(lp);
}
public Camera.Size getOptimalPreviewSize(List sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w/h;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.Size size : sizes) {
if (size.width == w && size.height == h) {
optimalSize = size;
return optimalSize;
}
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 (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
当运行resizePreview()方法时,应用程序不记录,它完美地改变视图;但是当我按下录制按钮时运行它时,它会冻结UI一段时间,并且视频输出未正确保存。主线程是否可能超载?
在此先感谢。
+0
这应该有帮助! http://stackoverflow.com/questions/20491499/resizing-surface-view-for-aspect-ratio-change-in-video-display-in-android –
+0
@ acac97我已经看到并实现了这个问题..它在应用程序不记录任何内容时工作正常,但我想在用户按下StartRecording按钮时调整SurfaceView的大小。 –
+0
还要确保你已经通过了这些步骤 https://developer.android.com/reference/android/hardware/Camera.html –