1.質問:
まず、私のアプリケーションシナリオMediacodecは、カメラストリームと画面記録ストリームを使用し、それらを切り替えてから、完全なビデオを記録します。つまり、カメラから画面、カメラ、そして画面へと、要件を比較します。。。携帯電話の画面を記録して記録する必要があるため、実際の解像度を直接使用することはできません。したがって、camera.getParameters()から幅と高さを取得し、出力ビデオの解像度に設定します。多くの携帯電話で録画されたビデオの画面が縮小するという現象がありますが、実際には黒い境界線が原因です。したがって、問題は実際には画面記録の出力ビデオ解像度に基づいており、他のほとんどの画面記録ソリューションも適用できます。
2.分析
ほとんどの携帯電話で取得されるカメラの解像度は、画面の解像度と一致していません。重要なことは、たとえば、アスペクト比が異なることです。カメラの解像度は1920 * 1080、携帯電話の解像度は2340 * 1080です。画面を記録するときにビデオが出力されます。最初の記録は全画面で記録する必要があります。つまり、幅は2340で、2番目のビデオはトリミングされません。 、したがって、最終的に1920 * 1080を出力する必要があります。その幅は自然に減少し、高さは比例して減少します。その後、黒い境界線が上下に塗りつぶされます。実際、ビデオの最終出力は1920 * 1080です。小さく見える理由は、黒い境界線が上下に塗りつぶされているためです。
したがって、カメラでサポートされている解像度を1つずつ確認し、比率を1つずつ計算して、いくつかのルールを見つけ、携帯電話を変更してから、この一連の操作を実行してから、変更する必要があります。ワンステップ携帯電話。。。
幸いなことに、私はあなたのためにそれをしました。
3.治療
電話機の実際の画面比率に最も近い、カメラでサポートされている解像度の値を見つけます
実際、携帯電話でサポートされているビデオ解像度から検出されますが、カメラも使用されているため、ビデオサポートにはカメラサポートとカメラサポート以上のものが含まれているため、カメラサポートを探す必要があります。つまり、List <Camera.Size> prviewSizeList = myParameters.getSupportedPreviewSizes();カメラを開かない場合は、List <Camera.Size> videoSizeList = myParameters.getSupportedVideoSizes();から検索してみてください。以下はコアコードです
public void initCamera() {
getScreenSize();
//注:摄像头相关的设置不写了,省的看混
............
Camera.Parameters myParameters = myCamera.getParameters();
//获取摄像头支持的分辨率
List<Camera.Size> prviewSizeList = myParameters.getSupportedPreviewSizes();
//获取手机支持的视频分辨率
//List<Camera.Size> videoSizeList = myParameters.getSupportedVideoSizes();
//获取最接近的分辨的索引
int selectIndex = bestVideoSize(prviewSizeList);
............
//设置相机预览尺寸
//TODO 在你设置视频大小的地方也是用这里计算出来的值,以为我设置录制视频分辨率的地方不在,
//这,不过也是取得这里的值,所以就不写了
myParameters.setPreviewSize(prviewSizeList.get(selectIndex).width,prviewSizeList.get(selectIndex).height);
}
int mRealSizeWidth;//手机屏幕真实宽度
int mRealSizeHeight;//手机屏幕真实高度
/**
* 查找最接近屏幕宽高比的参数
* @param cameraSizeList
* @return
*/
public int bestVideoSize(List<Camera.Size> cameraSizeList) {
if (cameraSizeList == null) {
return -1;
}
//计算屏幕的实际分辨率的比值
float realRatio = ((float) mRealSizeWidth / (float) mRealSizeHeight);
int index = 0;//目标索引
float outRatio = -1f;
for (int i = 0; i < cameraSizeList.size(); i++) {
if (cameraSizeList.get(i).height <= mRealSizeHeight) {//取的值高度不能高于屏
//幕真实高度
float ratio = (float) (cameraSizeList.get(i).width) / (float) (cameraSizeList.get(i).height);
if (outRatio == -1f) {
outRatio = Math.abs(ratio / realRatio - 1);
index = i;
} else {
if (outRatio > Math.abs(ratio / realRatio - 1)) {
//取绝对值小的值,即选择与屏幕分辨率最接近的值
index = i;
outRatio = Math.abs(ratio / realRatio - 1);
}else if (outRatio == Math.abs(ratio / realRatio - 1)) {
//如果有两组长宽比完全一样的,选择height比较大,小的可能会视频模糊
if (cameraSizeList.get(i).height >= cameraSizeList.get(index).height) {
index = i;
outRatio = Math.abs(ratio / realRatio - 1);
}
}
}
}
}
return index;
}
//计算屏幕真实分辨率
public void getScreenSize() {
WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point outPoint = new Point();
if (Build.VERSION.SDK_INT >= 19) {
// 可能有虚拟按键的情况
display.getRealSize(outPoint);
} else {
// 不可能有虚拟按键
display.getSize(outPoint);
}
mRealSizeHeight = outPoint.y;
mRealSizeWidth = outPoint.x;
}
注:水平スクリーンを記録したので、高さを比較します。垂直スクリーンの場合は、幅を使用するのが最適です。
Androidフォンのさまざまな解像度の問題については詳しく説明しません。すべてをテストすることはできません。手元にある一連のフォンをテストした後、(電話機のカメラを除いて)完璧な結果が得られました。画面比率と同じ解像度をサポートします。そうでない場合、フルスクリーンにはほとんどならず、最終的な効果は電話によってわずかに異なります。適切でない場合は、bestVideoSize()メソッドで制限できます。値の高さの範囲は、この方向で考慮されます。