- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我的 Android 应用程序中的 MediaRecorder 的宽高比有问题。我特别遇到三星 Galaxy S II 的问题,与普通相机相比,它的摄像机似乎放大了(这是我在手机上使用默认相机应用程序时注意到的一种行为)。
在这个视频中,当我从使用相机切换到使用 MediaRecorder 时,您可以看到长宽比是如何拉伸(stretch)的:
https://www.youtube.com/watch?v=U8vCwiNjCPU
在下面的截图中:
相机纵横比(正确):
视频纵横比(不正确):
如何确保视频预览的宽高比正确?
这是我的代码:
CustomCamera Activity :
public class CustomCamera extends SherlockActivity {
private boolean prepareVideoRecorder() {
Log.d(TAG, "in prepareVideoRecorder()");
// It is very important to unlock the camera before doing setCamera
// or it will results in a black preview
if (camera == null)
{
camera = getCameraInstance();
}
if (recorder == null){
recorder = new MediaRecorder();
}
//Have to stop preview before starting to record
camera.stopPreview();
// Step 1: Unlock and set camera to MediaRecorder
camera.unlock();
recorder.setCamera(camera);
// Step 2: Set sources
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath());
// No limit. Don't forget to check the space on disk.
recorder.setMaxDuration(50000);
recorder.setVideoFrameRate(30);
recorder.setVideoEncodingBitRate(3000000);
recorder.setAudioEncodingBitRate(8000);
// Step 5: Set the preview output
recorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());
//Setting the camera's orientation
int degree = 0;
// do not rotate image, just put rotation info in
switch (mOrientation) {
case ORIENTATION_LANDSCAPE_INVERTED:
degree = 180;
break;
case ORIENTATION_PORTRAIT_NORMAL:
degree = 90;
break;
case ORIENTATION_LANDSCAPE_NORMAL:
degree = 0;
break;
case ORIENTATION_PORTRAIT_INVERTED:
degree = 270;
break;
}
recorder.setOrientationHint(degree);
// Step 6: Prepare configured MediaRecorder
try {
recorder.prepare();
} catch (IllegalStateException e) {
// This is thrown if the previous calls are not called with the
// proper order
e.printStackTrace();
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
e.printStackTrace();
return false;
}
//Everything went successfully
return true;
}
}
/**
* Method used to set the camera preview's parameters to match the
* phone's width and set the height accordingly to assure that there are
* no aspect ratio issues.
*/
private void setHolderParameters() {
Log.d(TAG, "setting camera layout parameters");
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int width = metrics.widthPixels;
Size mPreviewSize = CameraPreview.getOptimalPreviewSize(camera.getParameters().getSupportedPreviewSizes(), width, height);
double ratio = ((double)mPreviewSize.width)/mPreviewSize.height;
FrameLayout.LayoutParams previewParams = new FrameLayout.LayoutParams(width, (int)(width*ratio));
cameraPreview.setLayoutParams(previewParams);
}
/**
* Open the camera asynchronously to reduce the lag when opening
* activity
*/
public void openCameraAsync(){
new AsyncTask<Object, Object, Object>(){
@Override
protected Object doInBackground(Object... arg0) {
if (!isFinishing()){
//Resuming camera and display when resuming
if(camera == null){
Log.d(TAG, "Resuming with a null camera");
camera = getCameraInstance();
}
}
return null;
}
@Override
protected void onPostExecute(Object result){
setHolderParameters();
cameraPreview.setCamera(camera);
//Calling surface created so that the preview of the camera is correct
cameraPreview.surfaceCreated(cameraPreview.getHolder());
}
}.execute();
}
CameraPreview.java:
public static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
Log.d(TAG, "getOptimalPreviewSize");
final double ASPECT_TOLERANCE = 0.05;
double targetRatio = (double) w/h;
if (sizes==null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Find size
for (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 (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
Log.d(TAG, "targetRatio: " + targetRatio);
Log.d(TAG, "optimalSize: " + optimalSize);
return optimalSize;
}
public void setRecorder(MediaRecorder recorder){
this.recorder = recorder;
}
最佳答案
正在设置任何 Camera.Parameters ?您需要使用 setPreviewSize(int width, int height)并将其设置为视频的宽度和高度。
在你的MediaRecorder ,您可能还需要使用 setVideoSize(int,int)并(再次)设置为视频的大小。
我遇到了与您相同的问题,要获得视频的正确纵横比,布局大小、相机预览大小和 MediaRecorder 大小应具有相同的纵横比。当其中之一关闭时,通常会发生错误。
关于Android MediaRecorder 纵横比不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22105251/
我正在为 chrome 商店构建一个屏幕录像机插件。我是 将麦克风的音轨添加到媒体流 包含( 屏幕的视频轨道 + 系统音频轨道 )。所以最终流包含 2 个音轨,一个是麦克风,另一个是系统音频。 当我将
当我尝试在我的程序中制作摄像机时,出现此错误: E/MediaRecorder﹕ start failed: -19 代码是 try { final SurfaceView sv = (Sur
const [rec, setRec] = useState({}); const [onRec, setOnRec] = useState(true); useEffect(() => {
这段代码在 Debug模式下工作得很好,但当不是 Debug模式时它总是抛出运行时异常。 mMediaRecorder.stop(); 根据 Java 文档: Stops recordin
当我尝试为我的 MediaRecorder 设置视频大小时,我在启动方法中收到 RuntimeException。 mRecorder.setAudioSource(MediaRecorder.Aud
录制音频是一个很长的操作,所以我启动mRecorder?.start()在服务内的协程中,您可以看到 RecordService.kt。 我调用 suspend fun startRecord(){.
使用媒体记录器,我可以在 azure 上上传和附加视频 blob。但是无法使用以下代码在下载时查找组合视频 - var chunks =[]; var mediaRecorder = new Medi
我在我的应用程序中集成了摄像头。当用户单击捕获按钮时,我隐藏了工具栏,以便摄像头预览屏幕尺寸增加。这会导致应用程序在停止在线录制时崩溃 - mMediaRecorder.stop(); 。 java.
我想在按住按钮时使用 MediaRecorder 开始录制语音消息。尝试在 onLongClickListener 中开始录制时出现 IllegalStateException。 如堆栈跟踪中所述,我
我的应用需要录制最长 8 秒的视频。这已经通过 MediaRecorder.setMaxDuration(long milliseconds) 实现。该应用还需要顶部的进度条和带有剩余时间倒计时的标签
使用时 CanvasCaptureMediaStream和 MediaRecorder,有没有办法在每一帧上获取一个事件? 我需要的和 requestAnimationFrame() 没什么不同,但我
我正在尝试使用媒体录音机来录制音频。我让它工作,以便我能够录制和播放。唯一的问题是我无法记录程序第二次崩溃的情况。我有一个单独的方法来重置 MediaRecorder,但无论我将它放在哪里,它都不起作
我正在使用 MediaRecorder 录制视频,但似乎无论我使用什么设置,帧率都令人震惊(~ 1fps) 这是我的代码: recorder.setAudioSource(MediaRecor
如果我使用 MediaRecorder.AudioSource.MIC 声音会正常录制。如果 MediaRecorder.AudioSource.VOICE_DOWNLINK 声音以慢速播放。我需要它
我查看了其他人遇到的这个问题,但没有找到合适的解决方案。像他们一样,我遵循了相机功能教程:http://developer.android.com/guide/topics/media/camera.
我正在准备一个小型 Android 应用程序,用于捕获用户的照片和录音。用户会用他的相机拍照,然后在查看该照片时添加音频评论。 为了捕捉音频,我正在使用 MediaRecorder [因为 andro
我想录制通话语音,但我收到 MediaRecorder:start failed : -2147483648 这是我的通话记录代码块 public void SesKayitBaslat(Str
我的应用程序录制了一个音频 fragment ,并在录制完成后使用 Retrofit2 将 fragment 发送到服务器。服务器接收到文件,但是文件损坏了,我说的损坏是无法播放。我使用以下 URL(
我尝试实现的方法如下所示。 它保存了文件,音频没问题,但视频全是绿色线条。 我做错了什么? camera.unlock(); mediaRecorder = new MediaRecorder();
我首先尝试创建 SurfaceView: SurfaceView sv = new SurfaceView(context); // Get a surface surfaceHolder = sv.
我是一名优秀的程序员,十分优秀!