Java使用WebSocket视频拆帧进度处理与拆帧图片推送,结合Apipost进行调试

发布于:2025-04-16 ⋅ 阅读:(31) ⋅ 点赞:(0)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
@Configuration
public class WebSocketConfig {
    /**
     * 启动 WebSocket 服务器
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

webSocket拆帧进度推送

/**
 * 请求连接路径 ws://127.0.0.1:4000/ws/sp/677b4046371de933500ae72bc03bf70b
 *
 * @author zym
 * date:  2025-04-14 18:58
 */
@Component
@ServerEndpoint("/ws/sp/{md5}") // WebSocket 连接端点
public class WebSocketSplitFrame {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    // 存储所有用户的 WebSocket 连接
    private static final Map<String, Session> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("md5") String md5) {
        clients.put(md5, session);
        logger.info("当前拆帧连接视频数量:{}", clients.size());
    }

    /**
     * 接收消息
     *
     * @param md5AndNum 9b60f7c6ef241ceb7076f8f241c62a22:1200
     */
    @OnMessage
    public int onMessage(String md5AndNum) throws InterruptedException {
        String[] split = md5AndNum.split(":", 2);
        String md5 = split[0];//拆帧视频的MD5值
        Integer num = Integer.valueOf(split[1]);//视频的总帧数
        File sfUiFile = FileUtil.getSfUiFile();
        File splitFrameFile = new File(sfUiFile.getPath() + File.separator + md5);
        int length = 0;
        while (num != length) {
            length = splitFrameFile.listFiles().length;
            Thread.sleep(400);
            sendFrameNum(md5, length);//推送当前拆帧的图片数量
        }
        logger.info("素材已拆帧数完毕 md5:{} num:{}", md5, length);
        return length;
    }


    /**
     * 发送视频帧数
     *
     * @param md5 拆帧视频的MD5值
     * @param num 拆帧数量
     */
    public void sendFrameNum(String md5, int num) {
        Session session = clients.get(md5);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(num + "");
            } catch (IOException e) {
                logger.error("sendFrameNum e:{}", e.getMessage());
            }
        } else {
            logger.info("[sendFrameNum]视频拆帧已完毕:{}", md5);
        }
    }

    @OnClose
    public void onClose(@PathParam("md5") String md5) {
        Session session = clients.get(md5);
        StreamClose.close(session);
        clients.remove(md5);
        logger.info("[onClose]视频拆帧已完毕断开连接:{}", md5);
    }
    
}

在这里插入图片描述

在这里插入图片描述

WebSocket图片推送

/**
 * 请求连接路径 ws://127.0.0.1:4000/ws/fp/677b4046371de933500ae72bc03bf70b
 *
 * @author zym
 */
@Component
@ServerEndpoint("/ws/fp/{md5}") // WebSocket 连接端点
public class WebSocketFramePic {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    // 存储所有用户的 WebSocket 连接
    private final Map<String, Session> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("md5") String md5) {
        clients.put(md5, session);
        logger.info("获取拆帧图连接数量:{}", clients.size());
    }

    /**
     * 接收消息,消息为MD5值
     *
     * @param md5 9b60f7c6ef241ceb7076f8f241c62a22
     */
    @OnMessage
    public int onMessage(String md5) throws InterruptedException {
        File splitFrameFile = new File(FileUtil.getSfUiFile().getPath() + File.separator + md5);
        //获取视频拆帧后的图片文件夹,根据图片名称进行排序
        LinkedList<File> mergePicFiles = Arrays.stream(splitFrameFile.listFiles())
                .sorted(Comparator.comparingInt(x -> Integer.parseInt(x.getName().substring(0, x.getName().lastIndexOf(".")))))
                .collect(Collectors.toCollection(LinkedList::new));
        List<String> pics = new ArrayList<>();
        for (File mergePicFile : mergePicFiles) {
            byte[] bytes = FileUtil.getFileBytes(mergePicFile);
            String base64str = Base64.encodeBase64String(bytes);
            String picBase64 = "data:image/jpeg;base64," + base64str;
            pics.add(picBase64);
            if (pics.size() == 30) {//单次传输图片最多30张
                Thread.sleep(1000);
                sendFramePic(md5, pics);//推送图片
                pics = new ArrayList<>();
            }
        }
        logger.info("获取素材已拆帧图片 md5:{} num:{}", md5, mergePicFiles.size());
        return mergePicFiles.size();
    }


    /**
     * 发送视频帧片
     *
     * @param md5  拆帧视频的MD5值
     * @param pics 图片
     */
    public void sendFramePic(String md5, List<String> pics) {
        Session session = clients.get(md5);
        if (session != null) {
            try {
                String text = JSONArray.toJSONString(pics);
                session.getBasicRemote().sendText(text);
            } catch (Exception e) {
                logger.error("sendFramePic e:{}", e.getMessage());
            }
        } else {
            logger.info("[sendFrameNum]视频拆帧已完毕:{}", md5);
        }
    }

    @OnClose
    public void onClose(@PathParam("md5") String md5) {
        Session session = clients.get(md5);
        StreamClose.close(session);
        clients.remove(md5);
        logger.info("[onClose]拆帧图片推送已完毕断开连接:{}", md5);
    }
    
}

在这里插入图片描述