/* package com.ruoyi.business.aidetection.config; */ /** * @Author:yuankun * @Package:com.ruoyi.business.aidetection.config * @Project:ruoyi-vue-service * @name:ZLMediaKit * @Date:2024/4/7 21:29 * @Filename:ZLMediaKit *//* import java.io.DataInput; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; @Component @Data @Slf4j @DependsOn("readConfig") public class ZLMediaKit { @Autowired private ReadConfig config; private String defaultPushStreamApp = "analyzer"; private int timeout = 1; private boolean mediaServerState = false; public ZLMediaKit(ReadConfig config) { this.config = config; } private String byteFormat(double bytes) { double factor = 1024; for (String unit : new String[]{"", "K", "M", "G"}) { if (bytes < factor) { return String.format("%.2f%sbps", bytes, unit); } bytes /= factor; } return ""; } public String getHlsUrl(String app, String name) { return String.format("%s/%s/%s.hls.m3u8", config.getMediaHttpHost(), app, name); } public String getFlvUrl(String app, String name) { return String.format("%s/%s/%s.live.flv", config.getMediaHttpHost(), app, name); } public String getRtspUrl(String app, String name) { return String.format("%s/%s/%s", config.getMediaRtspHost(), app, name); } public String addStreamProxy(String app, String name, String originUrl, String vhost) { String key = null; try { String url = String.format("%s/index/api/addStreamProxy?secret=%s&vhost=%s&app=%s&stream=%s&url=%s", config.getMediaHttpHost(), config.getMediaSecret(), vhost, app, name, originUrl); OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String responseBody = response.body().string(); int code = Integer.parseInt(responseBody); if (code == 0) { key = responseBody; } } mediaServerState = true; } catch (Exception e) { mediaServerState = false; System.out.printf("%s.%s() error: %s%n", this.getClass().getSimpleName(), Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage()); } return key; } public boolean delStreamProxy(String key) { boolean flag = false; try { String url = String.format("%s/index/api/delStreamProxy?secret=%s&key=%s", config.getMediaHttpHost(), config.getMediaSecret(), key); OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); if (response.isSuccessful()) { String responseBody = response.body().string(); int code = Integer.parseInt(responseBody); if (code == 0) { flag = true; } } mediaServerState = true; } catch (Exception e) { mediaServerState = false; System.out.printf("%s.%s() error: %s%n", this.getClass().getSimpleName(), Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage()); } return flag; } public List> getMediaList() { List> data = new ArrayList<>(); Response response = null; String videoStr = "无"; String audioStr = "无"; Integer createStamp= 0; Integer fps = 0; try { String url = String.format("%s/index/api/getMediaList?secret=%s", this.config.getMediaHttpHost(), this.config.getMediaSecret()); Map headers = new HashMap<>(); headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.57"); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(this.timeout, TimeUnit.SECONDS) .build(); Request request = new Request.Builder() .url(url) .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.57") .build(); response = client.newCall(request).execute(); //System.out.printf("getMediaList() error: %s\n", response.body().string()); //System.out.println(response); //System.out.println(response.body().string()); if (response.code() == 200) { Map responseJson = null; try { responseJson = new ObjectMapper().readValue(response.body().string(), Map.class); } catch (IOException e) { e.printStackTrace(); } if ((int)responseJson.get("code") == 0) { List> responseData = (List>)responseJson.get("data"); //System.out.println(responseData); if(responseData != null && responseData.size() > 0) {//无视频流,防止报空指针错误 Map>> dataGroup = new HashMap<>(); // Group data by app and stream for (Map d : responseData) { String app = (String)d.get("app"); createStamp = (Integer) d.get("createStamp"); String name = (String)d.get("stream"); String schema = (String)d.get("schema"); String code = String.format("%s_%s", app, name); if (!dataGroup.containsKey(code)) { dataGroup.put(code, new HashMap<>()); } dataGroup.get(code).put(schema, d); } for (Map.Entry>> entry : dataGroup.entrySet()) { List> schemasClients = new ArrayList<>(); Map d = null; int index = 0; for (Map.Entry> schemaEntry : entry.getValue().entrySet()) { schemasClients.add(new HashMap() {{ put("schema", schemaEntry.getKey()); put("readerCount", schemaEntry.getValue().get("readerCount")); }}); if (index == 0) { d = schemaEntry.getValue(); } index++; } if (d != null) { List> tracks = (List>)d.get("tracks"); if (tracks != null) { for (Map track : tracks) { int codecType = (int)track.get("codec_type"); if (codecType == 0) { // Video Double fpsDouble = (Double)track.get("fps"); fps = fpsDouble.intValue(); int height = (int)track.get("height"); int width = (int)track.get("width"); videoStr = String.format("%s/%d/%dx%d", track.get("codec_id_name"), fps, width, height); } else if (codecType == 1) { // Audio int channels = (int)track.get("channels"); int sampleBit = (int)track.get("sample_bit"); int sampleRate = (int)track.get("sample_rate"); audioStr = String.format("%s/%d/%d/%d", track.get("codec_id_name"), channels, sampleRate, sampleBit); } } } String produceSpeed = this.byteFormat((int)d.get("bytesSpeed")); String app = (String)d.get("app"); String name = (String)d.get("stream"); String finalVideoStr = videoStr; String finalAudioStr = audioStr; Map finalD = d; Integer finalFps = fps; Integer finalCreateStamp = createStamp; data.add(new HashMap() {{ put("active", true); put("code", entry.getKey()); put("app", app); put("name", name); put("fps", finalFps); put("createStamp", finalCreateStamp); put("produce_speed", produceSpeed); put("video", finalVideoStr); put("audio", finalAudioStr); put("originUrl", finalD.get("originUrl")); put("originType", finalD.get("originType")); put("originTypeStr", finalD.get("originTypeStr")); put("clients", finalD.get("totalReaderCount")); put("schemas_clients", schemasClients); put("flvUrl", getFlvUrl(app, name)); put("hlsUrl", getHlsUrl(app, name)); }}); } } } } } else { log.error("%s error:status: {}", this.getClass().getName(), response.code()); System.out.printf("%s error:status=%d\n", this.getClass().getName(), response.code()); } this.mediaServerState = true; } catch (Exception e) { log.error("Error in getMediaList: {}", e.getMessage(), e); this.mediaServerState = false; } return data; } } */ package com.ruoyi.business.aidetection.config; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.Data; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; @Component @Data @Slf4j @DependsOn("readConfig") public class ZLMediaKit { @Autowired private ReadConfig config; private String defaultPushStreamApp = "analyzer"; private int timeout = 1; private boolean mediaServerState = false; private final OkHttpClient client; public ZLMediaKit() { this.client = new OkHttpClient.Builder() .connectTimeout(timeout, TimeUnit.SECONDS) .build(); } public String getHlsUrl(String app, String name) { return String.format("%s/%s/%s.hls.m3u8", config.getMediaHttpHost(), app, name); } public String getFlvUrl(String app, String name) { return String.format("%s/%s/%s.live.flv", config.getMediaHttpHost(), app, name); } public String getRtspUrl(String app, String name) { return String.format("%s/%s/%s", config.getMediaRtspHost(), app, name); } public String addStreamProxy(String app, String name, String originUrl, String vhost) { String url = String.format( "%s/index/api/addStreamProxy?secret=%s&vhost=%s&app=%s&stream=%s&url=%s", config.getMediaHttpHost(), config.getMediaSecret(), vhost, app, name, originUrl ); String responseBody = sendRequest(url, "addStreamProxy"); if (responseBody != null) { // Assuming a successful response contains a non-zero key return responseBody; } return null; } public boolean delStreamProxy(String key) { String url = String.format( "%s/index/api/delStreamProxy?secret=%s&key=%s", config.getMediaHttpHost(), config.getMediaSecret(), key ); String responseBody = sendRequest(url, "delStreamProxy"); return responseBody != null && "0".equals(responseBody.trim()); } public List> getMediaList() { List> data = new ArrayList<>(); String url = String.format("%s/index/api/getMediaList?secret=%s", config.getMediaHttpHost(), config.getMediaSecret()); String responseBody = sendRequest(url, "getMediaList"); if (responseBody == null) { return data; // Return empty list if the request failed } try { Map responseJson = new ObjectMapper().readValue(responseBody, Map.class); if ((int) responseJson.get("code") == 0) { List> responseData = (List>) responseJson.get("data"); processMediaList(responseData, data); } } catch (Exception e) { log.error("Error parsing JSON in getMediaList: {}", e.getMessage(), e); } return data; } private void processMediaList(List> responseData, List> data) { if (responseData == null || responseData.isEmpty()) { return; } Map>> dataGroup = new HashMap<>(); // Group data by app and stream for (Map item : responseData) { String app = (String) item.get("app"); String stream = (String) item.get("stream"); String schema = (String) item.get("schema"); String code = String.format("%s_%s", app, stream); dataGroup.computeIfAbsent(code, k -> new HashMap<>()).put(schema, item); } for (Map.Entry>> entry : dataGroup.entrySet()) { Map d = entry.getValue().values().iterator().next(); // Get first item in the group if (d != null) { Map mediaInfo = buildMediaInfo(entry.getKey(), d); if (mediaInfo != null) { data.add(mediaInfo); } } } } /** * 将字节数格式化为带单位的字符串。 * * @param bytes 字节数 * @return 格式化后的字符串,如 "1024bps"、"1.00Kbps" 等 */ private String byteFormat(double bytes) { double factor = 1024; for (String unit : new String[]{"", "K", "M", "G"}) { if (bytes < factor) { return String.format("%.2f%sbps", bytes, unit); } bytes /= factor; } return ""; } private Map buildMediaInfo(String code, Map d) { Map mediaInfo = new HashMap<>(); try { String app = (String) d.get("app"); String stream = (String) d.get("stream"); Integer createStamp = (Integer) d.get("createStamp"); String produceSpeed = this.byteFormat((int)d.get("bytesSpeed")); mediaInfo.put("active", true); mediaInfo.put("code", code); mediaInfo.put("app", app); mediaInfo.put("name", stream); mediaInfo.put("createStamp", createStamp); mediaInfo.put("produceSpeed", produceSpeed); mediaInfo.put("video", createStamp); mediaInfo.put("createStamp", createStamp); mediaInfo.put("originUrl", d.get("originUrl")); mediaInfo.put("originType", d.get("originType")); mediaInfo.put("originTypeStr", d.get("originTypeStr")); mediaInfo.put("clients", d.get("totalReaderCount")); //mediaInfo.put("schemas_clients", schemasClients); mediaInfo.put("flvUrl", getFlvUrl(app, stream)); mediaInfo.put("hlsUrl", getHlsUrl(app, stream)); List> tracks = (List>) d.get("tracks"); if (tracks != null) { for (Map track : tracks) { int codecType = (int) track.get("codec_type"); if (codecType == 0) { // Video double fps = (Double) track.get("fps"); // 强制转换为 Double mediaInfo.put("fps", (int) fps); mediaInfo.put("video", formatTrackInfo(track)); } else if (codecType == 1) { // Audio mediaInfo.put("audio", formatTrackInfo(track)); } } } } catch (Exception e) { log.error("Error building media info: {}", e.getMessage(), e); } return mediaInfo; } private String formatTrackInfo(Map track) { try { String codecName = (String) track.get("codec_id_name"); if (track.get("fps") != null) { double fps = (Double) track.get("fps"); // 强制转换为 Double int width = (int)track.get("width"); int height = (int) track.get("height"); return String.format("%s/%d/%dx%d", codecName, (int)fps , width, height); } if (track.get("channels") != null) { return String.format("%s/%d/%d/%d", track.get("codec_id_name"), track.get("channels"), track.get("sample_bit"), track.get("sample_rate")); } return codecName; } catch (Exception e) { log.warn("Error formatting track info: {}", e.getMessage(), e); return "Unknown"; } } private String sendRequest(String url, String action) { mediaServerState = false; // 默认失败 try { Request request = new Request.Builder() .url(url) .addHeader("User-Agent", "Mozilla/5.0") .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { mediaServerState = true; return response.body().string(); } else { log.warn("{} request failed. Status code: {}", action, response.code()); } } } catch (Exception e) { log.error("{} request failed: {}", action, e.getMessage(), e); } return null; } }