现在有个需求,就是需要使用手机实现录像,在视频中添加时间水印,并且在录像过程中,实现拍照功能,在网上查找了资料,决定使用七牛的SDK来实现这个功能,在录像中拍照,在七牛中使用 截帧回调可以实现。
https://download.csdn.net/download/ljp345775/12543119
实现录像和拍照的功能不算很难,照着官方的开发文档弄就可以了,就是这个在录像视频中添加时间水印,我的思路是通过服务每秒发送一次广播,然后,接收到广播以后,就改变一次水印。跟我以前写过一篇通过服务和广播实现多界面共享计时器的思路差不多,有兴趣的可以看一下:android中利用service和广播实现多个activity共享计时器
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化
PLShortVideoEnv.init(getApplicationContext());
}
}
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
/**
* 初始化录制对象
*/
private void initRecorder(String name) {
mShortVideoRecorder = new PLShortVideoRecorder();
mShortVideoRecorder.setRecordStateListener(this);
// 摄像头采集选项
PLCameraSetting cameraSetting = new PLCameraSetting();
//后摄像头
cameraSetting.setCameraId(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK);
cameraSetting.setCameraPreviewSizeRatio(PLCameraSetting.CAMERA_PREVIEW_SIZE_RATIO.RATIO_16_9);
cameraSetting.setCameraPreviewSizeLevel(PLCameraSetting.CAMERA_PREVIEW_SIZE_LEVEL.PREVIEW_SIZE_LEVEL_720P);
// 麦克风采集选项
PLMicrophoneSetting microphoneSetting = new PLMicrophoneSetting();
// 视频编码选项
PLVideoEncodeSetting videoEncodeSetting = new PLVideoEncodeSetting(this);
videoEncodeSetting.setEncodingSizeLevel(PLVideoEncodeSetting.VIDEO_ENCODING_SIZE_LEVEL.VIDEO_ENCODING_SIZE_LEVEL_480P_2); // 480x480
videoEncodeSetting.setEncodingBitrate(1000 * 1024); // 1000kbps
videoEncodeSetting.setEncodingFps(25);
videoEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编
// 音频编码选项
PLAudioEncodeSetting audioEncodeSetting = new PLAudioEncodeSetting();
audioEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编
// 美颜选项
// PLFaceBeautySetting faceBeautySetting = new PLFaceBeautySetting(1.0f, 0.5f, 0.5f);
// 录制选项
recordSetting = new PLRecordSetting();
recordSetting.setMaxRecordDuration(600 * 1000); // 10s
String s = FileUtils.getVideoPath(mActivity, "test");
recordSetting.setVideoCacheDir(getRootPath(mActivity));
recordSetting.setVideoFilepath(s);
// 设置录制速度 (默认为 1.0)
// PLShortVideoRecorder.setRecordSpeed(1.0);
mShortVideoRecorder.prepare(glsurfaceview, cameraSetting, microphoneSetting,
videoEncodeSetting, audioEncodeSetting, null, recordSetting);
//用来设置时间水印
mWatermarkSetting = new PLWatermarkSetting();
}
/**
* ===============截图
*/
private void screenshot() {
mShortVideoRecorder.captureFrame(new PLCaptureFrameListener() {
@Override
public void onFrameCaptured(PLVideoFrame capturedFrame) {
if (capturedFrame == null) {
return;
}
Log.i("aaa", "captured frame width: " + capturedFrame.getWidth() + " height: " + capturedFrame.getHeight() + " timestamp: " + capturedFrame.getTimestampMs());
try {
String photoName = getPhotoName();
String picturePath = getRootFile(mActivity) + "/test/" + photoName;
Log.e("aaa", "onFrameCaptured: " + picturePath);
FileOutputStream fos = new FileOutputStream(picturePath);
capturedFrame.toBitmap().compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("aaa", "图片以保存");
Toast.makeText(mActivity, photoName + " 保存成功", Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* =======保存视频
*/
private void stopAndSaveVideo() {
// 结束一段视频
mShortVideoRecorder.endSection();
mShortVideoRecorder.concatSections(new PLVideoSaveListener() {
@Override
public void onSaveVideoSuccess(String s) {
Log.e("aaa", "onSaveVideoSuccess: " + s);
runOnUiThread(new Runnable() {
@Override
public void run() {
ToastUtil.showToast(mActivity, "视频保存完成");
}
});
}
@Override
public void onSaveVideoFailed(int i) {
Log.e("aaa", "onSaveVideoFailed: " + i);
}
@Override
public void onSaveVideoCanceled() {
Log.e("aaa", "onSaveVideoCanceled: ");
}
@Override
public void onProgressUpdate(final float v) {
Log.e("aaa", "onProgressUpdate: " + v);
runOnUiThread(new Runnable() {
@Override
public void run() {
ToastUtil.showToast(mActivity, "" + v);
}
});
}
});
}
public class TimeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
if (intentAction.equals("com.ljp.recorddemo.service.timer")) {
String time = intent.getStringExtra("time");
Bitmap bitmap = fromText(50, time);
mWatermarkSetting.setPosition(0.50f, 0.05f);
mWatermarkSetting.setBitmap(bitmap);
mShortVideoRecorder.setWatermark(mWatermarkSetting);
}
}
}
/**
* 作者:Administrator
* 时间:2020/6/22 0022 13:08
* 描述:时间服务
*/
public class TimerService extends Service {
private Timer timer = null;
private TimerTask timerTask = null;
private int i = 0;
@Override
public void onCreate() {
super.onCreate();
//在创建service的时候开始计时
if(timer==null&&timerTask==null){
timer = new Timer();
timerTask = new TimerTask() {
@Override
public void run() {
i++;
//没执行一次就发送一次广播
Intent intent = new Intent();
String time1 = FileUtils.getTime1();
intent.putExtra("time", time1);
intent.setAction("com.ljp.recorddemo.service.timer");
sendBroadcast(intent);
}
};
timer.schedule(timerTask,0,1000);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if(timerTask!=null){
timerTask.cancel();
timerTask=null;
}
if(timer!=null){
timer.cancel();
timer=null;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
在这个例子中,需要申请权限,我使用的是严振杰老师的permission:2.0.0-rc11,比较好用,我还发现了一个老师的另外一个好用的项目,就是AndServer,就是在手机端搭建服务器的,我也写了一个例子,有兴趣的可以看一下
Android利用Andserver搭建服务器