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)
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:
After several tries, I realized that if I set the layout to:
params.height = 810;
params.width = 1080;
Ration size remains correct:
Finally, I would like to display the video as recorded in the RecordingActivity (1080wx1440h):
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>
source to share
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
source to share