通过海康接口返回的rtsp视频接口,转换成.m3u8格式文件,逻辑如下

1、采用ffmpeg实时转化rtsp链接视频,转化为m3u8,存放服务器固定地址

2、采用nginx代理视频出.m3u8视频链接地址

3、采用token+redis方式处理视频播放和删除过程,开启视频录像,并将token或者自定义文件夹存入redis,将用户token解析部分(我解析的是jwt的token最后一个点后面内容,作为当前用户的开始视频存放的文件夹A),视频摄像头唯一编码作为下面一个子文件夹B,A+B作为ffmpeg开启的key

4、停止某个视频,通过A+B停止ffmpeg视频转化,并删除B下面所有资源,包含B所有文件夹

5、退出登录,停止并删除A下面的所有视频资源转化,并删除A文件夹

6、redis中的token过期,回调方法返回过期的key,对key解析,拿到token最后一个点后面内容,也是就是文件A,对第五步进行操作

1、nginx转码配置及ffmpeg转化,我参考的下面博客

https://www.freesion.com/article/5775913700/

, 注意,java的ffmpeg部分,我自定义了一个文件夹ffmpeg,

 1、我的调用ffmpeg的start方法开始转视频流,注意转流的文件路径要先创建,fileExistTWo.mkdirs();

@Autowired
CommandManager manager;
public String toHls(String fileName, String code, String url) {
    //.m3u8文件路径String basePath = rootPath + fileName + File.separator + code + File.separator + code + File.separator;//文件夹路径String basePathTWo = rootPath + fileName + File.separator + code + File.separator;File fileExist = new File(basePath);File fileExistTWo = new File(basePathTWo);System.err.println(fileExist);// 文件夹不存在,则新建if (!fileExistTWo.exists()) {fileExistTWo.mkdirs();}// 省略查询路径部分    实体-> resultString codeId = fileName + ":" + code;manager.stop(codeId);                             // 先停止视频manager.start(codeId, CommandBuidlerFactory.createBuidler().add("ffmpeg").add("-rtsp_transport", "tcp").add("-i", url)              // 取videoUrl.add("-c", "copy").add("-f", "hls").add("-hls_time", "2.0").add("-hls_list_size", "2").add("-hls_flags", "2").add(fileExist + ".m3u8"));TaskEntity info= (TaskEntity) manager.query(codeId);System.out.println(info);int suspensionState = info.getSuspensionState();System.out.println(suspensionState);String urlHead = "http://";
//    返回路径根据ffmpeg存放视频路径+nginx代理灵活配置String urlTwo = urlHead + CommonUtil.getIpv4IP().trim() + ":" + 1011 + "/videoCache/" + fileName + "/" + code + "/" + code + ".m3u8";return urlTwo;
}

获取公网IP方法

