TextureView video playback captured from the front camera

I am recording video from Samsung Galaxy S4 (1080wx1920h) from FRONT CAMERA. The resulting video is rotated 90 ° and inverted. (See picture)

Video result

Then I take a video (final resolution 320wx240h) and I display it in a TextureView with:

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

      

and I set the texture compositing parameters to:

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

      

The result looks like this:

1080wx1440h

After several tries, I realized that if I set the layout to:

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

      

Ration size remains correct:

810yx1080h

Finally, I would like to display the video as recorded in the RecordingActivity (1080wx1440h):

RecordingResolution

Any thoughts on how to do this?

Or is there a way to record video from the front camera when rotated correctly?

Full Activity Code:

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>

      

+3


source to share


1 answer


Camera play, previews, textures, and matrix can be tricky.

Keep in mind that the camera's natural orientation is landscape, so if you don't do anything, the resulting video will be in that orientation. In addition, the preview frames will be landscape.

when you do textureView.setRotation(90.0f);

and textureView.setScaleX(-1);

, you only change the texture's internal transformation matrix, this means that when something is rendered inside, a transformation takes place and what you see is different from the actual content. This is fine, but in fact the camera doesn't know anything about this rotation, and neither in the media recorder.

If you are using Mediarecorder you should take a look at

MediaRecorder.html # setOrientationHint (int)



Sets the orientation hint for playing the output video. This method should be called before preparation (). This method will not result in the original video frame to be rotated during video recording, but to add a composition matrix containing the rotation angle in the output video if the output format is OutputFormat.THREE_GPP or OutputFormat.MPEG_4 so the video player can choose the correct orientation for playback. Please note that some video players may ignore the composting matrix in the video during playback.

Parameters

graduates the clockwise rotation angle in degrees. the supported angles are 0, 90, 180 and 270 degrees.

If you are using a different approach to writing, you can probably take a look at

Camera.Parameters.html # setRotation (int)

or

Camera.html # setDisplayOrientation (int)

0


source







All Articles