websocket播放rtsp方案之websocket按帧播放rtsp

1 回顾

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

        不废话,上才艺!

2 代码实现

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

2.1 websocket

@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);
	}
}

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

/**
 *  获取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;
                    }
                }
            }
        }
    }

}

2.3 几个使用到的类

/**
 * 图片转码器
 */
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);
        }
    }

3 测试验证

@Slf4j
@Controller
public class IndexController {
    @Autowired
    RTSPToImage RTSPToImage;

    @GetMapping("/test")
    public void test() {
        RTSPToImage.live();
        return;
    }
}

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

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

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
WebSocket是一种全双工通信协议,而RTSP(Real-Time Streaming Protocol)是一种用于实时流媒体的传输协议。虽然WebSocket原本设计用于在浏览器和服务器之间建立低延迟、高效的实时通信连接,但可以通过WebSocket播放RTSP流。 在使用WebSocket播放RTSP时,可以采取以下步骤: 1. 客户端与服务器建立WebSocket连接。 2. 客户端发送包含RTSP流地址的消息给服务器。 3. 服务器接收到消息后,解析RTSP流地址,并建立与该地址的RTSP连接。 4. 一旦RTSP连接建立成功,服务器开始接收来自RTSP流的数据。 5. 服务器将接收到的RTSP流数据通过WebSocket发送给客户端。 6. 客户端接收到WebSocket消息,解析数据并渲染播放器进行播放。 需要注意的是,WebSocket本身并不支持RTSP协议。因此,在服务器端需要使用一些库或框架来处理RTSP连接,并将数据流转发到WebSocket。类似的实现通常会使用一些第三方库,如Node.js中的ws(WebSocket模块)和ffmpeg(用于处理多种媒体流)。 通过WebSocket播放RTSP流能够实现实时的音视频传输,并且相较于传统的RTSP播放方式,不需要使用插件或特定的播放器,而是直接在浏览器端实现。这样,用户可以使用现代浏览器来播放RTSP流,无需额外安装插件或软件。 总结来说,通过WebSocket播放RTSP流可以实现实时的音视频传输,并且可以在现代浏览器中直接播放,无需额外插件或软件支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值