22

我正在尝试从 Android 的前置摄像头录制视频,同时在表面视图上显示。

我发现前置摄像头在录制过程中会镜像翻转视频,即使表面视图显示正常视图也是如此。

有什么办法可以防止或修复它?

我阅读了其他 stackoverflow 文章,例如如何防止 android 从前置摄像头反转图像?

但似乎只是在谈论用前置摄像头拍照并反转图像,我自己已经使用矩阵修复了这一点。但是,似乎对视频使用矩阵不起作用。

4

5 回答 5

4

就我而言,我只需要在播放时水平翻转。录制时它已经翻转为镜像效果,我认为无法修改它。但是下面的代码解决了我在玩游戏时的问题。

videoPlayer.setScaleX(-1);
于 2017-07-10T15:58:59.767 回答
2

我没有解决方案,但在我看来,关键是:

MediaRecorder.setOrientationHint

设置输出视频播放的方向提示。此方法应在 prepare() 之前调用。此方法不会在视频录制过程中触发源视频帧旋转,而是在输出格式为OutputFormat.THREE_GPP 或 OutputFormat.MPEG_4时在输出视频中添加包含旋转角度的合成矩阵,以便视频播放器选择合适的播放方向。请注意,某些视频播放器可能会选择在播放期间忽略视频中的合成矩阵。

我正在用 H264 录制视频,但它对我不起作用:(但它可能对你有帮助。试过了吗?

于 2013-09-16T16:05:05.923 回答
2

在 setDisplayOrientation 方法的文档(http://developer.android.com/reference/android/hardware/Camera.html)中,我们可以找到:

请注意,前置摄像头的预览显示在旋转之前是水平翻转的,即图像沿摄像头传感器的中心垂直轴反射。因此,用户可以将自己视为照镜子。

所以你的预览显示应该被翻转,而不是你录制的视频。通过预览显示,您是否认为自己在照镜子?如果是这样,一切正常。

于 2013-09-17T12:15:09.250 回答
0

您必须应用矩阵变换,如下所示:

if(isFrontCamera) {
    m.preScale(-ratio, ratio);
} else {
    m.preScale(ratio, ratio);
}

假设您没有调整配给为 1 的任何内容,则使非前置摄像头 preScale 过时。

于 2013-09-16T10:57:48.147 回答
0

如果您需要翻转视频录制并将其保存到内部存储中,那么您可以在 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

于 2021-09-24T17:39:05.003 回答