Я создаю приложение простого диктофона. Я хочу динамически изменять SurfaceView, когда он начинает запись. Например, когда пользователь устанавливает разрешение видео в соотношении 4: 3 заранее в активности настроек и нажимает кнопку «начать запись», я хочу, чтобы SurfaceView менял его ширину и высоту в соотношении 4: 3. Таким образом, SurfaceView меняет свой размер при нажатии кнопки записи.android - Как я могу изменить размер SurfaceView динамически?
Я могу изменить размер SurfaceView, когда приложение ничего не записывает, но когда я пытаюсь изменить его прямо перед началом записи видео, оно меняет размер изображения, но запись не выполнена должным образом (он прекращает отмену ошибки при завершении записи).
Я хочу, чтобы мое приложение изменяло размер 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<Camera.Size> 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<Camera.Size> 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()
метод, когда приложение не записи, он изменяет вид отлично; но когда я запускаю его при нажатии кнопки записи, это временно замораживает пользовательский интерфейс, и видеовыход не сохраняется должным образом. Возможно ли, что основной поток перегружен?
Заранее спасибо.
Это должно помочь! http://stackoverflow.com/questions/20491499/resizing-surface-view-for-aspect-ratio-change-in-video-display-in-android – acac97
@ acac97 Я уже видел и реализовал этот вопрос .. он отлично работает, когда приложение ничего не записывает, но я хочу изменить размер SurfaceView, когда пользователь нажимает кнопку StartRecording. –
Также убедитесь, что вы прошли через эти шаги https://developer.android.com/reference/android/hardware/Camera.html – acac97