public static String getIpv4IP() {StringBuilder result = new StringBuilder();BufferedReader in = null;try {URL realUrl = new URL("https://www.taobao.com/help/getip.php");// 打开和URL之间的连接URLConnection connection = realUrl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立实际的连接connection.connect();// 获取所有响应头字段Map<String, List<String>> map = connection.getHeaderFields();// 定义 BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result.append(line);}} catch (Exception e) {
//            log.error("获取ipv4公网地址异常");e.printStackTrace();} finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}String str = result.toString().replace("ipCallback({ip:", "");String ipStr = str.replace("})", "");return ipStr.replace('"', ' ');}

 2、停止视频方法

token值如下

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJpc3N1c2VyIiwiYXVkIjoiYXVkaWVuY2UiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yIiwicG9zdF9pZCI6IjExMjM1OTg4MTc3Mzg2NzUyMDEiLCJ1c2VyX2lkIjoiMTEyMzU5ODgyMTczODY3NTIwMSIsInJvbGVfaWQiOiIxMTIzNTk4ODE2NzM4Njc1MjAxIiwidXNlcl9uYW1lIjoiYWRtaW4iLCJuaWNrX25hbWUiOiLnrqHnkIblkZgiLCJkZXRhaWwiOnsidHlwZSI6IndlYiIsInByb2plY3RJZCI6MTU4MjAwNTQ3Mzk1NTEzMTM5MywiVXNlckNhdGVnb3J5IjoiMCIsIldzSWQiOjE0MzgzMzIwNjQ1NjExNDM4MDl9LCJ0b2tlbl90eXBlIjoiYWNjZXNzX3Rva2VuIiwiZGVwdF9pZCI6IjExMjM1OTg4MTM3Mzg2NzUyMDEiLCJhY2NvdW50IjoiYWRtaW4iLCJjbGllbnRfaWQiOiJzYWJlciIsImV4cCI6MTY3MDU2OTAyMSwibmJmIjoxNjcwNTY1NDIxfQ.NHZiaWqrCIRukfvAqChkDNAAH34Pffm_PvQIEfqAU0SdKkS9ZNhxnB354demmkAJ2l8m3OXWIkeSkeHHGNuzEg

停止的方法如下

public R stopBackVideo(String code, String token) throws IOException {//解析jwt的token值,拿到最后面一截,这个也是不会重复String fileName = StringUtils.split(token, ".")[2];String basePath = rootPath + fileName + File.separator + code + File.separator;String basePathAll = rootPath + fileName + File.separator;List<String> fileNamesList = getFileNamesList(basePathAll);fileNamesList.forEach(x -> {System.err.println("文件名称:" + x);});System.err.println(basePathAll);File fileExist = new File(basePath);String codeId = fileName + ":" + code;//停止ffmpeg转码manager.stop(codeId);manager.start(codeId, CommandBuidlerFactory.createBuidler().add("rm -rf", fileExist.toString()));//对文件夹进行删除操作if (fileExist.exists()) {deleteDir(basePath);}return R.data("删除成功");
}

删除文件夹下面所有文件

public void deleteDir(String basePath) throws IOException {Path path = Paths.get(basePath);Files.walkFileTree(path,new SimpleFileVisitor<Path>() {// 先去遍历删除文件@Overridepublic FileVisitResult visitFile(Path file,BasicFileAttributes attrs) throws IOException {Files.delete(file);System.out.printf("文件被删除 : %s%n", file);return FileVisitResult.CONTINUE;}// 再去遍历删除目录@Overridepublic FileVisitResult postVisitDirectory(Path dir,IOException exc) throws IOException {Files.delete(dir);System.out.printf("文件夹被删除: %s%n", dir);return FileVisitResult.CONTINUE;}});
}

3、停止并删除当前用户的所有视频,及记录 

public void removeAllVideoByToken(String token1) throws IOException {String fileName = StringUtils.split(token1, ".")[2];String basePathAll = rootPath + fileName + File.separator;File fileExist = new File(basePathAll);// 文件夹文件夹存在,则停止后删除if (fileExist.exists()) {List<String> fileNamesList = getFileNamesList(basePathAll);if (CollectionUtils.isNotEmpty(fileNamesList)) {fileNamesList.forEach(x -> {try {stopBackVideo(x, token1);} catch (IOException e) {e.printStackTrace();}});if (fileExist.exists()) {deleteDir(basePathAll);}}}
}

拿取到所有该文件目录,下面所有的文件夹名称 集合

private List<String> getFileNamesList(String path) {File file = new File(path);if (!file.exists()) {return null;}List<String> fileNames = new ArrayList<>();return getFileNames(file, fileNames);}/*** 得到文件名称** @param file      文件* @param fileNames 文件名* @return {@link List}<{@link String}>*/private List<String> getFileNames(File file, List<String> fileNames) {File[] files = file.listFiles();for (File f : files) {if (f.isDirectory()) {fileNames.add(f.getName());}}//所有文件
//       if (f.isDirectory()) {
//          getFileNames(f, fileNames);
//       } else {
//          fileNames.add(f.getName());
//       }
//    }return fileNames;}

4、监听redis中token失效回调方法,并停止用户的没有关闭的视频流,删除文件,减少资源占用

redis.conf将 notify-keyspace-events修改 成Ex

notify-keyspace-events Ex

RedisMessageListenerContainer 加入容器

@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);return container;
}

我是放在application下面

监听key变化,key过期则对视频流进行清理操作

@Component@Slf4jpublic class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {super(listenerContainer);}@AutowiredCameraSecretInfoService cameraSecretInfoService;/*** key过期触发的事件*/@SneakyThrows@Overridepublic void onMessage(Message message, byte[] pattern) {String channel = new String(message.getChannel(), StandardCharsets.UTF_8);String key = new String(message.getBody(), StandardCharsets.UTF_8);boolean contains = key.contains("bladeFile:fileName:");if (contains) {log.info("redis key 过期:pattern={},channel={},key={}", new String(pattern), channel, key);String token = key.substring(19);cameraSecretInfoService.removeAllVideoByToken(token);}}
}

海康视频回放,rtsp视频接口转换成.m3u8格式文件相关推荐

  1. 视频AVI如何批量快速转换成MP4格式

    可能现在大部分人拍摄或是下载的视频都是MP4格式的,但其实视频的格式有非常多种.最近我们公司的小王就有个困扰,他的客户给了他一些AVI格式的视频,他却打不开了不知道怎么处理.其实AVI是将语音和影像同 ...

  2. 视频里的音乐怎么转换成mp3格式?

    视频里的音乐怎么转换成mp3格式?视频里的音乐转换为mp3的原因有很多,主要是因为mp3格式是一种音频格式,文件大小较小,更易于存储和传输.相比之下,视频格式则是一种视频文件格式,虽然包含音频,但我们 ...

  3. word文档转换成swf格式文件在网页中用flash显示

    word文档转换成swf格式文件在网页中用flash显示 在OA系统中我们常常需要将上传的word文档在网页中阅览,一般上传后的文档用html的形式查看是会导致排版混乱的,这次我介绍在ASP.NET中 ...

  4. python html转word文档_Python实现将HTML转换成doc格式文件的方法示例

    本文实例讲述了Python实现将HTML转换成doc格式文件的方法.分享给大家供大家参考,具体如下: 网页上的一些文章,因为有格式的原因,它们在网页上的源码都是带有html标签的,用css来进行描述. ...

  5. 如何把PDF文档转换成TXT格式文件

    在日常学习和日常工作中,如何将PDF文件转换为TXT文本? 尽管PDF文件的用户数量正在增加,但是TXT文本格式的接受度将会更高. 毕竟,TXT文本格式是任何设备都可以打开的格式.那么如何将PDF文件 ...

  6. python将源代码转换成在html可显示的格式,Python实现将HTML转换成doc格式文件的方法示例...

    Python实现将HTML转换成doc格式文件的方法示例 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Python实现将HTML转换成doc格式文件的方法示例. ...

  7. python修改文件格式为jpg_python将.ppm格式图片转换成.jpg格式文件的方法

    python将.ppm格式图片转换成.jpg格式文件的方法 将.ppm格式的图片转换成.jpg格式的图像,除了通过软件转换,还可以使用python脚本直接转换,so easy!!! from PIL ...

  8. 如何将pdf文件转换成cad格式文件

    pdf文件是一个封闭性文件,文件不仅不容易编辑修改,而且还可能被加密了,那么如何将pdf文件转换成cad格式文件呢? 下面小编教大家使用pdf转换器实现以上操作,具体步骤如下. 第一步:搜索迅捷pdf ...

  9. SWF格式的视频如何快速无损地转换成MP4格式

    SWF格式是一个动画文件,被广泛应用于网页设计.动画制作等领域.有时候我们需要将我们制作好的SWF格式动画转换成MP4格式的视频.那么该如何进行转换呢?其实很简单.下面小编便来分享我们平时转换的方法给 ...

最新文章

  1. 【Android UI设计与开发】第04期:引导界面(四)仿人人网V5.9.2最新版引导界面
  2. java 端口8161_ActiveMQ_Windows和Linux版本的安装部署
  3. python 怎么安装opencv?
  4. js方法的声明与调用
  5. mysql多实例访问代理_MySql-Proxy之多路结果集归并
  6. GrepWin:Win7下的文本替换工具
  7. leetcode101. 对称二叉树(两种做法)
  8. [数据结构]链表中销毁和清空的区别
  9. JDBC入门案例及相关API概述
  10. 懂分析、会预测,你见过这样的华为云DAS吗?
  11. html 读取 vb,VB编程:vb读取textbox控件某一行的方法
  12. 感谢所有常来我博客的朋友
  13. springboot统一异常处理及返回数据的处理
  14. 在宿舍的同学们,只要你有本本,就可以免费无线上网~~
  15. 住在上千万的豪宅里,你猜建筑成本占多少?
  16. 应用图标变小及换图标不生效的问题
  17. [Swift]LeetCode41. 缺失的第一个正数 | First Missing Positive
  18. vue + element 使用 iframe
  19. 由阿里IPO引发的思考:什么样的互联网公司才是好公司?
  20. 【C#】控制台应用程序闪退解决方法

热门文章

  1. POJ 1062 昂贵的聘礼 (dijkstra)
  2. 兴趣点检测方法及其最新改进思路
  3. 时间序列数据灌注与消费
  4. php函数不支持的功能有什么,wapl是什么功能?启用有什么用
  5. 北航计算机控制大作业,北航计算机控制系统大作业.docx
  6. 蓝牙上层协议,服务端的启动,获取以及蓝牙设备的连接
  7. 计算机应用基础110003,江苏开放大学计算机应用基础第一次
  8. 输入框输入手机号,中间插入空格格式化,且限制11位
  9. 如何用全自动引流脚本轻松引流短视频平台
  10. 筛查了超5000项全球研究后,FDA证实电子烟比卷烟危害小