Как записать видео определенной ширины и высоты на Android-устройстве Samsung?
Здравствуйте, я делаю приложение для Android, в котором я использую пользовательскую камеру для записи камеры. У меня проблема с устройством Samsung. Я не могу установить профиль устройства записи мультимедиа на CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_HIGH)
также, когда попробуйте использовать
profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
profile.videoFrameHeight=360;
profile.videoFrameWidth=640;
тогда мое приложение работает на некоторых устройствах, но вылетает на многих устройствах. Любая помощь будет заметна. Заранее спасибо, пожалуйста, проверьте код
Camera.Parameters param = mCamera.getParameters();
param.set( "cam_mode", 1 );
// Enable video stabilization. Convenience methods not available in API
// level <= 14
String vstabSupported = param.get("video-stabilization-supported");
if ("true".equals(vstabSupported)) {
param.set("video-stabilization", "true");
}
List<Size> sizes = mCamera.getParameters() .getSupportedVideoSizes();
mCamera.setParameters( param );
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
String deviceMan = android.os.Build.MANUFACTURER;
Toast.makeText(getApplicationContext(), deviceMan, Toast.LENGTH_SHORT).show();
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
CamcorderProfile profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
// if(!CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)){Log.d("", "the camcorder profile instance is null");
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.FROYO){
// Do something for froyo and above versions
boolean tellbol=CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH);
if(deviceMan.equals("samsung")){
profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_LOW);
profile.videoFrameHeight=360;
profile.videoFrameWidth=640;
}
else{
profile = CamcorderProfile.get(cameraid, CamcorderProfile.QUALITY_HIGH);
}
mMediaRecorder.setProfile(profile);
} else{
// do something for phones running an SDK before froyo
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// mMediaRecorder.setVideoSize(720, 480);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
}
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: Set the preview output
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("Video", "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d("Video", "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
2 ответа
Это происходит потому, что вы запрашиваете измерения, которые хотите, но не каждая камера способна на каждое измерение.
Кроме того, некоторые устройства работают с немного отличающимися пропорциями камеры, поэтому, если вы запрашиваете прямоугольник с неправильным соотношением или с размерами, отличными от поддерживаемых, на некоторых устройствах произойдет сбой.
Что делать?
Шаг 1.
Вы должны проверить поддерживаемые размеры. Вы можете сделать это с
Camera.Parameters p = myCamera.getParameters();
List<Size> previewsizes = p.getSupportedPreviewSizes();
List<Size> videosizes = p.getSupportedVideoSizes();
и тогда вы можете выбрать один. Если вы хотите автоматизировать это, вы можете пойти дальше и следовать
Шаг 2
напишите функцию для выбора наилучшего доступного размера, который получит поддерживаемые размеры и желаемый размер, например:
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
Log.d("Camera", "Checking size " + size.width + "w " + size.height
+ "h");
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);
}
}
// Cannot find the one match the aspect ratio, ignore the
// requirement
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);
}
}
}
return optimalSize;
}
И последний шаг, установите параметры
Шаг 3
private int desiredwidth=640, desiredheight=360;
Size optimalPreviewSize = getOptimalPreviewSize(previewsizes, desiredwidth, desiredheight);
Size optimalVideoSize = getOptimalPreviewSize(videosizes, desiredwidth, desiredheight);
p.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSize(optimalVideoSize.width, optimalVideoSize.height);
myCamera.setParameters(p);
При этом ваше приложение камеры будет работать на каждом устройстве с камерой!
ОБНОВИТЬ
С помощью getOptimalPreviewSize, который я написал, вы получите размер, отношение которого ближе к желаемому, и, если ни один из них не достаточно хорош, вы получите тот, высота которого близка к желаемому. если вы хотите придать больше значения размеру, вы можете легко изменить что-то вроде
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
if ( you want ratio as closed to what i asked for)
{ for (Size size : sizes) {
Log.d("Camera", "Checking size " + size.width + "w " + size.height
+ "h");
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 (you want height as closed to what i asked for) { //you can do other for width
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
if (you want the bigest one) {
minDiff = 0;
for (Size size : sizes) {
if ( size.height * size.width > minDiff ) {
optimalSize = size;
minDiff = size.height * size.width ;
}
}
}
return optimalSize;
}
С помощью параметров вы можете установить ширину и высоту просмотра видео.
Camera.Parameters param = camera.getParameters();
param.setPreviewSize("your width"
"your height");
camera.setParameters(param);