在設置MediaRecorder參數時有設置setVideoFrameRate(int rate)或者setVideoSize(int width, int height),這兩個方法代表設置錄製視頻的幀率和分辨率,關鍵在於需要手機硬件支持的,如果測試機的硬件不支持設置的參數就會無法start。
解決思路:查找手機支持的參數,選擇最合適的設置進去。
針對setVideoSize(int width, int height)來舉例:
通常在代碼中預覽佈局是SurfaceView,它的大小是可控的,我們可以在其getHolder.addCallback()裏獲取到寬度和高度:
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
//根據width和height去選取Camera最優預覽尺寸
}
獲取到SurfaceView寬高後,我們應該去選擇一個合適的預覽尺寸分辨率,選擇預覽尺寸的標準是(1)攝像頭支持的預覽尺寸的寬高比與SurfaceView的寬高比的絕對差值小於0.1;(2)在(1)獲得的尺寸中,選取與SurfaceView的高的差值最小的。這裏貼一下官方的代碼:
public Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
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) {
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;
}
在加載預覽畫面時,需要考慮Camera支持的尺寸(getSupportedPreviewSizes)和加載預覽畫面的SurfaceView的尺寸(layout_width/layout_height),在預覽階段,兩者之間的關係直接影響清晰度及圖像拉伸。對於Camera的尺寸,由於設備的硬件差異,不同設備支持的尺寸存在差異,但在默認情況(orientation=landscape)下,其width>height。以HTC609d爲例,Camera支持的分辨率爲1280*720(16:9)……640*480(4:3)……480*320(3:2)等十多種,而其屏幕的分辨率爲960*540(16:9)。因此,很容易得到以下結論:(1)當Camera預覽尺寸小於SurfaceView尺寸較多時,預覽畫面就不清晰;(2)Camera預覽尺寸寬高比與SurfaceView寬高比相差較大時,預覽畫面就會拉伸。
上述代碼在手機設置爲橫屏時並沒有問題,在設置爲豎屏時,爲獲得最優的預覽尺寸,需要在調用此方法前比較SurfaceView的寬高:
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes,
Math.max(width, height), Math.min(width, height));
}
獲得與當前SurfaceView匹配的預覽尺寸後,即可通過Camera.Parameters進行設置:
Camera.Parameters mParams = mCamera.getParameters();
mParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(mParams);
就醬~