依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId><version>5.2.5.RELEASE</version><scope>compile</scope>
</dependency>

1.视频工具类

import org.apache.log4j.Logger;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.WebSocketSession;import java.io.InputStream;
import java.util.List;/*** <pre>* TODO:视频工具类* </pre>** @author zhangjunchao* @date 2019/8/19*/
public class VideoUtils {private final static Logger logger = Logger.getLogger(VideoUtils.class);// 声明的ffmpeg.exe固定路径变量public  String FFMPEG_PATH = "D:/ffmpeg/bin/ffmpeg.exe";public  String channel = "";public  WebSocketSession webSocketSession = null;private  Process process;public VideoUtils(String channel, WebSocketSession webSocketSession) {// ffmpeg路径需要更换自己的FFMPEG_PATH = "D:\\developsoftware\\wisdom_screen_ds1200\\server\\ETCMornitoring\\src\\main\\resources" +"\\export_template" +"\\ffmpeg.exe";this.channel = channel;this.webSocketSession = webSocketSession;}/*** 视频转换** @param video_path*/public void convertCommand() {String channel = this.channel;WebSocketSession webSocketSession = this.webSocketSession;System.out.println("start");System.out.println(FFMPEG_PATH);InputStream errorStream = null;InputStream inputStream = null;try {List<String> commands = new java.util.ArrayList<String>();commands.add(FFMPEG_PATH);commands.add("-rtsp_transport");commands.add("tcp");commands.add("-i");commands.add(channel);commands.add("-vcodec");commands.add("copy");commands.add("-an");commands.add("-f");commands.add("mp4");commands.add("-movflags");commands.add("empty_moov+default_base_moof+frag_keyframe"); // <- Chrome); "frag_keyframe+empty_moov" <-// firefoxcommands.add("-reset_timestamps");commands.add("1");commands.add("-vsync");commands.add("1");commands.add("-flags");commands.add("global_header");commands.add("-bsf:v");commands.add("dump_extra");commands.add("-y");commands.add("-");ProcessBuilder builder = new ProcessBuilder();builder.command(commands);process = builder.start();//输出流inputStream = process.getInputStream();//错误流errorStream = process.getErrorStream();while (webSocketSession!=null&&webSocketSession.isOpen()) {if (!process.isAlive()) {System.out.println("shutdown");break;}byte[] b=new byte[1024*64];byte[] errb=new byte[1024*64];int readbytes = 0;int readbytesError = 0;try {//errorStream必须read不然缓冲区满了inputstream读不到数据if (errorStream.available() != 0) {readbytesError = errorStream.read(errb,0,errorStream.available());System.out.println("error:" + new String(errb,"utf-8"));}if (inputStream.available() != 0) {readbytes = inputStream.read(b,0,inputStream.available() );System.out.println("read:" + readbytes);System.out.println("write:" + readbytes);if (webSocketSession.isOpen()) {webSocketSession.sendMessage(new BinaryMessage(b, 0, readbytes, true));}}Thread.sleep(30);} catch (Exception e2) {}}if (errorStream != null) {errorStream.close();errorStream = null;}if (inputStream != null) {inputStream.close();inputStream = null;}process.destroy();} catch (Exception e) {process.destroy();} finally {if (process.isAlive()) {process.destroyForcibly();}}}
}

2.WebSocket握手拦截器

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;import java.util.Map;/*** WebSocket握手拦截器*/
public class WebSocketInterceptor implements HandshakeInterceptor {// 握手前@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,Map<String, Object> attr) throws Exception {if (request instanceof ServletServerHttpRequest) {ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;try {String user = servletRequest.getServletRequest().getParameter("WEBSOCKET_USERNAME");attr.put("WEBSOCKET_USERNAME", user);} catch (Exception ex) {}}return true;}// 握手后@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,Exception e) {}
}

3.applicationWebContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:websocket="http://www.springframework.org/schema/websocket"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/websockethttp://www.springframework.org/schema/websocket/spring-websocket.xsd"><websocket:handlersallowed-origins="*"order="0"><websocket:mappinghandler="VideoHandler"path="/common/mornitoring/video"/><websocket:handshake-interceptors><bean class="com.hndfsj.websocket.WebSocketInterceptor"/></websocket:handshake-interceptors></websocket:handlers></beans>

4.视频处理器

import com.hndfsj.app.monitoring.utils.VideoUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;import java.util.concurrent.ConcurrentHashMap;/*** <pre>* TODO:视频处理器* </pre>** @author zhangjunchao* @date 2019/8/26*/
@Component("VideoHandler")
public class VideoHandler extends AbstractWebSocketHandler {// 线程安全的静态变量,表示在线连接数private static volatile int onlineCount = 0;// 若要实现服务端与指定客户端通信的话,可以使用Map来存放,其中Key可以为用户标识public static ConcurrentHashMap<String, WebSocketSession> webSocketMap = new ConcurrentHashMap<String,WebSocketSession>();@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {try{}catch(Exception ex){}}// 摄像头@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {// 获取当前用户String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME");//指定客户端通讯webSocketMap.put(username, session);//更新在线连接数onlineCount = webSocketMap.size();//调用视频工具列VideoUtils v1 = new VideoUtils("rtsp://admin:1111@192.168.10.248:554/h264/ch1/sub/av_stream",session);// 执行转换命令v1.convertCommand();}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {System.out.println("websocket 关闭");String username = (String) session.getAttributes().get("WEBSOCKET_USERNAME");if (webSocketMap.get(username) != null) {if (webSocketMap.get(username).isOpen()) {webSocketMap.get(username).close();}webSocketMap.remove(username);onlineCount = webSocketMap.size();}}
}

