|
@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.http.HttpStatus; |
|
|
import org.springframework.http.HttpStatus; |
|
|
import org.springframework.http.ResponseEntity; |
|
|
import org.springframework.http.ResponseEntity; |
|
|
import org.springframework.util.StringUtils; |
|
|
import org.springframework.util.StringUtils; |
|
@ -26,29 +27,33 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|
|
@RestController |
|
|
@RestController |
|
|
@RequestMapping("/api") |
|
|
@RequestMapping("/api") |
|
|
public class PlaybackController { |
|
|
public class PlaybackController { |
|
|
|
|
|
|
|
|
private final static Logger logger = LoggerFactory.getLogger(PlaybackController.class); |
|
|
private final static Logger logger = LoggerFactory.getLogger(PlaybackController.class); |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private SIPCommander cmder; |
|
|
private SIPCommander cmder; |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private IVideoManagerStorager storager; |
|
|
private IVideoManagerStorager storager; |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private ZLMRESTfulUtils zlmresTfulUtils; |
|
|
private ZLMRESTfulUtils zlmresTfulUtils; |
|
|
|
|
|
|
|
|
|
|
|
@Value("${media.closeWaitRTPInfo}") |
|
|
|
|
|
private boolean closeWaitRTPInfo; |
|
|
|
|
|
|
|
|
@GetMapping("/playback/{deviceId}/{channelId}") |
|
|
@GetMapping("/playback/{deviceId}/{channelId}") |
|
|
public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId, String startTime, String endTime){ |
|
|
public ResponseEntity<String> play(@PathVariable String deviceId, @PathVariable String channelId, String startTime, |
|
|
|
|
|
String endTime) { |
|
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
if (logger.isDebugEnabled()) { |
|
|
logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s",deviceId, channelId)); |
|
|
logger.debug(String.format("设备回放 API调用,deviceId:%s ,channelId:%s", deviceId, channelId)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(channelId)) { |
|
|
if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(channelId)) { |
|
|
String log = String.format("设备回放 API调用失败,deviceId:%s ,channelId:%s",deviceId, channelId); |
|
|
String log = String.format("设备回放 API调用失败,deviceId:%s ,channelId:%s", deviceId, channelId); |
|
|
logger.warn(log); |
|
|
logger.warn(log); |
|
|
return new ResponseEntity<String>(log,HttpStatus.BAD_REQUEST); |
|
|
return new ResponseEntity<String>(log, HttpStatus.BAD_REQUEST); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Device device = storager.queryVideoDevice(deviceId); |
|
|
Device device = storager.queryVideoDevice(deviceId); |
|
@ -58,20 +63,22 @@ public class PlaybackController { |
|
|
cmder.streamByeCmd(streamInfo.getSsrc()); |
|
|
cmder.streamByeCmd(streamInfo.getSsrc()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// }else {
|
|
|
// }else {
|
|
|
// String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
|
|
|
// String streamId = String.format("%08x",
|
|
|
// JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
|
|
|
// Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
|
|
|
// if (rtpInfo.getBoolean("exist")) {
|
|
|
// JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
|
|
|
// return new ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK);
|
|
|
// if (rtpInfo.getBoolean("exist")) {
|
|
|
// }else {
|
|
|
// return new
|
|
|
// storager.stopPlayback(streamInfo);
|
|
|
// ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK);
|
|
|
// streamInfo = cmder.playbackStreamCmd(device, channelId, startTime, endTime);
|
|
|
// }else {
|
|
|
// }
|
|
|
// storager.stopPlayback(streamInfo);
|
|
|
// }
|
|
|
// streamInfo = cmder.playbackStreamCmd(device, channelId, startTime, endTime);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
streamInfo = cmder.playbackStreamCmd(device, channelId, startTime, endTime); |
|
|
streamInfo = cmder.playbackStreamCmd(device, channelId, startTime, endTime); |
|
|
|
|
|
|
|
|
String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); |
|
|
String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase(); |
|
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
if (logger.isDebugEnabled()) { |
|
|
logger.debug("设备回放 API调用,ssrc:" + streamInfo.getSsrc() + ",ZLMedia streamId:" + streamId); |
|
|
logger.debug("设备回放 API调用,ssrc:" + streamInfo.getSsrc() + ",ZLMedia streamId:" + streamId); |
|
|
} |
|
|
} |
|
@ -81,62 +88,71 @@ public class PlaybackController { |
|
|
long lockStartTime = System.currentTimeMillis(); |
|
|
long lockStartTime = System.currentTimeMillis(); |
|
|
JSONObject rtpInfo = null; |
|
|
JSONObject rtpInfo = null; |
|
|
|
|
|
|
|
|
while (lockFlag) { |
|
|
if (closeWaitRTPInfo) { |
|
|
try { |
|
|
String flv = storager.getMediaInfo().getWanIp() + ":" + storager.getMediaInfo().getHttpPort() + "/rtp/" |
|
|
if (System.currentTimeMillis() - lockStartTime > 75 * 1000) { |
|
|
+ streamId + ".flv"; |
|
|
storager.stopPlayback(streamInfo); |
|
|
streamInfo.setFlv("http://" + flv); |
|
|
logger.info("播放等待超时"); |
|
|
streamInfo.setWs_flv("ws://" + flv); |
|
|
return new ResponseEntity<String>("timeout",HttpStatus.OK); |
|
|
storager.startPlayback(streamInfo); |
|
|
}else { |
|
|
} else { |
|
|
streamInfo = storager.queryPlaybackByDevice(deviceId, channelId); |
|
|
while (lockFlag) { |
|
|
if (!rtpPushed) { |
|
|
try { |
|
|
logger.info("查询RTP推流信息..."); |
|
|
if (System.currentTimeMillis() - lockStartTime > 75 * 1000) { |
|
|
rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); |
|
|
storager.stopPlayback(streamInfo); |
|
|
} |
|
|
logger.info("播放等待超时"); |
|
|
if (rtpInfo != null && rtpInfo.getBoolean("exist") && streamInfo != null && streamInfo.getFlv() != null){ |
|
|
return new ResponseEntity<String>("timeout", HttpStatus.OK); |
|
|
logger.info("查询流编码信息:"+streamInfo.getFlv()); |
|
|
} else { |
|
|
rtpPushed = true; |
|
|
streamInfo = storager.queryPlaybackByDevice(deviceId, channelId); |
|
|
Thread.sleep(2000); |
|
|
if (!rtpPushed) { |
|
|
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId); |
|
|
logger.info("查询RTP推流信息..."); |
|
|
if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) { |
|
|
rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); |
|
|
lockFlag = false; |
|
|
} |
|
|
logger.info("流编码信息已获取"); |
|
|
if (rtpInfo != null && rtpInfo.getBoolean("exist") && streamInfo != null |
|
|
JSONArray tracks = mediaInfo.getJSONArray("tracks"); |
|
|
&& streamInfo.getFlv() != null) { |
|
|
streamInfo.setTracks(tracks); |
|
|
logger.info("查询流编码信息:" + streamInfo.getFlv()); |
|
|
storager.startPlayback(streamInfo); |
|
|
rtpPushed = true; |
|
|
}else { |
|
|
Thread.sleep(2000); |
|
|
logger.info("流编码信息未获取,2秒后重试..."); |
|
|
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId); |
|
|
|
|
|
if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) { |
|
|
|
|
|
lockFlag = false; |
|
|
|
|
|
logger.info("流编码信息已获取"); |
|
|
|
|
|
JSONArray tracks = mediaInfo.getJSONArray("tracks"); |
|
|
|
|
|
streamInfo.setTracks(tracks); |
|
|
|
|
|
storager.startPlayback(streamInfo); |
|
|
|
|
|
} else { |
|
|
|
|
|
logger.info("流编码信息未获取,2秒后重试..."); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
Thread.sleep(2000); |
|
|
|
|
|
continue; |
|
|
} |
|
|
} |
|
|
}else { |
|
|
|
|
|
Thread.sleep(2000); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
} |
|
|
} |
|
|
} catch (InterruptedException e) { |
|
|
|
|
|
e.printStackTrace(); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if(streamInfo!=null) { |
|
|
if (streamInfo != null) { |
|
|
return new ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK); |
|
|
return new ResponseEntity<String>(JSON.toJSONString(streamInfo), HttpStatus.OK); |
|
|
} else { |
|
|
} else { |
|
|
logger.warn("设备回放API调用失败!"); |
|
|
logger.warn("设备回放API调用失败!"); |
|
|
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@RequestMapping("/playback/{ssrc}/stop") |
|
|
@RequestMapping("/playback/{ssrc}/stop") |
|
|
public ResponseEntity<String> playStop(@PathVariable String ssrc){ |
|
|
public ResponseEntity<String> playStop(@PathVariable String ssrc) { |
|
|
|
|
|
|
|
|
cmder.streamByeCmd(ssrc); |
|
|
cmder.streamByeCmd(ssrc); |
|
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
if (logger.isDebugEnabled()) { |
|
|
logger.debug(String.format("设备录像回放停止 API调用,ssrc:%s", ssrc)); |
|
|
logger.debug(String.format("设备录像回放停止 API调用,ssrc:%s", ssrc)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if(ssrc!=null) { |
|
|
if (ssrc != null) { |
|
|
JSONObject json = new JSONObject(); |
|
|
JSONObject json = new JSONObject(); |
|
|
json.put("ssrc", ssrc); |
|
|
json.put("ssrc", ssrc); |
|
|
return new ResponseEntity<String>(json.toString(),HttpStatus.OK); |
|
|
return new ResponseEntity<String>(json.toString(), HttpStatus.OK); |
|
|
} else { |
|
|
} else { |
|
|
logger.warn("设备录像回放停止API调用失败!"); |
|
|
logger.warn("设备录像回放停止API调用失败!"); |
|
|
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
|
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
|
|