优化短视频

hdrplus
Matthew 1 year ago
parent 78c948b95f
commit 4d86ebe148

@ -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.
* <p>
* 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));
}
}

@ -1,4 +1,4 @@
package com.xypower.gpuvideoandroid.widget;
package com.xypower.mpapp.v2;
import android.content.Context;
import android.opengl.GLSurfaceView;

@ -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);
}

@ -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;

@ -6,7 +6,7 @@
>
<FrameLayout
<com.xypower.mpapp.v2.AspectRatioFrameLayout
android:id="@+id/wrap_view"
android:layout_width="0dp"
android:layout_height="0dp"

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<resources>
<!-- Must be kept in sync with AspectRatioFrameLayout -->
<attr name="resize_mode" format="enum">
<enum name="fit" value="0"/>
<enum name="fixed_width" value="1"/>
<enum name="fixed_height" value="2"/>
<enum name="fill" value="3"/>
</attr>
<!-- Must be kept in sync with SimpleExoPlayerView -->
<attr name="surface_type" format="enum">
<enum name="none" value="0"/>
<enum name="surface_view" value="1"/>
<enum name="texture_view" value="2"/>
</attr>
<attr name="show_timeout" format="integer"/>
<attr name="rewind_increment" format="integer"/>
<attr name="fastforward_increment" format="integer"/>
<attr name="player_layout_id" format="reference"/>
<attr name="controller_layout_id" format="reference"/>
<declare-styleable name="SimpleExoPlayerView">
<attr name="use_artwork" format="boolean"/>
<attr name="use_controller" format="boolean"/>
<attr name="surface_type"/>
<attr name="show_timeout"/>
<attr name="rewind_increment"/>
<attr name="fastforward_increment"/>
<attr name="resize_mode"/>
<attr name="player_layout_id"/>
<attr name="controller_layout_id"/>
</declare-styleable>
<declare-styleable name="AspectRatioFrameLayout">
<attr name="resize_mode"/>
</declare-styleable>
<declare-styleable name="PlaybackControlView">
<attr name="show_timeout"/>
<attr name="rewind_increment"/>
<attr name="fastforward_increment"/>
<attr name="controller_layout_id"/>
</declare-styleable>
</resources>
Loading…
Cancel
Save