Воспроизведение видео на TextureView, снятого с фронтальной камеры

Записываю видео с Samsung Galaxy S4 (1080wx1920h) с ​​ПЕРЕДНЕЙ КАМЕРЫ. Полученное видео повернуто на 90° и перевернуто. (Смотрите картинку)

Результат видео

Затем я беру видео (финальное разрешение 320x240h) и отображаю его в 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):

RecordingResolution

Любые мысли о том, как это сделать?

Или есть способ записать видео с фронтальной камеры в правильном повороте?

Полный код активности:

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>

person Vojtech B    schedule 16.09.2014    source источник


Ответы (1)


Играть с камерой, предварительным просмотром, текстурами и матрицей может быть непросто.

Имейте в виду, что естественная ориентация камеры — альбомная, поэтому, если вы ничего не сделаете, результирующее видео будет именно в этой ориентации. Кроме того, кадры предварительного просмотра будут альбомными.

когда вы делаете textureView.setRotation(90.0f); и textureView.setScaleX(-1);, вы только изменяете внутреннюю матрицу преобразования текстуры, то есть, когда что-то рисуется внутри, происходит преобразование, и то, что вы видите, отличается от фактического содержимого. Это хорошо, но на самом деле ни камера, ни медиарекордер ничего не знают об этом вращении.

Если вы используете Mediarecorder, вам следует взглянуть на

MediaRecorder.html#setOrientationHint(int)

Устанавливает подсказку ориентации для воспроизведения выходного видео. Этот метод следует вызывать до подготовки(). Этот метод не вызывает поворот исходного видеокадра во время видеозаписи, а добавляет матрицу композиции, содержащую угол поворота, в выходное видео, если формат вывода — OutputFormat.THREE_GPP или OutputFormat.MPEG_4, чтобы видеопроигрыватель мог выбрать правильный ориентация для воспроизведения. Обратите внимание, что некоторые видеоплееры могут игнорировать матрицу композиции в видео во время воспроизведения.

Параметры

градусы угол поворота по часовой стрелке в градусах. Поддерживаемые углы: 0, 90, 180 и 270 градусов.

Если вы используете другой подход к записи, возможно, вам следует взглянуть на

Camera.Parameters.html#setRotation(int)

or

Camera.html#setDisplayOrientation(int)

person Carlos Robles    schedule 15.10.2014
comment
Как сделать камеру фронтальной в этом - person EminenT; 27.03.2018