|
|
@ -69,7 +69,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
|
|
private int mCameraId;
|
|
|
|
private int mCameraId;
|
|
|
|
private long mVideoId = 0;
|
|
|
|
private long mVideoId = 0;
|
|
|
|
private int mDuration = 0;
|
|
|
|
private long mDuration = 0;
|
|
|
|
|
|
|
|
|
|
|
|
private int mOrientation = -1;
|
|
|
|
private int mOrientation = -1;
|
|
|
|
|
|
|
|
|
|
|
@ -84,10 +84,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
private Paint mPaint;
|
|
|
|
private Paint mPaint;
|
|
|
|
private Paint mPaintStroker;
|
|
|
|
private Paint mPaintStroker;
|
|
|
|
|
|
|
|
|
|
|
|
private List<Bitmap> mBitmaps = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private GlWatermarkFilter mOSDFilter = null;
|
|
|
|
private GlWatermarkFilter mOSDFilter = null;
|
|
|
|
private Object mBitmapLocker = new Object();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SimpleDateFormat mDateFormater;
|
|
|
|
private SimpleDateFormat mDateFormater;
|
|
|
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
|
|
|
|
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss a");
|
|
|
@ -127,71 +124,45 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
|
|
private Handler mHandler = null;
|
|
|
|
private Handler mHandler = null;
|
|
|
|
|
|
|
|
|
|
|
|
private class TimerRunner implements Runnable {
|
|
|
|
private Thread mOsdThread = new Thread(new Runnable() {
|
|
|
|
private Bitmap mBitmap;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TimerRunner(Bitmap bm) {
|
|
|
|
|
|
|
|
mBitmap = bm;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
|
|
Bitmap oldBm = null;
|
|
|
|
try {
|
|
|
|
if (mBitmap != null) {
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
oldBm = mOSDFilter.updateBitmap(mBitmap);
|
|
|
|
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
}
|
|
|
|
Bitmap oldBm = null;
|
|
|
|
if (oldBm != null) {
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
synchronized (mBitmapLocker) {
|
|
|
|
|
|
|
|
mBitmaps.add(oldBm);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
long zeroTs = ts - (ts % 1000);
|
|
|
|
long ms = ts % 1000;
|
|
|
|
long nextTs = zeroTs + 1000;
|
|
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "Cur TS=" + Long.toString(ts / 1000) + " Timer=" + Long.toString(1000 - ms));
|
|
|
|
while (true) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (nextTs > ts) {
|
|
|
|
|
|
|
|
Log.i("OSD", "Sleep " + Long.toString(nextTs - ts));
|
|
|
|
|
|
|
|
Thread.sleep(nextTs - ts);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (InterruptedException ex){
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
} catch(Exception ex){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Message msg = Message.obtain();
|
|
|
|
canvas.setBitmap(bm);
|
|
|
|
msg.what = 1;
|
|
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
|
|
msg.obj = new Long(ts - ms + 1000);
|
|
|
|
updateOSD(bm, nextTs);
|
|
|
|
mOsdHandler.sendMessage(msg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Handler mOsdHandler;
|
|
|
|
oldBm = mOSDFilter.updateBitmap(bm);
|
|
|
|
private Thread mOsdThread = new Thread(new Runnable() {
|
|
|
|
bm = oldBm;
|
|
|
|
@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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bm != null) {
|
|
|
|
|
|
|
|
updateOSD(bm, targetTs.longValue());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TimerRunner runner = new TimerRunner(bm);
|
|
|
|
ts = System.currentTimeMillis();
|
|
|
|
mHandler.postDelayed(runner, targetTs.longValue() - ts);
|
|
|
|
zeroTs = ts - (ts % 1000);
|
|
|
|
}
|
|
|
|
if (zeroTs + 1000 > nextTs) {
|
|
|
|
} else if (msg.what == 0) {
|
|
|
|
nextTs = zeroTs + 1000;
|
|
|
|
Looper.myLooper().quitSafely();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
|
|
}
|
|
|
|
Looper.loop();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -326,12 +297,6 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
|
|
mHandler = new Handler();
|
|
|
|
mHandler = new Handler();
|
|
|
|
|
|
|
|
|
|
|
|
mOsdThread.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long ts = 0;
|
|
|
|
|
|
|
|
long zeroTs = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bitmap bm2 = null;
|
|
|
|
|
|
|
|
if (!TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop)) {
|
|
|
|
if (!TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop) || !TextUtils.isEmpty(mOSDLeftTop)) {
|
|
|
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
|
|
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
|
|
mPaint.setStyle(Paint.Style.FILL);
|
|
|
|
mPaint.setStyle(Paint.Style.FILL);
|
|
|
@ -345,15 +310,12 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
mPaintStroker.setTextSize(fontSize);
|
|
|
|
mPaintStroker.setTextSize(fontSize);
|
|
|
|
mPaintStroker.setStrokeWidth(1);
|
|
|
|
mPaintStroker.setStrokeWidth(1);
|
|
|
|
|
|
|
|
|
|
|
|
bm2 = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
Bitmap bm = Bitmap.createBitmap(mVideoWidth, mVideoHeight, Bitmap.Config.ARGB_8888);
|
|
|
|
|
|
|
|
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
Canvas canvas = new Canvas(bm);
|
|
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
|
|
|
|
|
|
|
|
|
|
|
ts = System.currentTimeMillis();
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
zeroTs = ts - (ts % 1000);
|
|
|
|
long zeroTs = ts - (ts % 1000);
|
|
|
|
initOSD(bm, zeroTs);
|
|
|
|
initOSD(bm, zeroTs);
|
|
|
|
mOSDFilter = new GlWatermarkFilter(bm);
|
|
|
|
mOSDFilter = new GlWatermarkFilter(bm);
|
|
|
|
|
|
|
|
|
|
|
@ -361,41 +323,14 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
mGPUCameraRecorder.setFilter(mOSDFilter);
|
|
|
|
mGPUCameraRecorder.setFilter(mOSDFilter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
updateOSD(bm2, zeroTs + 1000);
|
|
|
|
mOsdThread.start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
final long prevZeroTs = zeroTs;
|
|
|
|
|
|
|
|
final Bitmap finalBm = bm2;
|
|
|
|
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
mNextVideoAbsolutePath = getVideoFilePath();
|
|
|
|
mNextVideoAbsolutePath = getVideoFilePath();
|
|
|
|
|
|
|
|
|
|
|
|
mGPUCameraRecorder.start(mNextVideoAbsolutePath);
|
|
|
|
mGPUCameraRecorder.start(mNextVideoAbsolutePath);
|
|
|
|
|
|
|
|
|
|
|
|
if (mOSDFilter != null) {
|
|
|
|
|
|
|
|
long ts2 = System.currentTimeMillis();
|
|
|
|
|
|
|
|
long zeroTs2 = ts2 - (ts2 % 1000);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Log.d("OSD", "Cur TS=" + Long.toString(ts2 / 1000) + " Timer=" + Long.toString(1000 - (ts2 - zeroTs2)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 0);
|
|
|
|
}, 0);
|
|
|
|
|
|
|
|
|
|
|
@ -416,7 +351,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
|
|
private void initOSD(Bitmap bm, long ts) {
|
|
|
|
private void initOSD(Bitmap bm, long ts) {
|
|
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "INIT OSD " + Long.toString(ts / 1000));
|
|
|
|
Log.i("OSD", "INIT OSD " + Long.toString(ts / 1000));
|
|
|
|
|
|
|
|
|
|
|
|
if (mStatusBarHeight == -1) {
|
|
|
|
if (mStatusBarHeight == -1) {
|
|
|
|
mStatusBarHeight = getStatusBarHeight(this);
|
|
|
|
mStatusBarHeight = getStatusBarHeight(this);
|
|
|
@ -600,7 +535,7 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
|
|
|
|
|
|
|
|
private void updateOSD(Bitmap bm, long ts) {
|
|
|
|
private void updateOSD(Bitmap bm, long ts) {
|
|
|
|
|
|
|
|
|
|
|
|
Log.d("OSD", "prepareOSD " + Long.toString(ts / 1000));
|
|
|
|
Log.i("OSD", "prepareOSD " + Long.toString(ts / 1000));
|
|
|
|
if (mStatusBarHeight == -1) {
|
|
|
|
if (mStatusBarHeight == -1) {
|
|
|
|
mStatusBarHeight = getStatusBarHeight(this);
|
|
|
|
mStatusBarHeight = getStatusBarHeight(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -726,27 +661,28 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onRecordComplete() {
|
|
|
|
public void onRecordComplete() {
|
|
|
|
// mHandler.removeCallbacks(mTimerRunnable);
|
|
|
|
// mHandler.removeCallbacks(mTimerRunnable);
|
|
|
|
Message msg = Message.obtain();
|
|
|
|
|
|
|
|
msg.what = 0;
|
|
|
|
|
|
|
|
mOsdHandler.sendMessage(msg);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onRecordStart() {
|
|
|
|
public void onRecordStart() {
|
|
|
|
Log.d("OSD", "Record Start ");
|
|
|
|
Log.i("OSD", "Record Start ");
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
Log.i("OSD", "Record Stop " + Long.toString(mDuration));
|
|
|
|
mGPUCameraRecorder.stop();
|
|
|
|
mGPUCameraRecorder.stop();
|
|
|
|
Log.d("OSD", "Record Stop " + Long.toString(mDuration));
|
|
|
|
|
|
|
|
|
|
|
|
int aa = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 256 + mDuration * 1000);
|
|
|
|
}, 999 + mDuration * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onError(Exception exception) {
|
|
|
|
public void onError(Exception exception) {
|
|
|
|
Log.e("GPUCameraRecorder", exception.toString());
|
|
|
|
Log.e("GPUCameraRecorder", exception.toString());
|
|
|
|
|
|
|
|
mOsdThread.interrupt();
|
|
|
|
broadcastVideoFile(false, mNextVideoAbsolutePath);
|
|
|
|
broadcastVideoFile(false, mNextVideoAbsolutePath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -757,18 +693,26 @@ public class Camera2VideoActivity extends AppCompatActivity {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onVideoFileReady() {
|
|
|
|
public void onVideoFileReady() {
|
|
|
|
// exportMp4ToGallery(getApplicationContext(), mNextVideoAbsolutePath);
|
|
|
|
// exportMp4ToGallery(getApplicationContext(), mNextVideoAbsolutePath);
|
|
|
|
|
|
|
|
mOsdThread.interrupt();
|
|
|
|
broadcastVideoFile(true, mNextVideoAbsolutePath);
|
|
|
|
broadcastVideoFile(true, mNextVideoAbsolutePath);
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
mHandler.postDelayed(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
Camera2VideoActivity.this.finish();
|
|
|
|
Camera2VideoActivity.this.finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onDurationArrived() {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.videoSize(mVideoWidth, mVideoHeight)
|
|
|
|
.videoSize(mVideoWidth, mVideoHeight)
|
|
|
|
.cameraSize(mCameraWidth, mCameraHeight)
|
|
|
|
.cameraSize(mCameraWidth, mCameraHeight)
|
|
|
|
.cameraId(Integer.toString(mCameraId))
|
|
|
|
.cameraId(Integer.toString(mCameraId))
|
|
|
|
|
|
|
|
.mute(true)
|
|
|
|
|
|
|
|
.duration(mDuration * 1000)
|
|
|
|
.build();
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
|
|
if (mOSDFilter != null) {
|
|
|
|
if (mOSDFilter != null) {
|
|
|
|