ApiStreamController.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package com.genersoft.iot.vmp.web;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.genersoft.iot.vmp.common.StreamInfo;
  6. import com.genersoft.iot.vmp.gb28181.bean.Device;
  7. import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
  8. import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  9. import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  10. import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  11. import com.genersoft.iot.vmp.vmanager.play.PlayController;
  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.beans.factory.annotation.Value;
  16. import org.springframework.http.HttpStatus;
  17. import org.springframework.http.ResponseEntity;
  18. import org.springframework.web.bind.annotation.*;
  19. /**
  20. * 兼容LiveGBS的API:实时直播
  21. */
  22. @CrossOrigin
  23. @RestController
  24. @RequestMapping(value = "/api/v1/stream")
  25. public class ApiStreamController {
  26. private final static Logger logger = LoggerFactory.getLogger(ApiStreamController.class);
  27. @Autowired
  28. private SIPCommander cmder;
  29. @Autowired
  30. private IVideoManagerStorager storager;
  31. private boolean closeWaitRTPInfo = false;
  32. @Autowired
  33. private ZLMRESTfulUtils zlmresTfulUtils;
  34. /**
  35. * 实时直播 - 开始直播
  36. * @param serial 设备编号
  37. * @param channel 通道序号 默认值: 1
  38. * @param code 通道编号,通过 /api/v1/device/channellist 获取的 ChannelList.ID, 该参数和 channel 二选一传递即可
  39. * @param cdn TODO 转推 CDN 地址, 形如: [rtmp|rtsp]://xxx, encodeURIComponent
  40. * @param audio TODO 是否开启音频, 默认 开启
  41. * @param transport 流传输模式, 默认 UDP
  42. * @param checkchannelstatus TODO 是否检查通道状态, 默认 false, 表示 拉流前不检查通道状态是否在线
  43. * @param transportmode TODO 当 transport=TCP 时有效, 指示流传输主被动模式, 默认被动
  44. * @param timeout TODO 拉流超时(秒),
  45. * @return
  46. */
  47. @RequestMapping(value = "/start")
  48. private JSONObject start(String serial ,
  49. @RequestParam(required = false)Integer channel ,
  50. @RequestParam(required = false)String code,
  51. @RequestParam(required = false)String cdn,
  52. @RequestParam(required = false)String audio,
  53. @RequestParam(required = false)String transport,
  54. @RequestParam(required = false)String checkchannelstatus ,
  55. @RequestParam(required = false)String transportmode,
  56. @RequestParam(required = false)String timeout
  57. ){
  58. int getEncoding = closeWaitRTPInfo? 1: 0;
  59. Device device = storager.queryVideoDevice(serial);
  60. if (device == null ) {
  61. JSONObject result = new JSONObject();
  62. result.put("error","device[ " + serial + " ]未找到");
  63. return result;
  64. }else if (device.getOnline() == 0) {
  65. JSONObject result = new JSONObject();
  66. result.put("error","device[ " + code + " ]offline");
  67. return result;
  68. }
  69. DeviceChannel deviceChannel = storager.queryChannel(serial, code);
  70. if (deviceChannel == null) {
  71. JSONObject result = new JSONObject();
  72. result.put("error","channel[ " + code + " ]未找到");
  73. return result;
  74. }else if (deviceChannel.getStatus() == 0) {
  75. JSONObject result = new JSONObject();
  76. result.put("error","channel[ " + code + " ]offline");
  77. return result;
  78. }
  79. // 查询是否已经在播放
  80. StreamInfo streamInfo = storager.queryPlayByDevice(device.getDeviceId(), code);
  81. if (streamInfo == null) {
  82. logger.debug("streamInfo 等于null, 重新点播");
  83. // streamInfo = cmder.playStreamCmd(device, code);
  84. }else {
  85. logger.debug("streamInfo 不等于null, 向流媒体查询是否正在推流");
  86. String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
  87. JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
  88. if (rtpInfo.getBoolean("exist")) {
  89. logger.debug("向流媒体查询正在推流, 直接返回: " + streamInfo.getRtsp());
  90. JSONObject result = new JSONObject();
  91. result.put("StreamID", streamInfo.getSsrc());
  92. result.put("DeviceID", device.getDeviceId());
  93. result.put("ChannelID", code);
  94. result.put("ChannelName", deviceChannel.getName());
  95. result.put("ChannelCustomName", "");
  96. result.put("FLV", streamInfo.getFlv());
  97. result.put("WS_FLV", streamInfo.getWs_flv());
  98. result.put("RTMP", streamInfo.getRtmp());
  99. result.put("HLS", streamInfo.getHls());
  100. result.put("RTSP", streamInfo.getRtsp());
  101. result.put("CDN", "");
  102. result.put("SnapURL", "");
  103. result.put("Transport", device.getTransport());
  104. result.put("StartAt", "");
  105. result.put("Duration", "");
  106. result.put("SourceVideoCodecName", "");
  107. result.put("SourceVideoWidth", "");
  108. result.put("SourceVideoHeight", "");
  109. result.put("SourceVideoFrameRate", "");
  110. result.put("SourceAudioCodecName", "");
  111. result.put("SourceAudioSampleRate", "");
  112. result.put("AudioEnable", "");
  113. result.put("Ondemand", "");
  114. result.put("InBytes", "");
  115. result.put("InBitRate", "");
  116. result.put("OutBytes", "");
  117. result.put("NumOutputs", "");
  118. result.put("CascadeSize", "");
  119. result.put("RelaySize", "");
  120. result.put("ChannelPTZType", 0);
  121. return result;
  122. } else {
  123. logger.debug("向流媒体查询没有推流, 重新点播");
  124. storager.stopPlay(streamInfo);
  125. // streamInfo = cmder.playStreamCmd(device, code);
  126. }
  127. }
  128. if (logger.isDebugEnabled()) {
  129. logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",serial, code));
  130. logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())));
  131. }
  132. boolean lockFlag = true;
  133. long startTime = System.currentTimeMillis();
  134. while (lockFlag) {
  135. try {
  136. if (System.currentTimeMillis() - startTime > 10 * 1000) {
  137. storager.stopPlay(streamInfo);
  138. logger.info("播放等待超时");
  139. JSONObject result = new JSONObject();
  140. result.put("error","timeout");
  141. return result;
  142. } else {
  143. StreamInfo streamInfoNow = storager.queryPlayByDevice(serial, code);
  144. logger.debug("正在向流媒体查询");
  145. if (streamInfoNow != null && streamInfoNow.getFlv() != null) {
  146. streamInfo = streamInfoNow;
  147. logger.debug("向流媒体查询到: " + streamInfoNow.getRtsp());
  148. lockFlag = false;
  149. continue;
  150. } else {
  151. Thread.sleep(2000);
  152. continue;
  153. }
  154. }
  155. } catch (InterruptedException e) {
  156. e.printStackTrace();
  157. }
  158. }
  159. if(streamInfo!=null) {
  160. JSONObject result = new JSONObject();
  161. result.put("StreamID", streamInfo.getSsrc());
  162. result.put("DeviceID", device.getDeviceId());
  163. result.put("ChannelID", code);
  164. result.put("ChannelName", deviceChannel.getName());
  165. result.put("ChannelCustomName", "");
  166. result.put("FLV", streamInfo.getFlv());
  167. result.put("WS_FLV", streamInfo.getWs_flv());
  168. result.put("RTMP", streamInfo.getRtmp());
  169. result.put("HLS", streamInfo.getHls());
  170. result.put("RTSP", streamInfo.getRtsp());
  171. result.put("CDN", "");
  172. result.put("SnapURL", "");
  173. result.put("Transport", device.getTransport());
  174. result.put("StartAt", "");
  175. result.put("Duration", "");
  176. result.put("SourceVideoCodecName", "");
  177. result.put("SourceVideoWidth", "");
  178. result.put("SourceVideoHeight", "");
  179. result.put("SourceVideoFrameRate", "");
  180. result.put("SourceAudioCodecName", "");
  181. result.put("SourceAudioSampleRate", "");
  182. result.put("AudioEnable", "");
  183. result.put("Ondemand", "");
  184. result.put("InBytes", "");
  185. result.put("InBitRate", "");
  186. result.put("OutBytes", "");
  187. result.put("NumOutputs", "");
  188. result.put("CascadeSize", "");
  189. result.put("RelaySize", "");
  190. result.put("ChannelPTZType", 0);
  191. return result;
  192. } else {
  193. logger.warn("设备预览API调用失败!");
  194. JSONObject result = new JSONObject();
  195. result.put("error","调用失败");
  196. return result;
  197. }
  198. }
  199. /**
  200. * 实时直播 - 直播流停止
  201. * @param serial 设备编号
  202. * @param channel 通道序号
  203. * @param code 通道国标编号
  204. * @param check_outputs
  205. * @return
  206. */
  207. @RequestMapping(value = "/stop")
  208. @ResponseBody
  209. private JSONObject stop(String serial ,
  210. @RequestParam(required = false)Integer channel ,
  211. @RequestParam(required = false)String code,
  212. @RequestParam(required = false)String check_outputs
  213. ){
  214. StreamInfo streamInfo = storager.queryPlayByDevice(serial, code);
  215. if (streamInfo == null) {
  216. JSONObject result = new JSONObject();
  217. result.put("error","未找到流信息");
  218. return result;
  219. }
  220. cmder.streamByeCmd(streamInfo.getSsrc());
  221. storager.stopPlay(streamInfo);
  222. return null;
  223. }
  224. /**
  225. * 实时直播 - 直播流保活
  226. * @param serial 设备编号
  227. * @param channel 通道序号
  228. * @param code 通道国标编号
  229. * @return
  230. */
  231. @RequestMapping(value = "/touch")
  232. @ResponseBody
  233. private JSONObject touch(String serial ,String t,
  234. @RequestParam(required = false)Integer channel ,
  235. @RequestParam(required = false)String code,
  236. @RequestParam(required = false)String autorestart,
  237. @RequestParam(required = false)String audio,
  238. @RequestParam(required = false)String cdn
  239. ){
  240. return null;
  241. }
  242. }