PlayController.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package com.genersoft.iot.vmp.vmanager.play;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.genersoft.iot.vmp.common.StreamInfo;
  5. import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.beans.factory.annotation.Value;
  10. import org.springframework.http.HttpStatus;
  11. import org.springframework.http.ResponseEntity;
  12. import org.springframework.web.bind.annotation.CrossOrigin;
  13. import org.springframework.web.bind.annotation.GetMapping;
  14. import org.springframework.web.bind.annotation.PathVariable;
  15. import org.springframework.web.bind.annotation.PostMapping;
  16. import org.springframework.web.bind.annotation.RequestMapping;
  17. import org.springframework.web.bind.annotation.RestController;
  18. import com.alibaba.fastjson.JSONObject;
  19. import com.genersoft.iot.vmp.gb28181.bean.Device;
  20. import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
  21. import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
  22. @CrossOrigin
  23. @RestController
  24. @RequestMapping("/api")
  25. public class PlayController {
  26. private final static Logger logger = LoggerFactory.getLogger(PlayController.class);
  27. @Autowired
  28. private SIPCommander cmder;
  29. @Autowired
  30. private IVideoManagerStorager storager;
  31. @Autowired
  32. private ZLMRESTfulUtils zlmresTfulUtils;
  33. @GetMapping("/play/{deviceId}/{channelId}")
  34. public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){
  35. Device device = storager.queryVideoDevice(deviceId);
  36. StreamInfo streamInfo = storager.queryPlayByDevice(deviceId, channelId);
  37. if (streamInfo == null) {
  38. streamInfo = cmder.playStreamCmd(device, channelId);
  39. }else {
  40. String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
  41. JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
  42. if (rtpInfo.getBoolean("exist")) {
  43. return new ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK);
  44. }else {
  45. storager.stopPlay(streamInfo);
  46. streamInfo = cmder.playStreamCmd(device, channelId);
  47. }
  48. }
  49. String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
  50. // 等待推流, TODO 默认超时30s
  51. boolean lockFlag = true;
  52. long startTime = System.currentTimeMillis();
  53. while (lockFlag) {
  54. try {
  55. if (System.currentTimeMillis() - startTime > 30 * 1000) {
  56. storager.stopPlay(streamInfo);
  57. logger.info("播放等待超时");
  58. return new ResponseEntity<String>("timeout",HttpStatus.OK);
  59. }else {
  60. streamInfo = storager.queryPlayByDevice(deviceId, channelId);
  61. JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
  62. if (rtpInfo != null && rtpInfo.getBoolean("exist") && streamInfo != null && streamInfo.getFlv() != null){
  63. logger.info("RTP已推流,查询编码信息:"+streamInfo.getFlv());
  64. Thread.sleep(2000);
  65. JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId);
  66. if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) {
  67. lockFlag = false;
  68. logger.info("媒体编码信息已获取");
  69. JSONArray tracks = mediaInfo.getJSONArray("tracks");
  70. streamInfo.setTracks(tracks);
  71. storager.startPlay(streamInfo);
  72. }else {
  73. logger.info("媒体编码信息未获取,2秒后重试...");
  74. }
  75. }else {
  76. Thread.sleep(2000);
  77. continue;
  78. };
  79. }
  80. } catch (InterruptedException e) {
  81. e.printStackTrace();
  82. }
  83. }
  84. if (logger.isDebugEnabled()) {
  85. logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId));
  86. logger.debug("设备预览 API调用,ssrc:"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())));
  87. }
  88. if(streamInfo!=null) {
  89. return new ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK);
  90. } else {
  91. logger.warn("设备预览API调用失败!");
  92. return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
  93. }
  94. }
  95. @PostMapping("/play/{ssrc}/stop")
  96. public ResponseEntity<String> playStop(@PathVariable String ssrc){
  97. cmder.streamByeCmd(ssrc);
  98. StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
  99. if (streamInfo == null) return new ResponseEntity<String>(HttpStatus.PAYMENT_REQUIRED);
  100. storager.stopPlay(streamInfo);
  101. if (logger.isDebugEnabled()) {
  102. logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc));
  103. }
  104. if(ssrc!=null) {
  105. JSONObject json = new JSONObject();
  106. json.put("ssrc", ssrc);
  107. return new ResponseEntity<String>(json.toString(),HttpStatus.OK);
  108. } else {
  109. logger.warn("设备预览停止API调用失败!");
  110. return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
  111. }
  112. }
  113. }