|
|
|
@ -17,8 +17,6 @@ import android.os.Build;
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.os.Environment;
|
|
|
|
|
import android.os.Handler;
|
|
|
|
|
import android.os.Looper;
|
|
|
|
|
import android.os.Message;
|
|
|
|
|
import android.provider.MediaStore;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.util.Log;
|
|
|
|
@ -51,10 +49,9 @@ import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Timer;
|
|
|
|
|
import java.util.concurrent.Semaphore;
|
|
|
|
|
|
|
|
|
|
public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
public class Camera2VideoActivityOld 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";
|
|
|
|
@ -84,12 +81,11 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
private int mOSDMargin = 0;
|
|
|
|
|
private Paint mPaint;
|
|
|
|
|
private Paint mPaintStroker;
|
|
|
|
|
|
|
|
|
|
private List<Bitmap> mBitmaps = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
private Bitmap mBitmap;
|
|
|
|
|
private GlWatermarkFilter mOSDFilter = null;
|
|
|
|
|
private Object mBitmapLocker = new Object();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SimpleDateFormat mDateFormater;
|
|
|
|
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
|
|
|
|
|
|
|
|
|
@ -98,6 +94,9 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
private int mTimeMask = 0;
|
|
|
|
|
private int mStatusBarHeight = -1;
|
|
|
|
|
private long mOsdTs = 0;
|
|
|
|
|
private Semaphore mOSDSemaphore = new Semaphore(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class OSD_ITEM
|
|
|
|
|
{
|
|
|
|
@ -127,75 +126,49 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
private final static int TIME_MASK_LB = TIME_MASK_LB_TS | TIME_MASK_LB_DT | TIME_MASK_LB_ML;
|
|
|
|
|
|
|
|
|
|
private Handler mHandler = null;
|
|
|
|
|
|
|
|
|
|
private class TimerRunner implements Runnable {
|
|
|
|
|
private Bitmap mBitmap;
|
|
|
|
|
|
|
|
|
|
TimerRunner(Bitmap bm) {
|
|
|
|
|
mBitmap = bm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Runnable mTimerRunnable = new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
Bitmap oldBm = null;
|
|
|
|
|
if (mBitmap != null) {
|
|
|
|
|
oldBm = mOSDFilter.updateBitmap(mBitmap);
|
|
|
|
|
}
|
|
|
|
|
if (oldBm != null) {
|
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
mBitmaps.add(oldBm);
|
|
|
|
|
if (mBitmap != null) {
|
|
|
|
|
Bitmap bitmap = mBitmap;
|
|
|
|
|
mBitmap = null;
|
|
|
|
|
mOSDFilter.updateBitmap(bitmap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
|
mOsdTs = ts + 1000; // next second
|
|
|
|
|
long ms = ts % 1000;
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "Cur TS=" + Long.toString(ts / 1000) + " Timer=" + Long.toString(1000 - ms));
|
|
|
|
|
|
|
|
|
|
Message msg = Message.obtain();
|
|
|
|
|
msg.what = 1;
|
|
|
|
|
msg.obj = new Long(ts - ms + 1000);
|
|
|
|
|
mOsdHandler.sendMessage(msg);
|
|
|
|
|
}
|
|
|
|
|
mOSDSemaphore.release();
|
|
|
|
|
|
|
|
|
|
mHandler.postDelayed(this, 1000 - ms);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private Handler mOsdHandler;
|
|
|
|
|
private Thread mOsdThread = new Thread(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
Looper.prepare();
|
|
|
|
|
|
|
|
|
|
mOsdHandler = new Handler(Looper.myLooper()) {
|
|
|
|
|
public void handleMessage(Message msg) {
|
|
|
|
|
if (msg.what == 1) {
|
|
|
|
|
Long targetTs = (Long)msg.obj;
|
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
|
if (ts > targetTs.longValue()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Bitmap bm = null;
|
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
if (!mBitmaps.isEmpty()) {
|
|
|
|
|
bm = mBitmaps.remove(0);
|
|
|
|
|
}
|
|
|
|
|
while (true) {
|
|
|
|
|
try {
|
|
|
|
|
mOSDSemaphore.acquire();
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
}
|
|
|
|
|
if (bm != null) {
|
|
|
|
|
updateOSD(bm, targetTs.longValue());
|
|
|
|
|
|
|
|
|
|
TimerRunner runner = new TimerRunner(bm);
|
|
|
|
|
mHandler.postDelayed(runner, targetTs.longValue() - ts);
|
|
|
|
|
}
|
|
|
|
|
} else if (msg.what == 0) {
|
|
|
|
|
Looper.myLooper().quitSafely();
|
|
|
|
|
if (mOsdTs == -1) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Looper.loop();
|
|
|
|
|
updateOSD(mOsdTs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
@ -204,6 +177,18 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
Window win = getWindow();
|
|
|
|
|
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
|
|
|
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
|
|
|
/*
|
|
|
|
|
win.setDecorFitsSystemWindows(false);
|
|
|
|
|
WindowInsetsController controller = win.getInsetsController();
|
|
|
|
|
if (controller != null) {
|
|
|
|
|
controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
|
|
|
|
|
controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setContentView(R.layout.activity_camera2_video);
|
|
|
|
|
|
|
|
|
|
getSupportActionBar().hide();
|
|
|
|
@ -212,7 +197,7 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
onCreateActivity();
|
|
|
|
|
|
|
|
|
|
getWindow().getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
|
|
|
|
|
mStatusBarHeight = px2dip(Camera2VideoActivityNew.this, insets.getStableInsetTop());
|
|
|
|
|
mStatusBarHeight = px2dip(Camera2VideoActivityOld.this, insets.getStableInsetTop());
|
|
|
|
|
|
|
|
|
|
return insets;
|
|
|
|
|
});
|
|
|
|
@ -332,7 +317,6 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
long ts = 0;
|
|
|
|
|
long zeroTs = 0;
|
|
|
|
|
|
|
|
|
|
Bitmap bm2 = null;
|
|
|
|
|
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);
|
|
|
|
@ -346,27 +330,22 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
mPaintStroker.setTextSize(fontSize);
|
|
|
|
|
mPaintStroker.setStrokeWidth(1);
|
|
|
|
|
|
|
|
|
|
bm2 = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
|
|
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
mBitmap = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
|
Canvas canvas = new Canvas(mBitmap);
|
|
|
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
|
|
|
|
|
|
|
|
ts = System.currentTimeMillis();
|
|
|
|
|
zeroTs = ts - (ts % 1000);
|
|
|
|
|
initOSD(bm, zeroTs);
|
|
|
|
|
mOSDFilter = new GlWatermarkFilter(bm);
|
|
|
|
|
initOSD(zeroTs);
|
|
|
|
|
|
|
|
|
|
if (mGPUCameraRecorder != null) {
|
|
|
|
|
mGPUCameraRecorder.setFilter(mOSDFilter);
|
|
|
|
|
}
|
|
|
|
|
mOSDFilter = new GlWatermarkFilter(mBitmap);
|
|
|
|
|
|
|
|
|
|
updateOSD(bm2, zeroTs + 1000);
|
|
|
|
|
mBitmap = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
updateOSD(zeroTs + 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final long prevZeroTs = zeroTs;
|
|
|
|
|
final Bitmap finalBm = bm2;
|
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
@ -380,33 +359,18 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
if (zeroTs2 > prevZeroTs) {
|
|
|
|
|
// Next second
|
|
|
|
|
Bitmap oldBm = mOSDFilter.updateBitmap(finalBm);
|
|
|
|
|
if (oldBm != null) {
|
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
mBitmaps.add(oldBm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Message msg = Message.obtain();
|
|
|
|
|
msg.what = 1;
|
|
|
|
|
msg.obj = new Long(zeroTs2 + 1000);
|
|
|
|
|
// mOsdTs = zeroTs2 + 1000;
|
|
|
|
|
mOsdHandler.sendMessage(msg);
|
|
|
|
|
} else {
|
|
|
|
|
TimerRunner runner = new TimerRunner(finalBm);
|
|
|
|
|
mHandler.postDelayed(runner, 1000 - (ts2 - zeroTs2));
|
|
|
|
|
mOSDFilter.updateBitmap(mBitmap);
|
|
|
|
|
mBitmap = null;
|
|
|
|
|
mOsdTs = zeroTs2 + 1000;
|
|
|
|
|
mOSDSemaphore.release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "Cur TS=" + Long.toString(ts2 / 1000) + " Timer=" + Long.toString(1000 - (ts2 - zeroTs2)));
|
|
|
|
|
mHandler.postDelayed(mTimerRunnable, 1000 - (ts2 - zeroTs2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
mGPUCameraRecorder.stop();
|
|
|
|
|
}
|
|
|
|
|
}, 16 + mDuration * 1000);
|
|
|
|
|
|
|
|
|
|
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -422,7 +386,7 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
releaseCamera();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initOSD(Bitmap bm, long ts) {
|
|
|
|
|
private void initOSD(long ts) {
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "INIT OSD " + Long.toString(ts / 1000));
|
|
|
|
|
|
|
|
|
@ -430,14 +394,15 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
mStatusBarHeight = getStatusBarHeight(this);
|
|
|
|
|
}
|
|
|
|
|
int statusHeight = mStatusBarHeight;
|
|
|
|
|
|
|
|
|
|
int bmWidth = bm.getWidth();
|
|
|
|
|
int bmHeight = bm.getHeight();
|
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
int bmWidth = mBitmap.getWidth();
|
|
|
|
|
int bmHeight = mBitmap.getHeight();
|
|
|
|
|
int margin = mOSDMargin;
|
|
|
|
|
int x = 0;
|
|
|
|
|
int y = 0;
|
|
|
|
|
// mOSDFilter.
|
|
|
|
|
|
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
|
Canvas canvas = new Canvas(mBitmap);
|
|
|
|
|
Rect textBounds = new Rect();
|
|
|
|
|
|
|
|
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
|
|
@ -603,10 +568,10 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
origin.y -= (textBounds.height() * 3) >> 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateOSD(Bitmap bm, long ts) {
|
|
|
|
|
private void updateOSD(long ts) {
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "prepareOSD " + Long.toString(ts / 1000));
|
|
|
|
|
if (mStatusBarHeight == -1) {
|
|
|
|
@ -614,6 +579,8 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
}
|
|
|
|
|
int statusHeight = mStatusBarHeight;
|
|
|
|
|
|
|
|
|
|
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
|
boolean aa = canvas.isHardwareAccelerated();
|
|
|
|
|
Rect textBounds = new Rect();
|
|
|
|
@ -664,6 +631,9 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
mBitmap = bm;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String updateOSDTime(String osd, long ts) {
|
|
|
|
@ -711,8 +681,11 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
if (mGPUCameraRecorder == null) return;
|
|
|
|
|
mGPUCameraRecorder.changeManualFocusPoint(event.getX(), event.getY(), width, height);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
frameLayout.addView(mPreviewView);
|
|
|
|
|
|
|
|
|
|
if (mGPUCameraRecorder != null) {
|
|
|
|
|
mGPUCameraRecorder.setFilter(mOSDFilter);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -733,23 +706,23 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onRecordComplete() {
|
|
|
|
|
// mHandler.removeCallbacks(mTimerRunnable);
|
|
|
|
|
Message msg = Message.obtain();
|
|
|
|
|
msg.what = 0;
|
|
|
|
|
mOsdHandler.sendMessage(msg);
|
|
|
|
|
mHandler.removeCallbacks(mTimerRunnable);
|
|
|
|
|
mOsdTs = -1;
|
|
|
|
|
mOSDSemaphore.release();
|
|
|
|
|
// exportMp4ToGallery(getApplicationContext(), mNextVideoAbsolutePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exportMp4ToGallery(getApplicationContext(), mNextVideoAbsolutePath);
|
|
|
|
|
broadcastVideoFile(true, mNextVideoAbsolutePath);
|
|
|
|
|
@Override
|
|
|
|
|
public void onRecordStart() {
|
|
|
|
|
Log.d("OSD", "Record Start ");
|
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
Camera2VideoActivityNew.this.finish();
|
|
|
|
|
}
|
|
|
|
|
}, 500);
|
|
|
|
|
mGPUCameraRecorder.stop();
|
|
|
|
|
Log.d("OSD", "Record Stop");
|
|
|
|
|
}
|
|
|
|
|
}, 64 + mDuration * 1000);
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onRecordStart() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@ -764,6 +737,13 @@ public class Camera2VideoActivityNew extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onVideoFileReady() {
|
|
|
|
|
broadcastVideoFile(true, mNextVideoAbsolutePath);
|
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
Camera2VideoActivityOld.this.finish();
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.videoSize(mVideoWidth, mVideoHeight)
|