2021SC@SDUSC
使用springboot进行后端开发,这部分后端由我完成。
一.引言
通过项目实训,我算是正式开始使用springboot作为后端框架来开发。在这个过程中,不断出错,改错,感觉自己的代码能力真的有进步,感觉收获很大,让我很开心。
选择springboot作为后端开发框架,首先考虑springboot的高效性,简洁性。抛弃了繁琐的xml配置过程,采用大量默认的配置来简化我们的spring开发过程。
其次能够直接使用Java main方法启动内嵌的Tomcat服务器运行springboot程序,不需要部署war包。
提供约定的starter POM来简化Maven配置,让Maven的配置变得简单。而且基本上可以完全不使用xml配合文件,采用注解配置。
二.后端记录
1.视频大文件的上传
上传大文件时,我们一般都会采用分片上传的方式,这样如果上传过程中断了,下次继续上传的话就不用重新全部上传,只需继续上传未上传的部分即可,进而可以实现秒传的效果。
原理其实就是在客户端将文件分割成多个小的分片,然后再将这些分片一片一片的上传给服务端,服务端拿到所有分片后再将这些分片合并起来还原成原来的文件。那服务端怎么知道我合并出来的文件是否和服务端上传的文件完全一样呢?这就需要用到文件的MD5值了。文件的MD5值就相当于是这个文件的“数字指纹”,只有当两个文件内容完全一样时,他们的MD5值才会一样。所以在上传文件前,客户端需要先计算出文件的MD5值,并且把这MD5值传递给服务端。服务端通过MD5唯一标识一个文件。
核心点罗列
MD5缓存
开始收到时加入,全部分片接收后移除。
private static final ConcurrentMap<String, File> MD5_CACHE
= new ConcurrentHashMap<String, File>()是否生成了文件?存在代表这个md5对应视频还在传中,否则代表第一次上传。
File targetFile = MD5_CACHE.get(md5);
if (targetFile == null) { // 没有生成的话就生成一个新的文件 targetFile = new File(DATA_DIR, id + "_" + name); targetFile.getParentFile().mkdirs(); MD5_CACHE.put(md5, targetFile); }完全传完后从MD5_CACHE中移除 if (finished) { System.out.println("success."); MD5_CACHE.remove(md5);这个方法可以对文件的任意位置进行读写 RandomAccessFile accessFile = new RandomAccessFile(targetFile, "rw");seek(long a)是定位文件指针在文件中的位置。参数a确定读写位置距离文件开头的字节个数
服务端在合并出文件后,在计算合并出的文件的MD5值,与客户端传递过来的进行比较,如果一致,则说明上传成功,若不一致,则说明上传过程中可能出现了丢包,上传失败。
2.人脸照片上传
上传人脸照片后端这里有一个逻辑判断就是先来检测一下上传的照片是否是人脸,以及人脸是否符合规范,例如五官都存在,如果不满足,则让客户端重传,满足的话才执行下面的算法。
人脸检测代码
这部分代码我使用的是Opencv中的一个级联分类器对人脸照片识别。
CascadeClassifier,是Opencv中做人脸检测的时候的一个级联分类器。并且既可以使用Haar,也可以使用LBP特征。
Haar特征是一种反映图像的灰度变化的,像素分模块求差值的一种特征。它分为三类:边缘特征、线性特征、中心特征和对角线特征。用黑白两种矩形框组合成特征模板,在特征模板内用 黑色矩形像素和 减去 白色矩形像素和来表示这个模版的特征值。
例如:脸部的一些特征能由矩形模块差值特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述在特定方向(水平、垂直、对角)上有明显像素模块梯度变化的图像结构。这样就可以进行区分人脸。
#读取图像
def readImg(path):
img = cv2.imread(path)
if img is None:
tmp = imageio.mimread(path)
if tmp is not None:
tmp = np.array(tmp)
img = tmp[0][:, :, :3]
return img
#获取命令行参数
path=sys.argv[1]
#识别人脸
face_cascade = cv2.CascadeClassifier('resources/haarcascade_frontalface_alt.xml')
img=readImg(path)
face = face_cascade.detectMultiScale(img,1.1,4)
核心点罗列
在照片上传结束后,调用python上面的人脸检测代码,根据返回值返回前端上传成功情况。
然后接下来是把人脸照片上传到服务器:
//照片上传
videoName=videoName.substring(0,videoName.indexOf("."));
String name2=name.substring(0,name.indexOf("."));
file_to_faces("F:/demo/temp/photo/" + id + "_" + name, id, id + "_" + videoName, id + "_" + name2);
这里file_to_faces是ssh制作的往服务器传的,用来向服务器传照片,由另一位同学编写。
//上传照片到faceS
public static void file_to_faces(String local_dir,String ID,String VideoName,String picture_name){
try {
String commandStr="cd ../opt/data/private/xuyunyang/EasyCut/"+ID+"/"+ID+"_"+VideoName+"/Resources/faceS/;mkdir "+picture_name;
Boolean result=Connection_to_Sever.connectLinux("222.206.4.160",25935,"root","shixun123",commandStr);
Connection_to_Sever.scpPut("222.206.4.160",25935,"root","shixun123", local_dir,"../opt/data/private/xuyunyang/EasyCut/"+ID+"/"+ID+"_"+VideoName+"/Resources/faceS/"+picture_name);
} catch (Exception e) {
e.printStackTrace();
}
}
文章评论