整合视频流截图+图片上传微服务
2018-03-06 本文已影响0人
questionuncle
经过一段时间技术积累,今天将摄像头抓图存图全过程串通。
大致流程是:用户通过请求触发指定摄像头从视频流中截图,将该截图上传到图片服务器中,并将图片访问地址返回给用户。
image.png
依赖服务和工具
服务名 | 工具 | 参考文章 |
---|---|---|
capturepicture-service | ffmpeg | 通过ffmpeg实现视频流截图 |
uploadpicture-service | fastdfs | 基于fastdfs实现文件上传微服务 |
如何整合
通过capturepicture-service、uploadpicture-service我们可以实现从视频流中截取图片和上传图片,但是视频流截图存在服务器物理路径下,还需要将该图片上传到fastdfs图片服务器上,那如何操作截取图片呢。
方法就是:将截取图片放到HTTP或FTP服务器目录下,capturepicture-service截图保存并返回图片url地址,center-service将截图服务返回的图片url传给uploadpicture-service,uploadpicture-service通过读取地址来获取截图的文件流,并将该文件流上传到fastdfs中。
具体实现
前面几篇博文中都有涉及到,具体请查看:
Spring Cloud微服务框架升级
Spring Cloud实现文件上传
基于fastdfs实现文件上传微服务
通过ffmpeg实现视频流截图
在串联过程中重点有两点
1.利用ffmpeg从视频流中截图,并放到指定位置同时返回文件名,该部分利用shell脚本予以实现
String cmd = "if [ ! -d /var/www/html/capture ]; then mkdir -p /var/www/html/capture; else cd /var/www/html/capture; fi; ";
cmd += "ffmpeg -y -i rtsp://user:password@" + cameraIp + ":port -ss 00:00:01 -vframes 1 -f image2 -vcodec png $(date +%Y%m%d)_" + pictureName +".png && ";
cmd += "echo $(date +%Y%m%d)_" + pictureName +".png || echo failed ";
2.从url中读取文件流
private static byte[] getImageFromNetByUrl(String strUrl) {
try {
URL url = new URL(strUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();// 通过输入流获取图片数据
byte[] btImg = readInputStream(inStream);// 得到图片的二进制数据
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
测试
通过postman模拟用户请求,返回图片服务器地址
image.png
通过浏览器访问图片服务器返回的地址
image.png
适用范围
本方案适用那些前端摄像头规格品牌不一,厂家也未开放操作摄像头接口的情况。
如果厂家直接提供操作摄像头的接口,大可不必这么折腾。
此外,本文实际操作对象是视频流,并借助ffmpeg工具,因此不仅限摄像头+截图,读者可以发挥想象,变幻出多种应用场景。