diff --git a/app/src/main/java/com/xypower/mpapp/v2/AspectRatioFrameLayout.java b/app/src/main/java/com/xypower/mpapp/v2/AspectRatioFrameLayout.java new file mode 100644 index 00000000..b281c90b --- /dev/null +++ b/app/src/main/java/com/xypower/mpapp/v2/AspectRatioFrameLayout.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xypower.mpapp.v2; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.widget.FrameLayout; + +import androidx.annotation.IntDef; + +import com.xypower.mpapp.R; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * A {@link FrameLayout} that resizes itself to match a specified aspect ratio. + */ +public final class AspectRatioFrameLayout extends FrameLayout { + + /** + * Resize modes for {@link AspectRatioFrameLayout}. + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({RESIZE_MODE_FIT, RESIZE_MODE_FIXED_WIDTH, RESIZE_MODE_FIXED_HEIGHT, RESIZE_MODE_FILL}) + public @interface ResizeMode {} + + /** + * Either the width or height is decreased to obtain the desired aspect ratio. + */ + public static final int RESIZE_MODE_FIT = 0; + /** + * The width is fixed and the height is increased or decreased to obtain the desired aspect ratio. + */ + public static final int RESIZE_MODE_FIXED_WIDTH = 1; + /** + * The height is fixed and the width is increased or decreased to obtain the desired aspect ratio. + */ + public static final int RESIZE_MODE_FIXED_HEIGHT = 2; + /** + * The specified aspect ratio is ignored. + */ + public static final int RESIZE_MODE_FILL = 3; + + /** + * The {@link FrameLayout} will not resize itself if the fractional difference between its natural + * aspect ratio and the requested aspect ratio falls below this threshold. + *
+ * This tolerance allows the view to occupy the whole of the screen when the requested aspect
+ * ratio is very close, but not exactly equal to, the aspect ratio of the screen. This may reduce
+ * the number of view layers that need to be composited by the underlying system, which can help
+ * to reduce power consumption.
+ */
+ private static final float MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f;
+
+ private float videoAspectRatio;
+ private int resizeMode;
+
+ public AspectRatioFrameLayout(Context context) {
+ this(context, null);
+ }
+
+ public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ resizeMode = RESIZE_MODE_FIT;
+ if (attrs != null) {
+ TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
+ R.styleable.AspectRatioFrameLayout, 0, 0);
+ try {
+ resizeMode = a.getInt(R.styleable.AspectRatioFrameLayout_resize_mode, RESIZE_MODE_FIT);
+ } finally {
+ a.recycle();
+ }
+ }
+ }
+
+ /**
+ * Set the aspect ratio that this view should satisfy.
+ *
+ * @param widthHeightRatio The width to height ratio.
+ */
+ public void setAspectRatio(float widthHeightRatio) {
+ if (this.videoAspectRatio != widthHeightRatio) {
+ this.videoAspectRatio = widthHeightRatio;
+ requestLayout();
+ }
+ }
+
+ /**
+ * Sets the resize mode.
+ *
+ * @param resizeMode The resize mode.
+ */
+ public void setResizeMode(@ResizeMode int resizeMode) {
+ if (this.resizeMode != resizeMode) {
+ this.resizeMode = resizeMode;
+ requestLayout();
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (resizeMode == RESIZE_MODE_FILL || videoAspectRatio <= 0) {
+ // Aspect ratio not set.
+ return;
+ }
+
+ int width = getMeasuredWidth();
+ int height = getMeasuredHeight();
+ float viewAspectRatio = (float) width / height;
+ float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
+ if (Math.abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) {
+ // We're within the allowed tolerance.
+ return;
+ }
+
+ switch (resizeMode) {
+ case RESIZE_MODE_FIXED_WIDTH:
+ height = (int) (width / videoAspectRatio);
+ break;
+ case RESIZE_MODE_FIXED_HEIGHT:
+ width = (int) (height * videoAspectRatio);
+ break;
+ default:
+ if (aspectDeformation > 0) {
+ height = (int) (width / videoAspectRatio);
+ } else {
+ width = (int) (height * videoAspectRatio);
+ }
+ break;
+ }
+ super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xypower/mpapp/v2/AutoFitGLView.java b/app/src/main/java/com/xypower/mpapp/v2/AutoFitGLView.java
index 1915f16e..4d2e2cb6 100644
--- a/app/src/main/java/com/xypower/mpapp/v2/AutoFitGLView.java
+++ b/app/src/main/java/com/xypower/mpapp/v2/AutoFitGLView.java
@@ -1,4 +1,4 @@
-package com.xypower.gpuvideoandroid.widget;
+package com.xypower.mpapp.v2;
import android.content.Context;
import android.opengl.GLSurfaceView;
diff --git a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java
index ec2b2a77..49c43407 100644
--- a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java
+++ b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivity.java
@@ -35,7 +35,7 @@ import com.xypower.gpuv.camerarecorder.CameraRecordListener;
import com.xypower.gpuv.camerarecorder.GPUCameraRecorder;
import com.xypower.gpuv.camerarecorder.GPUCameraRecorderBuilder;
import com.xypower.gpuv.egl.filter.GlWatermarkFilter;
-import com.xypower.gpuvideoandroid.widget.AutoFitGLView;
+import com.xypower.mpapp.v2.AutoFitGLView;
import com.xypower.mpapp.MicroPhotoService;
import com.xypower.mpapp.R;
@@ -57,7 +57,8 @@ public class Camera2VideoActivity extends AppCompatActivity {
public static final String ACTION_FINISH = "com.xypower.mvapp.ACT_FINISH";
public static final String ACTION_MP_VIDEO_FINISHED = "com.xypower.mpapp.ACT_V_FINISHED";
- private static final int DEFAULT_FONT_SIZE = 20;
+ private static final int DEFAULT_FONT_SIZE = 32;
+ private static final float DEFAULT_STROKE_WIDTH = 0.8f;
private AutoFitGLView mPreviewView;
protected GPUCameraRecorder mGPUCameraRecorder;
@@ -67,6 +68,9 @@ public class Camera2VideoActivity extends AppCompatActivity {
protected int mVideoWidth = 1280;
protected int mVideoHeight = 720;
+ protected int mPreviewWidth = 1280;
+ protected int mPreviewHeight = 720;
+
private int mCameraId;
private long mVideoId = 0;
private long mDuration = 0;
@@ -130,7 +134,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
try {
long ts = System.currentTimeMillis();
- Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
+ Bitmap bm = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Bitmap.Config.ARGB_8888);
Bitmap oldBm = null;
Canvas canvas = new Canvas(bm);
@@ -236,6 +240,9 @@ public class Camera2VideoActivity extends AppCompatActivity {
mCameraWidth = mVideoWidth;
mCameraHeight = mVideoHeight;
+ AspectRatioFrameLayout frameLayout = (AspectRatioFrameLayout)findViewById(R.id.wrap_view);
+ frameLayout.setAspectRatio((float)mVideoWidth / (float)mVideoHeight);
+
mTimeMask = 0;
if (!TextUtils.isEmpty(mOSDLeftTop)) {
mOSDLeftTop = mOSDLeftTop.replace("\r\n", "\n");
@@ -297,50 +304,27 @@ public class Camera2VideoActivity extends AppCompatActivity {
mHandler = new Handler();
- if (!TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop)) {
- mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setColor(Color.WHITE);
- int fontSize = DEFAULT_FONT_SIZE;
- mPaint.setTextSize(fontSize);
-
- mPaintStroker = new Paint(Paint.ANTI_ALIAS_FLAG);
- mPaintStroker.setStyle(Paint.Style.STROKE);
- mPaintStroker.setColor(Color.BLACK);
- mPaintStroker.setTextSize(fontSize);
- mPaintStroker.setStrokeWidth(1);
-
- Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bm);
- canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
-
- long ts = System.currentTimeMillis();
- long zeroTs = ts - (ts % 1000);
- initOSD(bm, zeroTs);
- mOSDFilter = new GlWatermarkFilter(bm);
-
- if (mGPUCameraRecorder != null) {
- mGPUCameraRecorder.setFilter(mOSDFilter);
- }
-
- mOsdThread.start();
- }
-
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mNextVideoAbsolutePath = getVideoFilePath();
- mGPUCameraRecorder.start(mNextVideoAbsolutePath);
- }
- }, 0);
-
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
protected void onResume() {
super.onResume();
- setUpCamera();
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setUpCamera();
+
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mNextVideoAbsolutePath = getVideoFilePath();
+ mGPUCameraRecorder.start(mNextVideoAbsolutePath);
+ }
+ }, 0);
+ }
+ }, 100);
+
}
@Override
@@ -358,8 +342,14 @@ public class Camera2VideoActivity extends AppCompatActivity {
}
int statusHeight = mStatusBarHeight;
- int bmWidth = bm.getWidth();
- int bmHeight = bm.getHeight();
+ int bmWidth = 1620;
+ int bmHeight = 1080;
+
+ AspectRatioFrameLayout frameLayout = (AspectRatioFrameLayout)findViewById(R.id.wrap_view);
+
+ int w = frameLayout.getWidth();
+ int h = frameLayout.getMeasuredHeight();
+
int margin = mOSDMargin;
int x = 0;
int y = 0;
@@ -630,8 +620,9 @@ public class Camera2VideoActivity extends AppCompatActivity {
runOnUiThread(() -> {
- FrameLayout frameLayout = findViewById(R.id.wrap_view);
+ AspectRatioFrameLayout frameLayout = (AspectRatioFrameLayout)findViewById(R.id.wrap_view);
frameLayout.removeAllViews();
+
mPreviewView = null;
mPreviewView = new AutoFitGLView(getApplicationContext());
mPreviewView.setTouchListener((event, width, height) -> {
@@ -640,12 +631,47 @@ public class Camera2VideoActivity extends AppCompatActivity {
});
frameLayout.addView(mPreviewView);
+
+ if (!TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop)) {
+ mPreviewWidth = frameLayout.getMeasuredWidth();
+ mPreviewHeight = frameLayout.getMeasuredHeight();
+
+ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setColor(Color.WHITE);
+ int fontSize = DEFAULT_FONT_SIZE * mPreviewHeight / 1024;
+ float strokeWidth = DEFAULT_STROKE_WIDTH * mPreviewHeight / 1024;
+ mPaint.setTextSize(fontSize);
+
+ mPaintStroker = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mPaintStroker.setStyle(Paint.Style.STROKE);
+ mPaintStroker.setColor(Color.BLACK);
+ mPaintStroker.setTextSize(fontSize);
+ mPaintStroker.setStrokeWidth(strokeWidth);
+
+ Bitmap bm = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bm);
+ canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
+
+ long ts = System.currentTimeMillis();
+ long zeroTs = ts - (ts % 1000);
+ initOSD(bm, zeroTs);
+ mOSDFilter = new GlWatermarkFilter(bm);
+
+ if (mGPUCameraRecorder != null) {
+ mGPUCameraRecorder.setFilter(mOSDFilter);
+ }
+
+ mOsdThread.start();
+ }
});
}
private void setUpCamera() {
setUpCameraView();
+
+
if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
mNextVideoAbsolutePath = getVideoFilePath(this);
}
diff --git a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivityOld.java b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivityOld.java
index 79f3ea8c..acd2048e 100644
--- a/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivityOld.java
+++ b/app/src/main/java/com/xypower/mpapp/v2/Camera2VideoActivityOld.java
@@ -33,7 +33,7 @@ import com.xypower.gpuv.camerarecorder.CameraRecordListener;
import com.xypower.gpuv.camerarecorder.GPUCameraRecorder;
import com.xypower.gpuv.camerarecorder.GPUCameraRecorderBuilder;
import com.xypower.gpuv.egl.filter.GlWatermarkFilter;
-import com.xypower.gpuvideoandroid.widget.AutoFitGLView;
+import com.xypower.mpapp.v2.AutoFitGLView;
import com.xypower.mpapp.MicroPhotoService;
import com.xypower.mpapp.R;
diff --git a/app/src/main/res/layout/activity_camera2_video.xml b/app/src/main/res/layout/activity_camera2_video.xml
index cdf43001..7c58cc11 100644
--- a/app/src/main/res/layout/activity_camera2_video.xml
+++ b/app/src/main/res/layout/activity_camera2_video.xml
@@ -6,7 +6,7 @@
>
-