赞
踩
上篇文章简单介绍了websocket的使用,有了这个基础我们就可以继续今天的内容了,原本想跳过websocket的介绍,但因为自己以前在项目中也没有使用过,就顺道说一说。
不废话,上才艺!
因为在上一篇文章中有了导包与配置本文就跳过该内容!直接上方案demo代码。
- @Slf4j
- @ServerEndpoint(value = "/webSocket", encoders = {ImageEncoder.class})
- @Component
- public class WebSocketReceiveMessage {
-
- //用来存放每个客户端对应的WebSocketReceiveMessage对象,适用于同时与多个客户端通信
- public static CopyOnWriteArraySet<WebSocketReceiveMessage> webSocketSet = new CopyOnWriteArraySet<>();
-
- //与某个客户端的连接会话,通过它实现定向推送
- private Session session;
-
- /**
- * 建立连接成功调用的方法
- */
- @OnOpen
- public void onOpen(Session session) {
- this.session = session;
- // 添加到set中
- webSocketSet.add(this);
- log.info("用户连接成功!");
- }
-
- /**
- * 关闭连接调用的方法
- */
- @OnClose
- public void onClose(Session closeSession){
- webSocketSet.remove(this);
- log.info("用户退出!");
- }
-
- /**
- * 收到客户端消息调用的方法
- */
- @OnMessage
- public void onMessage(String message,Session mysession) throws Exception{
- log.info("--------on message---{}----",message);
- for (WebSocketReceiveMessage item: webSocketSet) {
- item.sendAllMessage(message);
- }
- }
-
- public static void sendAllByObject(Object message) {
- if (!webSocketSet.isEmpty()) {
- for (WebSocketReceiveMessage next : webSocketSet) {
- next.sendMessageByObject(message);
- }
- }
- }
-
- public void sendMessageByObject(Object message) {
- if (message != null) {
- try {
- this.session.getBasicRemote().sendObject(message);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- public void sendAllMessage(String message) throws IOException {
- this.session.getBasicRemote().sendText(message);
- }
- }
- /**
- * 获取rtsp流,抓取每帧,通过websocket传递给前台显示
- */
- @Slf4j
- @Component
- @EnableAsync
- public class RTSPToImage {
-
- @Value("${rtsp.url:rtsp://admin:123456@192.168.1.107/cam/realmonitor?channel=1&subtype=1}")
- private String rtspUrl;
-
- @Value("${rtsp.transport.type:udp}")
- private String rtspTransportType;
-
-
- /**
- * 异步开启获取rtsp流,通过websocket传输数据
- */
- @Async
- public void live() {
- log.info("开始创建grabber");
- FFmpegFrameGrabber grabber = null;
- try {
- grabber = new FFmpegFrameGrabber(rtspUrl);
- grabber.setOption("rtsp_transport", rtspTransportType);
- //设置帧率
- grabber.setFrameRate(25);
- //设置获取的视频宽度
- grabber.setImageWidth(996);
- //设置获取的视频高度
- grabber.setImageHeight(996);
- //设置视频bit率
- grabber.setVideoBitrate(2000000);
- //设置日志等级
- avutil.av_log_set_level(avutil.AV_LOG_ERROR);
- grabber.start();
- log.info("创建并启动grabber成功");
- }catch (Exception e){
- e.printStackTrace();
- }
-
- //推送图片
- Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
- while (true) {
- try {
- if (grabber != null) {
- Frame frame = grabber.grabImage();
- if (null == frame) {
- continue;
- }
- BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ImageIO.write(bufferedImage, "jpg", out);
- //使用websocket发送视频帧数据
- WebSocketReceiveMessage.sendAllByObject(new Image(out.toByteArray()));
- }
- } catch (Exception e) {
- e.printStackTrace();
- if (grabber != null) {
- try {
- grabber.stop();
- } catch (Exception e1) {
- e1.printStackTrace();
- } finally {
- grabber = null;
- }
- }
- }
- }
- }
-
- }
- /**
- * 图片转码器
- */
- public class ImageEncoder implements Encoder.Text<Image> {
-
- @Override
- public String encode(Image image) throws EncodeException {
- if(image != null && !ArrayUtils.isEmpty(image.getImageByte())){
- String base64Image= Base64.encode(image.getImageByte());
- return JSON.toJSONString(new AjaxResult(AjaxResult.Type.SUCCESS,"获取帧成功",base64Image));
- }
- return JSON.toJSONString(new AjaxResult(AjaxResult.Type.ERROR,"获取帧失败",null));
- }
-
- @Override
- public void init(EndpointConfig endpointConfig) {
-
- }
-
- @Override
- public void destroy() {
-
- }
- }
- /**
- * 图片实体
- */
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @Accessors(chain = true)
- public class Image {
- private byte[] imageByte;
- }
- /**
- * 返回信息
- */
- public class AjaxResult extends HashMap<String, Object> {
- private static final long serialVersionUID = 1L;
-
- //状态码
- public static final String CODE = "code";
-
- //返回信息
- public static final String MSG = "msg";
-
- //数据
- public static final String DATA = "data";
-
- /**
- * 状态类型
- */
- public enum Type {
- SUCCESS(200),
- ERROR(500);
- private final int value;
- Type(int value) {
- this.value = value;
- }
- public int value() {
- return this.value;
- }
- }
-
- public AjaxResult(Type type, String msg, Object data) {
- super.put(CODE, type.value);
- super.put(MSG, msg);
- if (ObjectUtils.isNotEmpty(data)) {
- super.put(DATA, data);
- }
- }
- @Slf4j
- @Controller
- public class IndexController {
- @Autowired
- RTSPToImage RTSPToImage;
-
- @GetMapping("/test")
- public void test() {
- RTSPToImage.live();
- return;
- }
- }
我们在websocket中连接后即可获取到返给前端显示的图字节数组。
最后等前端哥们儿把前端代码实现了看能不能搞到前端代码;写个完整的demo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。