ZLMMediaNodeServerService.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. package com.genersoft.iot.vmp.media.zlm;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONArray;
  4. import com.alibaba.fastjson2.JSONObject;
  5. import com.genersoft.iot.vmp.common.CommonCallback;
  6. import com.genersoft.iot.vmp.common.StreamInfo;
  7. import com.genersoft.iot.vmp.conf.exception.ControllerException;
  8. import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  9. import com.genersoft.iot.vmp.media.bean.MediaInfo;
  10. import com.genersoft.iot.vmp.media.bean.MediaServer;
  11. import com.genersoft.iot.vmp.media.service.IMediaNodeServerService;
  12. import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig;
  13. import com.genersoft.iot.vmp.streamProxy.bean.StreamProxy;
  14. import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
  15. import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
  16. import lombok.extern.slf4j.Slf4j;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Service;
  19. import org.springframework.util.ObjectUtils;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. @Slf4j
  25. @Service("zlm")
  26. public class ZLMMediaNodeServerService implements IMediaNodeServerService {
  27. @Autowired
  28. private ZLMRESTfulUtils zlmresTfulUtils;
  29. @Autowired
  30. private ZLMServerFactory zlmServerFactory;
  31. @Override
  32. public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) {
  33. return zlmServerFactory.createRTPServer(mediaServer, streamId, ssrc, port, onlyAuto, reUsePort, tcpMode);
  34. }
  35. @Override
  36. public void closeRtpServer(MediaServer mediaServer, String streamId) {
  37. zlmServerFactory.closeRtpServer(mediaServer, streamId);
  38. }
  39. @Override
  40. public void closeRtpServer(MediaServer mediaServer, String streamId, CommonCallback<Boolean> callback) {
  41. zlmServerFactory.closeRtpServer(mediaServer, streamId, callback);
  42. }
  43. @Override
  44. public void closeStreams(MediaServer mediaServer, String app, String stream) {
  45. zlmresTfulUtils.closeStreams(mediaServer, app, stream);
  46. }
  47. @Override
  48. public Boolean updateRtpServerSSRC(MediaServer mediaServer, String streamId, String ssrc) {
  49. return zlmServerFactory.updateRtpServerSSRC(mediaServer, streamId, ssrc);
  50. }
  51. @Override
  52. public boolean checkNodeId(MediaServer mediaServer) {
  53. if (mediaServer == null) {
  54. return false;
  55. }
  56. JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer);
  57. if (responseJSON != null) {
  58. JSONArray data = responseJSON.getJSONArray("data");
  59. if (data != null && !data.isEmpty()) {
  60. ZLMServerConfig zlmServerConfig= JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
  61. return zlmServerConfig.getGeneralMediaServerId().equals(mediaServer.getId());
  62. }else {
  63. return false;
  64. }
  65. }else {
  66. return false;
  67. }
  68. }
  69. @Override
  70. public void online(MediaServer mediaServer) {
  71. }
  72. @Override
  73. public MediaServer checkMediaServer(String ip, int port, String secret) {
  74. MediaServer mediaServer = new MediaServer();
  75. mediaServer.setIp(ip);
  76. mediaServer.setHttpPort(port);
  77. mediaServer.setFlvPort(port);
  78. mediaServer.setWsFlvPort(port);
  79. mediaServer.setSecret(secret);
  80. JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig(mediaServer);
  81. if (responseJSON == null) {
  82. throw new ControllerException(ErrorCode.ERROR100.getCode(), "连接失败");
  83. }
  84. JSONArray data = responseJSON.getJSONArray("data");
  85. if (data == null) {
  86. throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败");
  87. }
  88. ZLMServerConfig zlmServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), ZLMServerConfig.class);
  89. if (zlmServerConfig == null) {
  90. throw new ControllerException(ErrorCode.ERROR100.getCode(), "读取配置失败");
  91. }
  92. mediaServer.setId(zlmServerConfig.getGeneralMediaServerId());
  93. mediaServer.setHttpSSlPort(zlmServerConfig.getHttpPort());
  94. mediaServer.setFlvSSLPort(zlmServerConfig.getHttpPort());
  95. mediaServer.setWsFlvSSLPort(zlmServerConfig.getHttpPort());
  96. mediaServer.setRtmpPort(zlmServerConfig.getRtmpPort());
  97. mediaServer.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort());
  98. mediaServer.setRtspPort(zlmServerConfig.getRtspPort());
  99. mediaServer.setRtspSSLPort(zlmServerConfig.getRtspSSlport());
  100. mediaServer.setRtpProxyPort(zlmServerConfig.getRtpProxyPort());
  101. mediaServer.setStreamIp(ip);
  102. mediaServer.setHookIp("127.0.0.1");
  103. mediaServer.setSdpIp(ip);
  104. mediaServer.setType("zlm");
  105. return mediaServer;
  106. }
  107. @Override
  108. public boolean stopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) {
  109. Map<String, Object> param = new HashMap<>();
  110. param.put("vhost", "__defaultVhost__");
  111. param.put("app", app);
  112. param.put("stream", stream);
  113. if (!ObjectUtils.isEmpty(ssrc)) {
  114. param.put("ssrc", ssrc);
  115. }
  116. JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaInfo, param);
  117. if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
  118. log.error("停止发流失败: {}, 参数:{}", jsonObject.getString("msg"), JSON.toJSONString(param));
  119. throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
  120. }
  121. return true;
  122. }
  123. @Override
  124. public boolean initStopSendRtp(MediaServer mediaInfo, String app, String stream, String ssrc) {
  125. Map<String, Object> param = new HashMap<>();
  126. param.put("vhost", "__defaultVhost__");
  127. param.put("app", app);
  128. param.put("stream", stream);
  129. if (!ObjectUtils.isEmpty(ssrc)) {
  130. param.put("ssrc", ssrc);
  131. }
  132. JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(mediaInfo, param);
  133. if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
  134. log.error("停止发流失败: {}, 参数:{}", jsonObject.getString("msg"), JSON.toJSONString(param));
  135. return false;
  136. }
  137. return true;
  138. }
  139. @Override
  140. public boolean deleteRecordDirectory(MediaServer mediaServer, String app, String stream, String date, String fileName) {
  141. log.info("[zlm-deleteRecordDirectory] 删除磁盘文件, server: {} {}:{}->{}/{}", mediaServer.getId(), app, stream, date, fileName);
  142. JSONObject jsonObject = zlmresTfulUtils.deleteRecordDirectory(mediaServer, app,
  143. stream, date, fileName);
  144. if (jsonObject.getInteger("code") == 0) {
  145. return true;
  146. }else {
  147. log.info("[zlm-deleteRecordDirectory] 删除磁盘文件错误, server: {} {}:{}->{}/{}, 结果: {}", mediaServer.getId(), app, stream, date, fileName, jsonObject);
  148. return false;
  149. }
  150. }
  151. @Override
  152. public List<StreamInfo> getMediaList(MediaServer mediaServer, String app, String stream, String callId) {
  153. List<StreamInfo> streamInfoList = new ArrayList<>();
  154. JSONObject mediaList = zlmresTfulUtils.getMediaList(mediaServer, app, stream);
  155. if (mediaList != null) {
  156. if (mediaList.getInteger("code") == 0) {
  157. JSONArray data = mediaList.getJSONArray("data");
  158. if (data == null) {
  159. return null;
  160. }
  161. JSONObject mediaJSON = data.getJSONObject(0);
  162. MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer);
  163. StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true);
  164. if (streamInfo != null) {
  165. streamInfoList.add(streamInfo);
  166. }
  167. }
  168. }
  169. return streamInfoList;
  170. }
  171. public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) {
  172. StreamInfo streamInfoResult = new StreamInfo();
  173. streamInfoResult.setStream(stream);
  174. streamInfoResult.setApp(app);
  175. String addr = mediaServer.getStreamIp();
  176. streamInfoResult.setIp(addr);
  177. streamInfoResult.setMediaServerId(mediaServer.getId());
  178. String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId;
  179. streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam);
  180. streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam);
  181. String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam);
  182. streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile);
  183. streamInfoResult.setWsFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile);
  184. streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
  185. streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
  186. streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam);
  187. streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay);
  188. streamInfoResult.setMediaInfo(mediaInfo);
  189. streamInfoResult.setOriginType(mediaInfo.getOriginType());
  190. return streamInfoResult;
  191. }
  192. @Override
  193. public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) {
  194. JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServer, address, port, stream);
  195. log.info("[TCP主动连接对方] 结果: {}", jsonObject);
  196. return jsonObject.getInteger("code") == 0;
  197. }
  198. @Override
  199. public void getSnap(MediaServer mediaServer, String streamUrl, int timeoutSec, int expireSec, String path, String fileName) {
  200. zlmresTfulUtils.getSnap(mediaServer, streamUrl, timeoutSec, expireSec, path, fileName);
  201. }
  202. @Override
  203. public MediaInfo getMediaInfo(MediaServer mediaServer, String app, String stream) {
  204. JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServer, app, "rtsp", stream);
  205. if (jsonObject.getInteger("code") != 0) {
  206. return null;
  207. }
  208. return MediaInfo.getInstance(jsonObject, mediaServer);
  209. }
  210. @Override
  211. public Boolean pauseRtpCheck(MediaServer mediaServer, String streamKey) {
  212. JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServer, streamKey);
  213. return jsonObject.getInteger("code") == 0;
  214. }
  215. @Override
  216. public Boolean resumeRtpCheck(MediaServer mediaServer, String streamKey) {
  217. JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServer, streamKey);
  218. return jsonObject.getInteger("code") == 0;
  219. }
  220. @Override
  221. public String getFfmpegCmd(MediaServer mediaServer, String cmdKey) {
  222. JSONObject jsonObject = zlmresTfulUtils.getMediaServerConfig(mediaServer);
  223. if (jsonObject.getInteger("code") != 0) {
  224. log.warn("[getFfmpegCmd] 获取流媒体配置失败");
  225. throw new ControllerException(ErrorCode.ERROR100.getCode(), "获取流媒体配置失败");
  226. }
  227. JSONArray dataArray = jsonObject.getJSONArray("data");
  228. JSONObject mediaServerConfig = dataArray.getJSONObject(0);
  229. if (ObjectUtils.isEmpty(cmdKey)) {
  230. cmdKey = "ffmpeg.cmd";
  231. }
  232. return mediaServerConfig.getString(cmdKey);
  233. }
  234. @Override
  235. public WVPResult<String> addFFmpegSource(MediaServer mediaServer, String srcUrl, String dstUrl, int timeoutMs, boolean enableAudio, boolean enableMp4, String ffmpegCmdKey) {
  236. JSONObject jsonObject = zlmresTfulUtils.addFFmpegSource(mediaServer, srcUrl, dstUrl, timeoutMs, enableAudio, enableMp4, ffmpegCmdKey);
  237. if (jsonObject.getInteger("code") != 0) {
  238. log.warn("[getFfmpegCmd] 添加FFMPEG代理失败");
  239. return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加FFMPEG代理失败");
  240. }else {
  241. JSONObject data = jsonObject.getJSONObject("data");
  242. if (data == null) {
  243. return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject);
  244. }else {
  245. return WVPResult.success(data.getString("key"));
  246. }
  247. }
  248. }
  249. @Override
  250. public WVPResult<String> addStreamProxy(MediaServer mediaServer, String app, String stream, String url,
  251. boolean enableAudio, boolean enableMp4, String rtpType, Integer timeout) {
  252. JSONObject jsonObject = zlmresTfulUtils.addStreamProxy(mediaServer, app, stream, url, enableAudio, enableMp4, rtpType, timeout);
  253. if (jsonObject.getInteger("code") != 0) {
  254. return WVPResult.fail(ErrorCode.ERROR100.getCode(), "添加代理失败");
  255. }else {
  256. JSONObject data = jsonObject.getJSONObject("data");
  257. if (data == null) {
  258. return WVPResult.fail(ErrorCode.ERROR100.getCode(), "代理结果异常: " + jsonObject);
  259. }else {
  260. return WVPResult.success(data.getString("key"));
  261. }
  262. }
  263. }
  264. @Override
  265. public Boolean delFFmpegSource(MediaServer mediaServer, String streamKey) {
  266. JSONObject jsonObject = zlmresTfulUtils.delFFmpegSource(mediaServer, streamKey);
  267. return jsonObject.getInteger("code") == 0;
  268. }
  269. @Override
  270. public Boolean delStreamProxy(MediaServer mediaServer, String streamKey) {
  271. JSONObject jsonObject = zlmresTfulUtils.delStreamProxy(mediaServer, streamKey);
  272. return jsonObject.getInteger("code") == 0;
  273. }
  274. @Override
  275. public Map<String, String> getFFmpegCMDs(MediaServer mediaServer) {
  276. Map<String, String> result = new HashMap<>();
  277. JSONObject mediaServerConfigResuly = zlmresTfulUtils.getMediaServerConfig(mediaServer);
  278. if (mediaServerConfigResuly != null && mediaServerConfigResuly.getInteger("code") == 0
  279. && mediaServerConfigResuly.getJSONArray("data").size() > 0){
  280. JSONObject mediaServerConfig = mediaServerConfigResuly.getJSONArray("data").getJSONObject(0);
  281. for (String key : mediaServerConfig.keySet()) {
  282. if (key.startsWith("ffmpeg.cmd")){
  283. result.put(key, mediaServerConfig.getString(key));
  284. }
  285. }
  286. }
  287. return result;
  288. }
  289. @Override
  290. public void startSendRtpPassive(MediaServer mediaServer, SendRtpItem sendRtpItem, Integer timeout) {
  291. Map<String, Object> param = new HashMap<>(12);
  292. param.put("vhost","__defaultVhost__");
  293. param.put("app", sendRtpItem.getApp());
  294. param.put("stream", sendRtpItem.getStream());
  295. param.put("ssrc", sendRtpItem.getSsrc());
  296. param.put("src_port", sendRtpItem.getLocalPort());
  297. param.put("pt", sendRtpItem.getPt());
  298. param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  299. param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  300. param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
  301. param.put("recv_stream_id", sendRtpItem.getReceiveStream());
  302. if (timeout != null) {
  303. param.put("close_delay_ms", timeout);
  304. }
  305. if (!sendRtpItem.isTcp()) {
  306. // 开启rtcp保活
  307. param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");
  308. }
  309. if (!sendRtpItem.isTcpActive()) {
  310. param.put("dst_url",sendRtpItem.getIp());
  311. param.put("dst_port", sendRtpItem.getPort());
  312. }
  313. JSONObject jsonObject = zlmServerFactory.startSendRtpPassive(mediaServer, param, null);
  314. if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
  315. log.error("启动监听TCP被动推流失败: {}, 参数:{}", jsonObject.getString("msg"), JSON.toJSONString(param));
  316. throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
  317. }
  318. log.info("调用ZLM-TCP被动推流接口, 结果: {}", jsonObject);
  319. log.info("启动监听TCP被动推流成功[ {}/{} ],{}->{}:{}, " , sendRtpItem.getApp(), sendRtpItem.getStream(),
  320. jsonObject.getString("local_port"), param.get("dst_url"), param.get("dst_port"));
  321. }
  322. @Override
  323. public void startSendRtpStream(MediaServer mediaServer, SendRtpItem sendRtpItem) {
  324. Map<String, Object> param = new HashMap<>(12);
  325. param.put("vhost", "__defaultVhost__");
  326. param.put("app", sendRtpItem.getApp());
  327. param.put("stream", sendRtpItem.getStream());
  328. param.put("ssrc", sendRtpItem.getSsrc());
  329. param.put("src_port", sendRtpItem.getLocalPort());
  330. param.put("pt", sendRtpItem.getPt());
  331. param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  332. param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  333. param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
  334. if (!sendRtpItem.isTcp()) {
  335. // udp模式下开启rtcp保活
  336. param.put("udp_rtcp_timeout", sendRtpItem.isRtcp() ? "1" : "0");
  337. }
  338. param.put("dst_url", sendRtpItem.getIp());
  339. param.put("dst_port", sendRtpItem.getPort());
  340. JSONObject jsonObject = zlmresTfulUtils.startSendRtp(mediaServer, param);
  341. if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
  342. throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
  343. }
  344. }
  345. @Override
  346. public Long updateDownloadProcess(MediaServer mediaServer, String app, String stream) {
  347. MediaInfo mediaInfo = getMediaInfo(mediaServer, app, stream);
  348. if (mediaInfo == null) {
  349. log.warn("[获取下载进度] 查询进度失败, 节点Id: {}, {}/{}", mediaServer.getId(), app, stream);
  350. return null;
  351. }
  352. return mediaInfo.getDuration();
  353. }
  354. @Override
  355. public StreamInfo startProxy(MediaServer mediaServer, StreamProxy streamProxy) {
  356. String dstUrl;
  357. if ("ffmpeg".equalsIgnoreCase(streamProxy.getType())) {
  358. String ffmpegCmd = getFfmpegCmd(mediaServer, streamProxy.getFfmpegCmdKey());
  359. if (ffmpegCmd == null) {
  360. throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法获取ffmpeg cmd");
  361. }
  362. String schema = getSchemaFromFFmpegCmd(ffmpegCmd);
  363. if (schema == null) {
  364. throw new ControllerException(ErrorCode.ERROR100.getCode(), "ffmpeg拉流代理无法从ffmpeg cmd中获取到输出格式");
  365. }
  366. int port;
  367. String schemaForUri;
  368. if (schema.equalsIgnoreCase("rtsp")) {
  369. port = mediaServer.getRtspPort();
  370. schemaForUri = schema;
  371. }else if (schema.equalsIgnoreCase("flv")) {
  372. port = mediaServer.getRtmpPort();
  373. schemaForUri = schema;
  374. }else {
  375. port = mediaServer.getRtmpPort();
  376. schemaForUri = schema;
  377. }
  378. dstUrl = String.format("%s://%s:%s/%s/%s", schemaForUri, "127.0.0.1", port, streamProxy.getApp(),
  379. streamProxy.getStream());
  380. }else {
  381. dstUrl = String.format("rtsp://%s:%s/%s/%s", "127.0.0.1", mediaServer.getRtspPort(), streamProxy.getApp(),
  382. streamProxy.getStream());
  383. }
  384. MediaInfo mediaInfo = getMediaInfo(mediaServer, streamProxy.getApp(), streamProxy.getStream());
  385. if (mediaInfo != null) {
  386. if (mediaInfo.getOriginUrl().equals(streamProxy.getSrcUrl())) {
  387. log.info("[启动拉流代理] 已存在, 直接返回, app: {}, stream: {}", mediaInfo.getApp(), streamProxy.getStream());
  388. return getStreamInfoByAppAndStream(mediaServer, streamProxy.getApp(), streamProxy.getStream(), null, null, true);
  389. }
  390. closeStreams(mediaServer, streamProxy.getApp(), streamProxy.getStream());
  391. }
  392. JSONObject jsonObject = null;
  393. if ("ffmpeg".equalsIgnoreCase(streamProxy.getType())){
  394. if (streamProxy.getTimeout() == 0) {
  395. streamProxy.setTimeout(15);
  396. }
  397. jsonObject = zlmresTfulUtils.addFFmpegSource(mediaServer, streamProxy.getSrcUrl().trim(), dstUrl,
  398. streamProxy.getTimeout(), streamProxy.isEnableAudio(), streamProxy.isEnableMp4(),
  399. streamProxy.getFfmpegCmdKey());
  400. }else {
  401. jsonObject = zlmresTfulUtils.addStreamProxy(mediaServer, streamProxy.getApp(), streamProxy.getStream(), streamProxy.getSrcUrl().trim(),
  402. streamProxy.isEnableAudio(), streamProxy.isEnableMp4(), streamProxy.getRtspType(), streamProxy.getTimeout());
  403. }
  404. if (jsonObject == null) {
  405. throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败");
  406. }else if (jsonObject.getInteger("code") != 0) {
  407. throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
  408. }else {
  409. JSONObject data = jsonObject.getJSONObject("data");
  410. if (data == null) {
  411. throw new ControllerException(jsonObject.getInteger("code"), "代理结果异常: " + jsonObject);
  412. }else {
  413. streamProxy.setStreamKey(jsonObject.getString("key"));
  414. return getStreamInfoByAppAndStream(mediaServer, streamProxy.getApp(), streamProxy.getStream(), null, null, true);
  415. }
  416. }
  417. }
  418. private String getSchemaFromFFmpegCmd(String ffmpegCmd) {
  419. ffmpegCmd = ffmpegCmd.replaceAll(" + ", " ");
  420. String[] paramArray = ffmpegCmd.split(" ");
  421. if (paramArray.length == 0) {
  422. return null;
  423. }
  424. for (int i = 0; i < paramArray.length; i++) {
  425. if (paramArray[i].equalsIgnoreCase("-f")) {
  426. if (i + 1 < paramArray.length - 1) {
  427. return paramArray[i+1];
  428. }else {
  429. return null;
  430. }
  431. }
  432. }
  433. return null;
  434. }
  435. @Override
  436. public void stopProxy(MediaServer mediaServer, String streamKey) {
  437. JSONObject jsonObject = zlmresTfulUtils.delStreamProxy(mediaServer, streamKey);
  438. if (jsonObject == null) {
  439. throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败");
  440. }else if (jsonObject.getInteger("code") != 0) {
  441. throw new ControllerException(jsonObject.getInteger("code"), jsonObject.getString("msg"));
  442. }
  443. }
  444. }