如何确保录制视频的正确播放方向?

4
我正在使用MediaStore.ACTION_VIDEO_CAPTURE意图来捕获视频,并稍后使用VideoView播放。我想知道捕获的视频方向。

我不想使用意图调用时的方向,因为用户可能在按下快门按钮之前旋转设备。我也不想实现自己的自定义视频捕获。

视频的方向是否存储在保存的文件中和/或在意图结果中返回?


你不能比较视频的高度和宽度,自己决定方向吗?我认为大多数相机只记录单一方向(横向)。 - auselen
相机怎么可能防止用户旋转设备呢?我希望至少捕获意图能够记录哪个方向是向上,并将其存储在视频文件的元数据中。肯定有很多情况需要竖屏视频(前置摄像头是一个典型例子)。 - Jeff Axelrod
3个回答

13

视频的方向信息是否存储在保存的文件中或者通过意图返回结果中?

AOSP的VideoCameraactivity会将相机设备的旋转值传递给MediaRecorder.setOrientationHint()方法。以下是与此相关的代码片段,位于 VideoCamera.initializeRecorder() 代码中:

    // See android.hardware.Camera.Parameters.setRotation for
    // documentation.
    // Note that mOrientation here is the device orientation, which is 
    // the opposite of what getWindowManager().getDefaultDisplay().getRotation() 
    // would return, which is the orientation the graphics need to rotate 
    // in order to render correctly.
    int rotation = 0;
    if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
        CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
        if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
            rotation = (info.orientation - mOrientation + 360) % 360;
        } else {  // back-facing camera
            rotation = (info.orientation + mOrientation) % 360;
        }
    }
    mMediaRecorder.setOrientationHint(rotation);

这里是 setOrientationHint() 的文档,解释了信息的存储:

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

由于您正在使用框架的 VideoView 小部件来回放视频,因此它应该已经正确处理合成矩阵中的信息,您只需要比较视频的宽度和高度来决定在播放活动中设置横向或纵向方向。一种简单的方法是只需调用 ThumbnailUtils.createVideoThumbnail()(内部使用 MediaMetaDataRetriever),并检查返回位图的分辨率。


我很惊讶VideoView不会默认根据当前布局的方向播放视频。也就是说,如果VideoView正在播放横向视频,而当前布局是纵向方向,则视频将被“letterboxed”,并仍以纵向方向播放,使得视频的“上”正确指向屏幕上方,而无需旋转屏幕。 - Jeff Axelrod
我正在使用相同的方法,但如何获取mOrientation值?因为我得到的info.orientation值是相同的。顺便说一下,我正在以固定横向方向捕获视频。 - chikka.anddev

4

和al.在他的回答中提到的一样,我使用MediaMetadataRetriever,但是使用METADATA_KEY_VIDEO_ROTATION键:

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource( absoluteVideoFilePath );
String orientation = mediaMetadataRetriever.extractMetadata(
         MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION );

我检查了使用前置摄像头进行视频捕获的4个不同方向,元数据始终不同。 注意:METADATA_KEY_VIDEO_ROTATION需要API Level 17或以上。


1
是的,你必须小心处理这个问题,因为 METADATA_KEY_VIDEO_ROTATION 键只在 API Level 17 及以上版本中可用。 - Stefan Anca

0
你可以使用MediaMetadataRetriever获取视频的宽度和高度,并在加载之前确定其方向。

您有证据表明在使用不同方向录制时它们被交换了吗? - Jeff Axelrod
1
不,我没有证据。但我可以告诉你,在Android框架中(例如导航栏),屏幕宽度与高度进行比较以获取方向。你为什么不能自己测试一下呢?应该相对快速的。 - al.
是的,如果没有其他答案,我会去检查这个。我发现ffmpeg可以检查方向标识 - 虽然如果它起作用,那肯定是一个更重的答案。 - Jeff Axelrod
对于现在阅读此内容的任何人来说,宽度和高度不会被交换。它总是看起来像是横向视频。 - BLuFeNiX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接