3

我从前置摄像头录制了三星 Galaxy S4 (1080wx1920h) 的视频。生成的视频旋转 90° 并上下颠倒。(见图片)

视频结果

然后我拍摄视频(最终分辨率为 320wx240h)并将其显示到 TextureView:

textureView.setRotation(90.0f);
textureView.setScaleX(-1);

我将 textureView 的布局参数设置为:

ViewGroup.LayoutParams params = textureView.getLayoutParams();
params.height = 1440;
params.width = 1080;
textureView.setLayoutParams(params);

结果如下所示:

1080wx1440h

经过几次重试后,我想如果我将布局设置为:

params.height = 810;
params.width = 1080;

尺寸配比保持正确:

810yx1080h

最后,我想显示在 RecordingActivity (1080wx1440h) 中录制的视频:

录音分辨率

关于如何做到这一点的任何想法?

或者有没有办法从前置摄像头正确旋转录制视频?

完整活动代码:

import android.app.Activity;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Surface;
import android.view.TextureView;
import android.view.ViewGroup;

public class ReplayActivity extends Activity  implements TextureView.SurfaceTextureListener {
    private String pathToVideo;
    private TextureView textureView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_replay);
        textureView = (TextureView)findViewById(R.id.texture_view);
        textureView.setSurfaceTextureListener(this);
        textureView.setRotation(90.0f);
        textureView.setScaleX(-1);
        pathToVideo = getIntent().getStringExtra("path");
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setSurface(new Surface(surface));

        try {
            mediaPlayer.setDataSource(pathToVideo);

            mediaPlayer.prepare();

            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);//x = 1080, y = 1920

            Point videoDimensions = new Point(mediaPlayer.getVideoWidth(),mediaPlayer.getVideoHeight());//x = 320, y = 240
            Point resultParams = VideoHelpers.getScaledDimension(new Point(videoDimensions.y * 1000, videoDimensions.x * 1000), size);//x = 1080, y = 1440
            ViewGroup.LayoutParams params = textureView.getLayoutParams();
            params.height = resultParams.y;//1440
            params.width = resultParams.x;//1080
            textureView.setLayoutParams(params);
            mediaPlayer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {return false;}
    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {}
    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
}

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF0000">
    <TextureView
        android:id="@+id/texture_view"
        android:layout_width="wrap_content"
        android:background="#000000"
        android:layout_height="wrap_content" />
</RelativeLayout>
4

1 回答 1

0

使用相机、预览、纹理和矩阵可能会很棘手。

请记住,相机的自然方向是横向的,因此如果您不执行任何其他操作,生成的视频将处于该方向。此外,预览帧将是横向的。

当你这样做时textureView.setRotation(90.0f);textureView.setScaleX(-1);你只是在修改纹理的内部变换矩阵,也就是说,当在里面绘制一些东西时,就会发生变换,你看到的与实际内容不同。这很好,但实际上相机对这种旋转一无所知,媒体记录器也不知道。

如果你正在使用Mediarecorder你应该看看

MediaRecorder.html#setOrientationHint(int)

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

参数

以度为单位顺时针旋转的角度。支持的角度为 0、90、180 和 270 度。

如果您正在使用其他录制方法,可能您应该看看

Camera.Parameters.html#setRotation(int)

或者

Camera.html#setDisplayOrientation(int)

于 2014-10-15T19:17:55.323 回答