Merge remote-tracking branch 'origin/master' into wvp-28181-2.0
# Conflicts: # README.md # src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHTTPProxyController.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java # src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java # src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java # src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java # src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java # src/main/java/com/genersoft/iot/vmp/vmanager/playback/PlaybackController.java # src/main/java/com/genersoft/iot/vmp/vmanager/service/impl/PlayServiceImpl.java # src/main/java/com/genersoft/iot/vmp/web/ApiStreamController.java # src/main/resources/application-dev.yml # web_src/src/components/gb28181/devicePlayer.vue
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
package com.genersoft.iot.vmp.vmanager.device;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.genersoft.iot.vmp.common.PageResult;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
@@ -19,6 +19,8 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
|
||||
import javax.sip.message.Response;
|
||||
|
||||
@CrossOrigin
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
@@ -50,13 +52,13 @@ public class DeviceController {
|
||||
}
|
||||
|
||||
@GetMapping("/devices")
|
||||
public PageResult<Device> devices(int page, int count){
|
||||
public PageInfo<Device> devices(int page, int count){
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("查询所有视频设备API调用");
|
||||
}
|
||||
|
||||
return storager.queryVideoDeviceList(null, page, count);
|
||||
return storager.queryVideoDeviceList(page, count);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,18 +68,33 @@ public class DeviceController {
|
||||
* @param count 每页条数
|
||||
* @return 通道列表
|
||||
*/
|
||||
/**
|
||||
* 分页查询通道数
|
||||
*
|
||||
* @param deviceId 设备id
|
||||
* @param page 当前页
|
||||
* @param count 每页条数
|
||||
* @param query 查询内容
|
||||
* @param online 是否在线 在线 true / 离线 false
|
||||
* @param channelType 设备 false/子目录 true
|
||||
* @return 通道列表
|
||||
*/
|
||||
@GetMapping("/devices/{deviceId}/channels")
|
||||
public ResponseEntity<PageResult> channels(@PathVariable String deviceId,
|
||||
public ResponseEntity<PageInfo> channels(@PathVariable String deviceId,
|
||||
int page, int count,
|
||||
@RequestParam(required = false) String query,
|
||||
@RequestParam(required = false) String online,
|
||||
@RequestParam(required = false) Boolean online,
|
||||
@RequestParam(required = false) Boolean channelType
|
||||
){
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("查询所有视频设备API调用");
|
||||
}
|
||||
PageResult pageResult = storager.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count);
|
||||
if (StringUtils.isEmpty(query)) {
|
||||
query = null;
|
||||
}
|
||||
|
||||
PageInfo pageResult = storager.queryChannelsByDeviceId(deviceId, query, channelType, online, page, count);
|
||||
return new ResponseEntity<>(pageResult,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@@ -86,11 +103,25 @@ public class DeviceController {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
}
|
||||
logger.debug("设备信息同步API调用,deviceId:" + deviceId);
|
||||
logger.debug("设备通道信息同步API调用,deviceId:" + deviceId);
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
cmder.catalogQuery(device);
|
||||
DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>();
|
||||
cmder.catalogQuery(device, event -> {
|
||||
Response response = event.getResponse();
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
|
||||
msg.setData(String.format("同步通道失败,错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
DeferredResult<ResponseEntity<Device>> result = new DeferredResult<ResponseEntity<Device>>(2*1000L);
|
||||
result.onTimeout(()->{
|
||||
logger.warn(String.format("设备通道信息同步超时"));
|
||||
// 释放rtpserver
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId);
|
||||
msg.setData("Timeout");
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_CATALOG+deviceId, result);
|
||||
return result;
|
||||
}
|
||||
@@ -124,7 +155,7 @@ public class DeviceController {
|
||||
* @return 子通道列表
|
||||
*/
|
||||
@GetMapping("/subChannels/{deviceId}/{channelId}/channels")
|
||||
public ResponseEntity<PageResult> subChannels(@PathVariable String deviceId,
|
||||
public ResponseEntity<PageInfo> subChannels(@PathVariable String deviceId,
|
||||
@PathVariable String channelId,
|
||||
int page,
|
||||
int count,
|
||||
@@ -137,23 +168,23 @@ public class DeviceController {
|
||||
}
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId,channelId);
|
||||
if (deviceChannel == null) {
|
||||
PageResult<DeviceChannel> deviceChannelPageResult = new PageResult<>();
|
||||
PageInfo<DeviceChannel> deviceChannelPageResult = new PageInfo<>();
|
||||
return new ResponseEntity<>(deviceChannelPageResult,HttpStatus.OK);
|
||||
}
|
||||
|
||||
PageResult pageResult = storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);
|
||||
PageInfo pageResult = storager.querySubChannels(deviceId, channelId, query, channelType, online, page, count);
|
||||
return new ResponseEntity<>(pageResult,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/channel/update/{deviceId}")
|
||||
public ResponseEntity<PageResult> updateChannel(@PathVariable String deviceId,DeviceChannel channel){
|
||||
public ResponseEntity<PageInfo> updateChannel(@PathVariable String deviceId,DeviceChannel channel){
|
||||
storager.updateChannel(deviceId, channel);
|
||||
return new ResponseEntity<>(null,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/devices/{deviceId}/transport/{streamMode}")
|
||||
@PostMapping("/devices/{deviceId}/transport/{streamMode}")
|
||||
public ResponseEntity<PageResult> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){
|
||||
public ResponseEntity<PageInfo> updateTransport(@PathVariable String deviceId, @PathVariable String streamMode){
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
device.setStreamMode(streamMode);
|
||||
storager.updateDevice(device);
|
||||
|
||||
@@ -1,401 +0,0 @@
|
||||
package com.genersoft.iot.vmp.vmanager.device.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.validation.constraints.Max;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @Description:视频设备信息
|
||||
* @author: songww
|
||||
* @date: 2020年5月8日 下午2:05:56
|
||||
*/
|
||||
@ApiModel(value = "视频设备信息", description = "视频设备信息")
|
||||
@Table(name="VMP_VIDEODEVICES")
|
||||
public class Device {
|
||||
|
||||
/**
|
||||
* 设备Id
|
||||
*/
|
||||
@ApiModelProperty("设备编号")
|
||||
@Id
|
||||
@Column(name="DEVICE_ID")
|
||||
@NotNull(message = "deviceId 不能为 null")
|
||||
@Size(min = 4, max = 32, message = "deviceId 必须大于 4 位并且小于 32 位")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@ApiModelProperty("设备名称")
|
||||
@Column(name="DEVICE_NAME")
|
||||
@Size(max = 32, message = "deviceName 必须小于 32 位")
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 生产厂商
|
||||
*/
|
||||
@ApiModelProperty("生产厂商")
|
||||
@Column(name="MANUFACTURER")
|
||||
@Size(max = 64, message = "manufacturer 必须小于 64 位")
|
||||
private String manufacturer;
|
||||
|
||||
/**
|
||||
* 型号
|
||||
*/
|
||||
@ApiModelProperty("型号")
|
||||
@Column(name="MODEL")
|
||||
@Size(max = 64, message = "manufacturer 必须小于 64 位")
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 固件版本
|
||||
*/
|
||||
@ApiModelProperty("固件版本")
|
||||
@Column(name="FIRMWARE")
|
||||
@Size(max = 64, message = "firmware 必须小于 64 位")
|
||||
private String firmware;
|
||||
|
||||
/**
|
||||
* 通信协议
|
||||
* GB28181 ONVIF
|
||||
*/
|
||||
@ApiModelProperty("通信协议")
|
||||
@Column(name="PROTOCOL")
|
||||
@NotNull(message = "protocol 不能为 null")
|
||||
@Size(max = 16, message = "protocol 必须小于 16 位")
|
||||
private String protocol;
|
||||
|
||||
/**
|
||||
* SIP 传输协议
|
||||
* UDP/TCP
|
||||
*/
|
||||
@ApiModelProperty("SIP 传输协议")
|
||||
@Column(name="TRANSPORT")
|
||||
@Size(min = 3,max = 3 ,message = "transport 必须为 3 位")
|
||||
private String transport;
|
||||
|
||||
/**
|
||||
* 数据流传输模式
|
||||
* UDP:udp传输
|
||||
* TCP-ACTIVE:tcp主动模式
|
||||
* TCP-PASSIVE:tcp被动模式
|
||||
*/
|
||||
@ApiModelProperty("数据流传输模式")
|
||||
@Column(name="STREAM_MODE")
|
||||
@Size(max = 64, message = "streamMode 必须小于 16 位")
|
||||
private String streamMode;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*/
|
||||
@ApiModelProperty("IP地址")
|
||||
@Column(name="IP")
|
||||
@Size(max = 15, message = "streamMode 必须小于 15 位")
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 端口号
|
||||
*/
|
||||
@ApiModelProperty("端口号")
|
||||
@Column(name="PORT")
|
||||
@Max(value = 65535,message = "port 最大值为 65535")
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* 在线状态 1在线, 0离线
|
||||
*/
|
||||
@ApiModelProperty("在线状态")
|
||||
@Size(min = 1,max = 1 ,message = "online 必须为 1 位")
|
||||
@Column(name="ONLINE")
|
||||
private String online;
|
||||
|
||||
/**
|
||||
* 通道数量
|
||||
*/
|
||||
@ApiModelProperty("通道数量")
|
||||
@Column(name="CHANNEL_SUM")
|
||||
@Max(value = 1000000000,message = "channelSum 最大值为 1000000000")
|
||||
private Integer channelSum;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Device{" +
|
||||
"deviceId='" + deviceId + '\'' +
|
||||
", deviceName='" + deviceName + '\'' +
|
||||
", manufacturer='" + manufacturer + '\'' +
|
||||
", model='" + model + '\'' +
|
||||
", firmware='" + firmware + '\'' +
|
||||
", protocol='" + protocol + '\'' +
|
||||
", transport='" + transport + '\'' +
|
||||
", streamMode='" + streamMode + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", port=" + port +
|
||||
", online='" + online + '\'' +
|
||||
", channelSum=" + channelSum +
|
||||
", createTime='" + createTime + '\'' +
|
||||
", registerTime='" + registerTime + '\'' +
|
||||
", heartbeatTime='" + heartbeatTime + '\'' +
|
||||
", updateTime='" + updateTime + '\'' +
|
||||
", updatePerson='" + updatePerson + '\'' +
|
||||
", syncTime='" + syncTime + '\'' +
|
||||
", syncPerson='" + syncPerson + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", channelList=" + channelList +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ApiModelProperty("创建时间")
|
||||
@Column(name="CREATE_TIME")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 注册时间
|
||||
*/
|
||||
@ApiModelProperty("注册时间")
|
||||
@Column(name="REGISTER_TIME")
|
||||
private String registerTime;
|
||||
|
||||
/**
|
||||
* 心跳时间
|
||||
*/
|
||||
@ApiModelProperty("心跳时间")
|
||||
@Column(name="HEARTBEAT_TIME")
|
||||
private String heartbeatTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@ApiModelProperty("更新时间")
|
||||
@Column(name="UPDATE_TIME")
|
||||
private String updateTime;
|
||||
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@ApiModelProperty("修改人")
|
||||
@Column(name="UPDATE_PERSON")
|
||||
private String updatePerson;
|
||||
|
||||
/**
|
||||
* 同步时间
|
||||
*/
|
||||
@ApiModelProperty("同步时间")
|
||||
@Column(name="SYNC_TIME")
|
||||
private String syncTime;
|
||||
|
||||
/**
|
||||
* 同步人
|
||||
*/
|
||||
@ApiModelProperty("同步人")
|
||||
@Column(name="SYNC_PERSON")
|
||||
private String syncPerson;
|
||||
|
||||
/**
|
||||
* ONVIF协议-用户名
|
||||
*/
|
||||
@ApiModelProperty("用户名")
|
||||
@Column(name="USERNAME")
|
||||
@Size(max = 32, message = "username 必须小于 32 位")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* ONVIF协议-密码
|
||||
*/
|
||||
@ApiModelProperty("密码")
|
||||
@Size(max = 32, message = "password 必须小于 32 位")
|
||||
@Column(name="PASSWORD")
|
||||
private String password;
|
||||
|
||||
@Transient
|
||||
private List<DeviceChannel> channelList;
|
||||
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public String getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
public void setManufacturer(String manufacturer) {
|
||||
this.manufacturer = manufacturer;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getFirmware() {
|
||||
return firmware;
|
||||
}
|
||||
|
||||
public void setFirmware(String firmware) {
|
||||
this.firmware = firmware;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getTransport() {
|
||||
return transport;
|
||||
}
|
||||
|
||||
public void setTransport(String transport) {
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
public String getStreamMode() {
|
||||
return streamMode;
|
||||
}
|
||||
|
||||
public void setStreamMode(String streamMode) {
|
||||
this.streamMode = streamMode;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
public void setOnline(String online) {
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public Integer getChannelSum() {
|
||||
return channelSum;
|
||||
}
|
||||
|
||||
public void setChannelSum(Integer channelSum) {
|
||||
this.channelSum = channelSum;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getRegisterTime() {
|
||||
return registerTime;
|
||||
}
|
||||
|
||||
public void setRegisterTime(String registerTime) {
|
||||
this.registerTime = registerTime;
|
||||
}
|
||||
|
||||
public String getHeartbeatTime() {
|
||||
return heartbeatTime;
|
||||
}
|
||||
|
||||
public void setHeartbeatTime(String heartbeatTime) {
|
||||
this.heartbeatTime = heartbeatTime;
|
||||
}
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public String getUpdatePerson() {
|
||||
return updatePerson;
|
||||
}
|
||||
|
||||
public void setUpdatePerson(String updatePerson) {
|
||||
this.updatePerson = updatePerson;
|
||||
}
|
||||
|
||||
public String getSyncTime() {
|
||||
return syncTime;
|
||||
}
|
||||
|
||||
public void setSyncTime(String syncTime) {
|
||||
this.syncTime = syncTime;
|
||||
}
|
||||
|
||||
public String getSyncPerson() {
|
||||
return syncPerson;
|
||||
}
|
||||
|
||||
public void setSyncPerson(String syncPerson) {
|
||||
this.syncPerson = syncPerson;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public List<DeviceChannel> getChannelList() {
|
||||
return channelList;
|
||||
}
|
||||
|
||||
public void setChannelList(List<DeviceChannel> channelList) {
|
||||
this.channelList = channelList;
|
||||
}
|
||||
}
|
||||
@@ -1,385 +0,0 @@
|
||||
package com.genersoft.iot.vmp.vmanager.device.entity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* @Description:设备通道信息
|
||||
* @author: songww
|
||||
* @date: 2020年5月20日 下午9:00:46
|
||||
*/
|
||||
@ApiModel(value = "设备通道信息", description = "设备通道信息")
|
||||
@Table(name="VMP_VIDEOCHANNELS")
|
||||
public class DeviceChannel {
|
||||
|
||||
/**
|
||||
* 通道编号
|
||||
*/
|
||||
@ApiModelProperty("通道编号")
|
||||
@Id
|
||||
@Column(name="CHANNEL_ID")
|
||||
private String channelId;
|
||||
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
@ApiModelProperty("设备编号")
|
||||
@Column(name="DEVICE_ID")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 通道名
|
||||
*/
|
||||
@ApiModelProperty("通道名")
|
||||
@Column(name="CHANNEL_NAME")
|
||||
private String channelName;
|
||||
|
||||
/**
|
||||
* 生产厂商
|
||||
*/
|
||||
@ApiModelProperty("生产厂商")
|
||||
@Column(name="MANUFACTURER")
|
||||
private String manufacture;
|
||||
|
||||
/**
|
||||
* 型号
|
||||
*/
|
||||
@ApiModelProperty("型号")
|
||||
@Column(name="MODEL")
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 设备归属
|
||||
*/
|
||||
@ApiModelProperty("设备归属")
|
||||
@Column(name="OWNER")
|
||||
private String owner;
|
||||
|
||||
/**
|
||||
* 行政区域
|
||||
*/
|
||||
@ApiModelProperty("行政区域")
|
||||
@Column(name="CIVIL_CODE")
|
||||
private String civilCode;
|
||||
|
||||
/**
|
||||
* 警区
|
||||
*/
|
||||
@ApiModelProperty("警区")
|
||||
@Column(name="BLOCK")
|
||||
private String block;
|
||||
|
||||
/**
|
||||
* 安装地址
|
||||
*/
|
||||
@ApiModelProperty("安装地址")
|
||||
@Column(name="ADDRESS")
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 是否有子设备 1有, 0没有
|
||||
*/
|
||||
@ApiModelProperty("是否有子设备")
|
||||
@Column(name="PARENTAL")
|
||||
private String parental;
|
||||
|
||||
/**
|
||||
* 父级id
|
||||
*/
|
||||
@ApiModelProperty("父级编码")
|
||||
@Column(name="PARENT_ID")
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式
|
||||
*/
|
||||
@ApiModelProperty("信令安全模式")
|
||||
@Column(name="SAFETY_WAY")
|
||||
private String safetyWay;
|
||||
|
||||
/**
|
||||
* 注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式
|
||||
*/
|
||||
@ApiModelProperty("注册方式")
|
||||
@Column(name="REGISTER_WAY")
|
||||
private String registerWay;
|
||||
|
||||
/**
|
||||
* 证书序列号
|
||||
*/
|
||||
@ApiModelProperty("证书序列号")
|
||||
@Column(name="CERT_NUM")
|
||||
private String certNum;
|
||||
|
||||
/**
|
||||
* 证书有效标识 缺省为0;证书有效标识:0:无效1: 有效
|
||||
*/
|
||||
@ApiModelProperty("证书有效标识")
|
||||
@Column(name="CERT_VALID")
|
||||
private String certValid;
|
||||
|
||||
/**
|
||||
* 证书无效原因码
|
||||
*/
|
||||
@ApiModelProperty("证书无效原因码")
|
||||
@Column(name="CERT_ERRCODE")
|
||||
private String certErrCode;
|
||||
|
||||
/**
|
||||
* 证书终止有效期
|
||||
*/
|
||||
@ApiModelProperty("证书终止有效期")
|
||||
@Column(name="CERT_ENDTIME")
|
||||
private String certEndTime;
|
||||
|
||||
/**
|
||||
* 保密属性 缺省为0; 0:不涉密, 1:涉密
|
||||
*/
|
||||
@ApiModelProperty("保密属性")
|
||||
@Column(name="SECRECY")
|
||||
private String secrecy;
|
||||
|
||||
/**
|
||||
* IP地址
|
||||
*/
|
||||
@ApiModelProperty("IP地址")
|
||||
@Column(name="IP")
|
||||
private String ip;
|
||||
|
||||
/**
|
||||
* 端口号
|
||||
*/
|
||||
@ApiModelProperty("端口号")
|
||||
@Column(name="PORT")
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@ApiModelProperty("密码")
|
||||
@Column(name="PASSWORD")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 在线/离线
|
||||
* 1在线,0离线
|
||||
* 默认在线
|
||||
* 信令:
|
||||
* <Status>ON</Status>
|
||||
* <Status>OFF</Status>
|
||||
* 遇到过NVR下的IPC下发信令可以推流, 但是 Status 响应 OFF
|
||||
*/
|
||||
@ApiModelProperty("状态")
|
||||
@Column(name="ONLINE")
|
||||
private String online;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
@ApiModelProperty("经度")
|
||||
@Column(name="LONGITUDE")
|
||||
private double longitude;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
@ApiModelProperty("纬度")
|
||||
@Column(name="LATITUDE")
|
||||
private double latitude;
|
||||
|
||||
public String getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(String channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(String deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
|
||||
public String getChannelName() {
|
||||
return channelName;
|
||||
}
|
||||
|
||||
public void setChannelName(String channelName) {
|
||||
this.channelName = channelName;
|
||||
}
|
||||
|
||||
public String getManufacture() {
|
||||
return manufacture;
|
||||
}
|
||||
|
||||
public void setManufacture(String manufacture) {
|
||||
this.manufacture = manufacture;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public void setModel(String model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getCivilCode() {
|
||||
return civilCode;
|
||||
}
|
||||
|
||||
public void setCivilCode(String civilCode) {
|
||||
this.civilCode = civilCode;
|
||||
}
|
||||
|
||||
public String getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
public void setBlock(String block) {
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getParental() {
|
||||
return parental;
|
||||
}
|
||||
|
||||
public void setParental(String parental) {
|
||||
this.parental = parental;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getSafetyWay() {
|
||||
return safetyWay;
|
||||
}
|
||||
|
||||
public void setSafetyWay(String safetyWay) {
|
||||
this.safetyWay = safetyWay;
|
||||
}
|
||||
|
||||
public String getRegisterWay() {
|
||||
return registerWay;
|
||||
}
|
||||
|
||||
public void setRegisterWay(String registerWay) {
|
||||
this.registerWay = registerWay;
|
||||
}
|
||||
|
||||
public String getCertNum() {
|
||||
return certNum;
|
||||
}
|
||||
|
||||
public void setCertNum(String certNum) {
|
||||
this.certNum = certNum;
|
||||
}
|
||||
|
||||
public String getCertValid() {
|
||||
return certValid;
|
||||
}
|
||||
|
||||
public void setCertValid(String certValid) {
|
||||
this.certValid = certValid;
|
||||
}
|
||||
|
||||
public String getCertErrCode() {
|
||||
return certErrCode;
|
||||
}
|
||||
|
||||
public void setCertErrCode(String certErrCode) {
|
||||
this.certErrCode = certErrCode;
|
||||
}
|
||||
|
||||
public String getCertEndTime() {
|
||||
return certEndTime;
|
||||
}
|
||||
|
||||
public void setCertEndTime(String certEndTime) {
|
||||
this.certEndTime = certEndTime;
|
||||
}
|
||||
|
||||
public String getSecrecy() {
|
||||
return secrecy;
|
||||
}
|
||||
|
||||
public void setSecrecy(String secrecy) {
|
||||
this.secrecy = secrecy;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
public void setOnline(String online) {
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import com.genersoft.iot.vmp.conf.MediaServerConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.service.IPlayService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -27,6 +29,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sip.message.Response;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -43,6 +46,9 @@ public class PlayController {
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
@Autowired
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@@ -58,18 +64,11 @@ public class PlayController {
|
||||
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
StreamInfo streamInfo = storager.queryPlayByDevice(deviceId, channelId);
|
||||
StreamInfo streamInfo = redisCatchStorage.queryPlayByDevice(deviceId, channelId);
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
|
||||
// 超时处理
|
||||
result.onTimeout(()->{
|
||||
logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData("Timeout");
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
|
||||
|
||||
@@ -78,9 +77,15 @@ public class PlayController {
|
||||
cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
|
||||
logger.info("收到订阅消息: " + response.toJSONString());
|
||||
playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
|
||||
}, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
Response response = event.getResponse();
|
||||
msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
} else {
|
||||
String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
|
||||
String streamId = streamInfo.getStreamId();
|
||||
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
|
||||
if (rtpInfo.getBoolean("exist")) {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
@@ -88,58 +93,107 @@ public class PlayController {
|
||||
msg.setData(JSON.toJSONString(streamInfo));
|
||||
resultHolder.invokeResult(msg);
|
||||
} else {
|
||||
storager.stopPlay(streamInfo);
|
||||
// TODO playStreamCmd 超时处理
|
||||
redisCatchStorage.stopPlay(streamInfo);
|
||||
cmder.playStreamCmd(device, channelId, (JSONObject response) -> {
|
||||
logger.info("收到订阅消息: " + response.toJSONString());
|
||||
playService.onPublishHandlerForPlay(response, deviceId, channelId, uuid.toString());
|
||||
}, event -> {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
Response response = event.getResponse();
|
||||
msg.setData(String.format("点播失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 超时处理
|
||||
result.onTimeout(()->{
|
||||
logger.warn(String.format("设备点播超时,deviceId:%s ,channelId:%s", deviceId, channelId));
|
||||
// 释放rtpserver
|
||||
cmder.closeRTPServer(device, channelId);
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData("Timeout");
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/play/{ssrc}/stop")
|
||||
public ResponseEntity<String> playStop(@PathVariable String ssrc) {
|
||||
@PostMapping("/play/{streamId}/stop")
|
||||
public DeferredResult<ResponseEntity<String>> playStop(@PathVariable String streamId) {
|
||||
|
||||
cmder.streamByeCmd(ssrc);
|
||||
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
|
||||
if (streamInfo == null)
|
||||
return new ResponseEntity<String>("ssrc not found", HttpStatus.OK);
|
||||
storager.stopPlay(streamInfo);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("设备预览停止API调用,ssrc:%s", ssrc));
|
||||
}
|
||||
logger.debug(String.format("设备预览/回放停止API调用,streamId:%s", streamId));
|
||||
|
||||
if (ssrc != null) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
DeferredResult<ResponseEntity<String>> result = new DeferredResult<ResponseEntity<String>>();
|
||||
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_STOP + uuid, result);
|
||||
|
||||
cmder.streamByeCmd(streamId, event -> {
|
||||
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
|
||||
if (streamInfo == null) {
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData("streamId not found");
|
||||
resultHolder.invokeResult(msg);
|
||||
redisCatchStorage.stopPlay(streamInfo);
|
||||
}
|
||||
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid);
|
||||
Response response = event.getResponse();
|
||||
msg.setData(String.format("success"));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (streamId != null) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("ssrc", ssrc);
|
||||
return new ResponseEntity<String>(json.toString(), HttpStatus.OK);
|
||||
json.put("streamId", streamId);
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData(json.toString());
|
||||
resultHolder.invokeResult(msg);
|
||||
} else {
|
||||
logger.warn("设备预览停止API调用失败!");
|
||||
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
logger.warn("设备预览/回放停止API调用失败!");
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData("streamId null");
|
||||
resultHolder.invokeResult(msg);
|
||||
}
|
||||
|
||||
// 超时处理
|
||||
result.onTimeout(()->{
|
||||
logger.warn(String.format("设备预览/回放停止超时,streamId:%s ", streamId));
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_STOP + uuid);
|
||||
msg.setData("Timeout");
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将不是h264的视频通过ffmpeg 转码为h264 + aac
|
||||
* @param ssrc
|
||||
* @param streamId 流ID
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/play/{ssrc}/convert")
|
||||
public ResponseEntity<String> playConvert(@PathVariable String ssrc) {
|
||||
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
|
||||
@PostMapping("/play/{streamId}/convert")
|
||||
public ResponseEntity<String> playConvert(@PathVariable String streamId) {
|
||||
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
|
||||
if (streamInfo == null) {
|
||||
logger.warn("视频转码API调用失败!, 视频流已经停止!");
|
||||
return new ResponseEntity<String>("未找到视频流信息, 视频流可能已经停止", HttpStatus.OK);
|
||||
}
|
||||
String streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase();
|
||||
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
|
||||
if (!rtpInfo.getBoolean("exist")) {
|
||||
logger.warn("视频转码API调用失败!, 视频流已停止推流!");
|
||||
return new ResponseEntity<String>("推流信息在流媒体中不存在, 视频流可能已停止推流", HttpStatus.OK);
|
||||
} else {
|
||||
MediaServerConfig mediaInfo = storager.getMediaInfo();
|
||||
MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo();
|
||||
String dstUrl = String.format("rtmp://%s:%s/convert/%s", "127.0.0.1", mediaInfo.getRtmpPort(),
|
||||
streamId );
|
||||
String srcUrl = String.format("rtsp://%s:%s/rtp/%s", "127.0.0.1", mediaInfo.getRtspPort(), streamId);
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.service.IPlayService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -27,6 +28,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
import org.springframework.web.context.request.async.DeferredResult;
|
||||
|
||||
import javax.sip.message.Response;
|
||||
import java.util.UUID;
|
||||
|
||||
@CrossOrigin
|
||||
@@ -42,6 +44,9 @@ public class PlaybackController {
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
@Autowired
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@@ -69,15 +74,21 @@ public class PlaybackController {
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
StreamInfo streamInfo = storager.queryPlaybackByDevice(deviceId, channelId);
|
||||
StreamInfo streamInfo = redisCatchStorage.queryPlaybackByDevice(deviceId, channelId);
|
||||
if (streamInfo != null) {
|
||||
// 停止之前的回放
|
||||
cmder.streamByeCmd(streamInfo.getSsrc());
|
||||
cmder.streamByeCmd(streamInfo.getStreamId());
|
||||
}
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid, result);
|
||||
cmder.playbackStreamCmd(device, channelId, startTime, endTime, (JSONObject response) -> {
|
||||
logger.info("收到订阅消息: " + response.toJSONString());
|
||||
playService.onPublishHandlerForPlayBack(response, deviceId, channelId, uuid.toString());
|
||||
}, event -> {
|
||||
Response response = event.getResponse();
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
msg.setData(String.format("回放失败, 错误码: %s, %s", response.getStatusCode(), response.getReasonPhrase()));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
@@ -29,15 +29,14 @@ public class PtzController {
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
/***
|
||||
* http://localhost:8080/api/ptz/34020000001320000002_34020000001320000008?leftRight=1&upDown=0&inOut=0&moveSpeed=50&zoomSpeed=0
|
||||
* @param deviceId
|
||||
* @param channelId
|
||||
* @param leftRight
|
||||
* @param upDown
|
||||
* @param inOut
|
||||
* @param moveSpeed
|
||||
* @param zoomSpeed
|
||||
* @return
|
||||
* 云台控制
|
||||
* @param deviceId 设备id
|
||||
* @param channelId 通道id
|
||||
* @param cmdCode 指令码
|
||||
* @param horizonSpeed 水平移动速度
|
||||
* @param verticalSpeed 垂直移动速度
|
||||
* @param zoomSpeed 缩放速度
|
||||
* @return String 控制结果
|
||||
*/
|
||||
@PostMapping("/ptz/{deviceId}/{channelId}")
|
||||
public ResponseEntity<String> ptz(@PathVariable String deviceId,@PathVariable String channelId,int cmdCode, int horizonSpeed, int verticalSpeed, int zoomSpeed){
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.genersoft.iot.vmp.vmanager.record;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -32,7 +33,7 @@ public class RecordController {
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
|
||||
@GetMapping("/record/{deviceId}/{channelId}")
|
||||
public DeferredResult<ResponseEntity<RecordInfo>> recordinfo(@PathVariable String deviceId,@PathVariable String channelId, String startTime, String endTime){
|
||||
|
||||
@@ -42,9 +43,17 @@ public class RecordController {
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
cmder.recordInfoQuery(device, channelId, startTime, endTime);
|
||||
DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>();
|
||||
// 指定超时时间 1分钟30秒
|
||||
DeferredResult<ResponseEntity<RecordInfo>> result = new DeferredResult<ResponseEntity<RecordInfo>>(90*1000L);
|
||||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(DeferredResultHolder.CALLBACK_CMD_RECORDINFO+channelId, result);
|
||||
result.onTimeout(()->{
|
||||
RequestMessage msg = new RequestMessage();
|
||||
msg.setDeviceId(deviceId);
|
||||
msg.setType(DeferredResultHolder.CALLBACK_CMD_RECORDINFO);
|
||||
msg.setData("timeout");
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.MediaServerConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
import com.genersoft.iot.vmp.vmanager.play.PlayController;
|
||||
import com.genersoft.iot.vmp.vmanager.service.IPlayService;
|
||||
@@ -24,6 +26,9 @@ public class PlayServiceImpl implements IPlayService {
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
@Autowired
|
||||
private IRedisCatchStorage redisCatchStorage;
|
||||
|
||||
@Autowired
|
||||
private DeferredResultHolder resultHolder;
|
||||
|
||||
@@ -33,7 +38,13 @@ public class PlayServiceImpl implements IPlayService {
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
|
||||
if (streamInfo != null) {
|
||||
storager.startPlay(streamInfo);
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
deviceChannel.setStreamId(streamInfo.getStreamId());
|
||||
storager.updateChannel(deviceId, deviceChannel);
|
||||
}
|
||||
|
||||
redisCatchStorage.startPlay(streamInfo);
|
||||
msg.setData(JSON.toJSONString(streamInfo));
|
||||
resultHolder.invokeResult(msg);
|
||||
} else {
|
||||
@@ -49,7 +60,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
msg.setId(DeferredResultHolder.CALLBACK_CMD_PlAY + uuid);
|
||||
StreamInfo streamInfo = onPublishHandler(resonse, deviceId, channelId, uuid);
|
||||
if (streamInfo != null) {
|
||||
storager.startPlayback(streamInfo);
|
||||
redisCatchStorage.startPlayback(streamInfo);
|
||||
msg.setData(JSON.toJSONString(streamInfo));
|
||||
resultHolder.invokeResult(msg);
|
||||
} else {
|
||||
@@ -61,13 +72,11 @@ public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
public StreamInfo onPublishHandler(JSONObject resonse, String deviceId, String channelId, String uuid) {
|
||||
String streamId = resonse.getString("id");
|
||||
String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16));
|
||||
StreamInfo streamInfo = new StreamInfo();
|
||||
streamInfo.setSsrc(ssrc);
|
||||
streamInfo.setStreamId(streamId);
|
||||
streamInfo.setDeviceID(deviceId);
|
||||
streamInfo.setCahnnelId(channelId);
|
||||
MediaServerConfig mediaServerConfig = storager.getMediaInfo();
|
||||
MediaServerConfig mediaServerConfig = redisCatchStorage.getMediaInfo();
|
||||
|
||||
streamInfo.setFlv(String.format("http://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
|
||||
streamInfo.setWs_flv(String.format("ws://%s:%s/rtp/%s.flv", mediaServerConfig.getWanIp(), mediaServerConfig.getHttpPort(), streamId));
|
||||
|
||||
Reference in New Issue
Block a user