我正在尝试从 Android 的前置摄像头录制视频,同时在表面视图上显示。
我发现前置摄像头在录制过程中会镜像翻转视频,即使表面视图显示正常视图也是如此。
有什么办法可以防止或修复它?
我阅读了其他 stackoverflow 文章,例如如何防止 android 从前置摄像头反转图像?
但似乎只是在谈论用前置摄像头拍照并反转图像,我自己已经使用矩阵修复了这一点。但是,似乎对视频使用矩阵不起作用。
我正在尝试从 Android 的前置摄像头录制视频,同时在表面视图上显示。
我发现前置摄像头在录制过程中会镜像翻转视频,即使表面视图显示正常视图也是如此。
有什么办法可以防止或修复它?
我阅读了其他 stackoverflow 文章,例如如何防止 android 从前置摄像头反转图像?
但似乎只是在谈论用前置摄像头拍照并反转图像,我自己已经使用矩阵修复了这一点。但是,似乎对视频使用矩阵不起作用。
就我而言,我只需要在播放时水平翻转。录制时它已经翻转为镜像效果,我认为无法修改它。但是下面的代码解决了我在玩游戏时的问题。
videoPlayer.setScaleX(-1);
我没有解决方案,但在我看来,关键是:
MediaRecorder.setOrientationHint
设置输出视频播放的方向提示。此方法应在 prepare() 之前调用。此方法不会在视频录制过程中触发源视频帧旋转,而是在输出格式为OutputFormat.THREE_GPP 或 OutputFormat.MPEG_4时在输出视频中添加包含旋转角度的合成矩阵,以便视频播放器选择合适的播放方向。请注意,某些视频播放器可能会选择在播放期间忽略视频中的合成矩阵。
我正在用 H264 录制视频,但它对我不起作用:(但它可能对你有帮助。试过了吗?
在 setDisplayOrientation 方法的文档(http://developer.android.com/reference/android/hardware/Camera.html)中,我们可以找到:
请注意,前置摄像头的预览显示在旋转之前是水平翻转的,即图像沿摄像头传感器的中心垂直轴反射。因此,用户可以将自己视为照镜子。
所以你的预览显示应该被翻转,而不是你录制的视频。通过预览显示,您是否认为自己在照镜子?如果是这样,一切正常。
您必须应用矩阵变换,如下所示:
if(isFrontCamera) {
m.preScale(-ratio, ratio);
} else {
m.preScale(ratio, ratio);
}
假设您没有调整配给为 1 的任何内容,则使非前置摄像头 preScale 过时。
如果您需要翻转视频录制并将其保存到内部存储中,那么您可以在 android studio 中使用 Mp4Composer 依赖项。
首先你需要添加依赖,
步骤 1. 将 JitPack 存储库添加到您的构建文件
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
步骤 2. 添加依赖项
dependencies {
implementation 'com.github.MasayukiSuda:Mp4Composer-android:v0.4.1'
}
以下是与垂直翻转相同的示例代码。你可以通过制作来翻转它flipVertical(true)
。你也可以水平翻转它flipHorizontal(true)
。
private void flipVideo(String path, String destinationPath) {
new Mp4Composer(sourcePath, destinationPath)
.size(1280, 720)
.fillMode(FillMode.PRESERVE_ASPECT_FIT)
//.flipHorizontal(true)
.flipVertical(true)
// .rotation(Rotation.ROTATION_270)
//.filter(glFilter)
//.mute(muteCheckBox.isChecked())
//.timeScale(2f)
//.changePitch(false)
//.trim(2000, 5000)
.listener(new Mp4Composer.Listener() {
@Override
public void onProgress(double progress) {
Log.d("app_log", "onProgress = " + progress);
runOnUiThread(() -> progressBar.setProgress((int) (progress * 100)));
}
@Override
public void onCompleted() {
Log.d("app_log", "onCompleted(): video conversion completed");
runOnUiThread(() -> {
Toast.makeText(CameraActivity.this, "video saved under " + destinationPath, Toast.LENGTH_SHORT).show();
});
}
@Override
public void onCanceled() {
}
@Override
public void onCurrentWrittenVideoTime(long timeUs) {
}
@Override
public void onFailed(Exception exception) {
Log.e("app_log", "onFailed() " + exception.getMessage());
}
})
.start();
}
像这样调用方法,
flipVideo(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video_input.mp4", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video_output.mp4");
更多信息:Mp4Composer-android