当前位置:   article > 正文

websocket播放rtsp方案之websocket按帧播放rtsp_websocket方案实现rtsp

websocket方案实现rtsp

1 回顾

        上篇文章简单介绍了websocket的使用,有了这个基础我们就可以继续今天的内容了,原本想跳过websocket的介绍,但因为自己以前在项目中也没有使用过,就顺道说一说。  

        不废话,上才艺!

2 代码实现

因为在上一篇文章中有了导包与配置本文就跳过该内容!直接上方案demo代码。

2.1 websocket

  1. @Slf4j
  2. @ServerEndpoint(value = "/webSocket", encoders = {ImageEncoder.class})
  3. @Component
  4. public class WebSocketReceiveMessage {
  5. //用来存放每个客户端对应的WebSocketReceiveMessage对象,适用于同时与多个客户端通信
  6. public static CopyOnWriteArraySet<WebSocketReceiveMessage> webSocketSet = new CopyOnWriteArraySet<>();
  7. //与某个客户端的连接会话,通过它实现定向推送
  8. private Session session;
  9. /**
  10. * 建立连接成功调用的方法
  11. */
  12. @OnOpen
  13. public void onOpen(Session session) {
  14. this.session = session;
  15. // 添加到set中
  16. webSocketSet.add(this);
  17. log.info("用户连接成功!");
  18. }
  19. /**
  20. * 关闭连接调用的方法
  21. */
  22. @OnClose
  23. public void onClose(Session closeSession){
  24. webSocketSet.remove(this);
  25. log.info("用户退出!");
  26. }
  27. /**
  28. * 收到客户端消息调用的方法
  29. */
  30. @OnMessage
  31. public void onMessage(String message,Session mysession) throws Exception{
  32. log.info("--------on message---{}----",message);
  33. for (WebSocketReceiveMessage item: webSocketSet) {
  34. item.sendAllMessage(message);
  35. }
  36. }
  37. public static void sendAllByObject(Object message) {
  38. if (!webSocketSet.isEmpty()) {
  39. for (WebSocketReceiveMessage next : webSocketSet) {
  40. next.sendMessageByObject(message);
  41. }
  42. }
  43. }
  44. public void sendMessageByObject(Object message) {
  45. if (message != null) {
  46. try {
  47. this.session.getBasicRemote().sendObject(message);
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. }
  53. public void sendAllMessage(String message) throws IOException {
  54. this.session.getBasicRemote().sendText(message);
  55. }
  56. }

2.2 rtsp流转换为图片通过websocket发送给前端展示

  1. /**
  2. *  获取rtsp流,抓取每帧,通过websocket传递给前台显示  
  3. */
  4. @Slf4j
  5. @Component
  6. @EnableAsync
  7. public class RTSPToImage {
  8. @Value("${rtsp.url:rtsp://admin:123456@192.168.1.107/cam/realmonitor?channel=1&subtype=1}")
  9. private String rtspUrl;
  10. @Value("${rtsp.transport.type:udp}")
  11. private String rtspTransportType;
  12. /**
  13. * 异步开启获取rtsp流,通过websocket传输数据
  14. */
  15. @Async
  16. public void live() {
  17. log.info("开始创建grabber");
  18. FFmpegFrameGrabber grabber = null;
  19. try {
  20. grabber = new FFmpegFrameGrabber(rtspUrl);
  21. grabber.setOption("rtsp_transport", rtspTransportType);
  22. //设置帧率
  23. grabber.setFrameRate(25);
  24. //设置获取的视频宽度
  25. grabber.setImageWidth(996);
  26. //设置获取的视频高度
  27. grabber.setImageHeight(996);
  28. //设置视频bit率
  29. grabber.setVideoBitrate(2000000);
  30. //设置日志等级
  31. avutil.av_log_set_level(avutil.AV_LOG_ERROR);
  32. grabber.start();
  33. log.info("创建并启动grabber成功");
  34. }catch (Exception e){
  35. e.printStackTrace();
  36. }
  37. //推送图片
  38. Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
  39. while (true) {
  40. try {
  41. if (grabber != null) {
  42. Frame frame = grabber.grabImage();
  43. if (null == frame) {
  44. continue;
  45. }
  46. BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);
  47. ByteArrayOutputStream out = new ByteArrayOutputStream();
  48. ImageIO.write(bufferedImage, "jpg", out);
  49. //使用websocket发送视频帧数据
  50. WebSocketReceiveMessage.sendAllByObject(new Image(out.toByteArray()));
  51. }
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. if (grabber != null) {
  55. try {
  56. grabber.stop();
  57. } catch (Exception e1) {
  58. e1.printStackTrace();
  59. } finally {
  60. grabber = null;
  61. }
  62. }
  63. }
  64. }
  65. }
  66. }

2.3 几个使用到的类

  1. /**
  2. * 图片转码器
  3. */
  4. public class ImageEncoder implements Encoder.Text<Image> {
  5. @Override
  6. public String encode(Image image) throws EncodeException {
  7. if(image != null && !ArrayUtils.isEmpty(image.getImageByte())){
  8. String base64Image= Base64.encode(image.getImageByte());
  9. return JSON.toJSONString(new AjaxResult(AjaxResult.Type.SUCCESS,"获取帧成功",base64Image));
  10. }
  11. return JSON.toJSONString(new AjaxResult(AjaxResult.Type.ERROR,"获取帧失败",null));
  12. }
  13. @Override
  14. public void init(EndpointConfig endpointConfig) {
  15. }
  16. @Override
  17. public void destroy() {
  18. }
  19. }
  1. /**
  2. * 图片实体
  3. */
  4. @Data
  5. @AllArgsConstructor
  6. @NoArgsConstructor
  7. @Accessors(chain = true)
  8. public class Image {
  9. private byte[] imageByte;
  10. }
  1. /**
  2. * 返回信息
  3. */
  4. public class AjaxResult extends HashMap<String, Object> {
  5. private static final long serialVersionUID = 1L;
  6. //状态码
  7. public static final String CODE = "code";
  8. //返回信息
  9. public static final String MSG = "msg";
  10. //数据
  11. public static final String DATA = "data";
  12. /**
  13. * 状态类型
  14. */
  15. public enum Type {
  16. SUCCESS(200),
  17. ERROR(500);
  18. private final int value;
  19. Type(int value) {
  20. this.value = value;
  21. }
  22. public int value() {
  23. return this.value;
  24. }
  25. }
  26. public AjaxResult(Type type, String msg, Object data) {
  27. super.put(CODE, type.value);
  28. super.put(MSG, msg);
  29. if (ObjectUtils.isNotEmpty(data)) {
  30. super.put(DATA, data);
  31. }
  32. }

3 测试验证

  1. @Slf4j
  2. @Controller
  3. public class IndexController {
  4. @Autowired
  5. RTSPToImage RTSPToImage;
  6. @GetMapping("/test")
  7. public void test() {
  8. RTSPToImage.live();
  9. return;
  10. }
  11. }

我们在websocket中连接后即可获取到返给前端显示的图字节数组。

最后等前端哥们儿把前端代码实现了看能不能搞到前端代码;写个完整的demo

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/280119
推荐阅读
相关标签
  

闽ICP备14008679号