我正在尝试以编程方式记录Android设备前置摄像头的视频。虽然我拥有的大多数测试设备,包括Nexus 4,Nexus 7和三星Galaxy S4,都能正确录制视频,有些则没有。
例如,这是三星Galaxy S3录制的视频片段的屏幕截图:
有奇怪的文物和颜色,视频似乎没有居中(它指向一个人的脸,你可以看到在镜头中几乎看不到)。
这是我的代码:
//
// starting code
//
CAMERA = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
Camera.Parameters cameraParameters = CAMERA.getParameters();
if (cameraParameters.isZoomSupported()) {
cameraParameters.setZoom(0);
}
CAMERA.setParameters(cameraParameters);
CAMERA.setDisplayOrientation(90);
CAMERA.setPreviewDisplay(CAMERA_SURFACE_VIEW.getHolder());
CAMERA.startPreview();
CAMERA.unlock();
CAMERA_MEDIA_RECORDER = new MediaRecorder();
CAMERA_MEDIA_RECORDER.setCamera(CAMERA);
try {
CAMERA_MEDIA_RECORDER.setOrientationHint(270);
} catch (Exception e) {
// this is to fix "setParameter failed" b/c of unsupported orientation hint
CAMERA_MEDIA_RECORDER.setOrientationHint(90);
}
CAMERA_MEDIA_RECORDER.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
CAMERA_MEDIA_RECORDER.setVideoSource(MediaRecorder.VideoSource.CAMERA);
ArrayList<Integer> profileIds = new ArrayList<Integer>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
profileIds.add(CamcorderProfile.QUALITY_480P);
profileIds.add(CamcorderProfile.QUALITY_720P);
}
profileIds.add(CamcorderProfile.QUALITY_HIGH);
profileIds.add(CamcorderProfile.QUALITY_LOW);
CamcorderProfile camcorderProfile = null;
for (int profileId : profileIds) {
try {
camcorderProfile = CamcorderProfile.get(Camera.CameraInfo.CAMERA_FACING_FRONT, profileId);
break; // found our most desired profile, done
} catch (IllegalArgumentException e) {
// profile not found on device... It's okay, the next one might exist.
continue;
} catch (RuntimeException e) {
continue;
}
}
if (camcorderProfile == null) {
return false;
}
CAMERA_MEDIA_RECORDER.setProfile(camcorderProfile);
CAMERA_MEDIA_RECORDER.setAudioEncodingBitRate(96000);
int audioSamplingRate = 44100;
for (int rate : new int[] {44100, 32000, 22050, 16000, 11025, 8000}) {
if (AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT) > 0) {
audioSamplingRate = rate;
break;
}
}
CAMERA_MEDIA_RECORDER.setAudioSamplingRate(audioSamplingRate);
CAMERA_MEDIA_RECORDER.setVideoEncodingBitRate(700000);
String extension = ".3gpp";
if (camcorderProfile.fileFormat == MediaRecorder.OutputFormat.MPEG_4) {
extension = ".mp4";
}
File file = new File(Internal.getStoragePath(Internal.CURRENT_ACTIVITY) + "/webcam" + extension);
file.createNewFile();
CAMERA_MEDIA_RECORDER.setOutputFile(file.toString());
CAMERA_MEDIA_RECORDER.setPreviewDisplay(CAMERA_SURFACE_VIEW.getHolder().getSurface());
CAMERA_MEDIA_RECORDER.prepare();
CAMERA_MEDIA_RECORDER.start();
//
// stopping code
//
try {
CAMERA_MEDIA_RECORDER.stop();
} catch (IllegalStateException e) {
// do nothing
} catch (RuntimeException e) {
// do nothing
}
CAMERA_MEDIA_RECORDER.reset();
CAMERA_MEDIA_RECORDER.release();
CAMERA.lock();
CAMERA.stopPreview();
CAMERA.release();
CAMERA_MEDIA_RECORDER = null;
CAMERA = null;
CAMERA_SURFACE_VIEW = null;
编辑:我应该指出,surfaceView是1 x 1 px并且在屏幕边界之外。我不希望显示预览。
如何确保所有带前置摄像头的设备上的录像效果都很好?
答案 0 :(得分:1)
&#34;接受&#34;答案只是一种解决方法,并没有解决问题,因为当你发布预览并开始录制时,缩放或方面会发生变化,因为mediarecorder会将预览曲面调整到它实际需要的位置,因此镜头的框架将会当你达到不合需要的记录时改变。正确的做法是将预览大小设置为与录制大小的宽高比一致,以便mediarecorder获得预期的表面。
检查Android相机应用程序,它不会停止预览,然后开始录制(你可以通过保持闪光灯开启来检查这一点,如果你开始录制闪光灯没有关闭然后再打开,这将是会发生什么,如果你在录制之前释放表面 - 你可以在你自己的应用程序中测试它。
最好的方法是查看Google如何使用内置的Android相机应用程序。查看util.java类中的getOptimalPreviewSize()方法。
答案 1 :(得分:0)
我终于能够使用三星Galaxy S3设备并进行一些测试了。问题是由以下几行引起的:
CAMERA.setPreviewDisplay(CAMERA_SURFACE_VIEW.getHolder());
CAMERA.startPreview();
我在StackOverflow上找到的以下答案让我得到了解决方案:https://stackoverflow.com/a/14319270/379245
如果在SurfaceView
和Camera
之间共享MediaRecorder
预览,则显然会导致问题,例如我遇到的问题。从Camera
对象中删除预览显示的设置最终解决了问题。