5.连接测试

WebSocket 在线测试 v13:http://www.websocket-test.com/

ws://127.0.0.1:8080/common/mornitoring/video?WEBSOCKET_USERNAME=111111

java SSM框架使用WebSocket推送视频流相关推荐

  1. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】分享

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

  2. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

  3. 用 Go 编写一个简单的 WebSocket 推送服务

    用 Go 编写一个简单的 WebSocket 推送服务 本文中代码可以在 github.com/alfred-zhon- 获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息都是通过短信,微 ...

  4. 抓取WebSocket推送的消息

    介绍 很多直播或对数据及时性要求比较高的网站,使用了WebSocket.这种数据要怎么抓呢? 我们这里以socket.io为例,我们可以查看网站网页源代码看使用的H5的WebSocket还是socke ...

  5. 极光 php 自定义消息,laravel框架使用极光推送消息操作示例

    本文实例讲述了laravel框架使用极光推送消息.分享给大家供大家参考,具体如下: 最近需要使用极光推送往客户端推消息,所以这里记录下使用过程. 极光推送的服务端文档: https://docs.ji ...

  6. php极光推送教程,laravel框架使用极光推送消息操作示例

    本文实例讲述了laravel框架使用极光推送消息.分享给大家供大家参考,具体如下: 最近需要使用极光推送往客户端推消息,所以这里记录下使用过程. 极光推送的服务端文档: https://docs.ji ...

  7. java 百度api接口开发_百度熊掌号使用Java工具类对接API推送接口进行文章推送实例详解...

    对于java程序员来说,自己运维的百度熊掌号当然得使用java的方式去每天推送文章了.目前,百度推出了百度熊掌号服务.旨在更好的为站长服务.那么百度熊掌号如何通过推送API接口实现自动文章推送呢? 第 ...

  8. java ssm框架 mapper文件里的#符号和$符号的区别

    Java SSM框架里面,Mapper.xml文件 (一)#符号生成的sql语句是作为传参的 <!-- 获得数据列表(包括课程相关信息) --><select id="Ge ...

  9. java集成jpush实现客户端推送

    代码地址如下: http://www.demodashi.com/demo/13700.html 前言 java 集成jpush 实现客户端推送 ###一.准备工作 开发环境: jdk1.6 Ecli ...

最新文章

  1. Windows 下 tail 查看日志命令工具分享
  2. Android设计模式-观察者模式
  3. 两个蓝牙模块配对的方法
  4. 前端技术周刊 2019-01-21:跨端开发的三条路线
  5. 微服务面试必问的Dubbo,这么详细还怕自己找不到工作?
  6. * poj 1251 JungleRoad 最小生成树 Kruskal算法、Prim算法
  7. 福布斯中国发布最杰出商界女性排行榜:董明珠再次夺冠
  8. Intellij IDEA的配置
  9. 1036 跟奥巴马一起编程 (15 分)—PAT (Basic Level) Practice (中文)
  10. solr mysql安装教程_Solr安装使用教程
  11. 将QQ和微信的保存路径由C盘转移到其他盘
  12. 什么是vr直播?新上线APP 3分钟开启vr直播大秀
  13. Poland’s ruling Law and Justice party is doing lasting damage
  14. Nand2Tetris - Week 1
  15. 遍身罗绮者 不是养蚕人
  16. Android Studio Buid缓慢问题
  17. 【SIM】MCC(移动国家码)和 MNC(移动网络码)
  18. Spark Scala当中reduceByKey(_+_) reduceByKey((x,y) => x+y)的用法
  19. 动漫Q版人物头部怎么画?
  20. Sqlite3中对于毫秒数和本地时间之间的转换以及时间相关操作

热门文章

  1. Adobe AcrobatDistiller 字体错误“Times-Roman not found. Font cannot
  2. 万千企业看好百度爱采购运营推广的四个理由@运营猫工具箱
  3. 【Unity资源】(贴图和材质)
  4. 亲测解决注册kaggle时不出现验证码的问题!
  5. 基本类型和引用类型区别
  6. win7 java不是内部或外部命令_Win7系统输入javac命令提示“javac不是内部或外部命令”怎么办...
  7. 【代码质量】码农提升代码质量的三重境界
  8. mybatis自定义动态sql传入对象
  9. 中台这块“硬骨头”,久久丫越啃越有味道!
  10. python制作视频播放器_Python使用PyQT制作视频播放器!专属播放器~