Merge branch 'wvp-28181-2.0'
# Conflicts:
# src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
| | |
| | | - [X] 实时视音频点播 |
| | | - [X] 设备控制 |
| | | - [X] 云台控制 |
| | | - [ ] 远程启动 |
| | | - [ ] 录像控制 |
| | | - [ ] 报警布防/撤防 |
| | | - [ ] 报警复位 |
| | | - [X] 远程启动 |
| | | - [X] 录像控制 |
| | | - [X] 报警布防/撤防 |
| | | - [X] 报警复位 |
| | | - [X] 强制关键帧 |
| | | - [ ] 拉框放大 |
| | | - [ ] 拉框缩小 |
| | | - [ ] 看守位控制 |
| | | - [ ] 设备配置 |
| | | - [X] 拉框放大 |
| | | - [X] 拉框缩小 |
| | | - [X] 看守位控制 |
| | | - [X] 设备配置 |
| | | - [X] 报警事件通知和分发 |
| | | - [X] 设备目录订阅 |
| | | - [X] 网络设备信息查询 |
| | | - [X] 设备目录查询 |
| | | - [X] 设备状态查询 |
| | | - [ ] 设备配置查询 |
| | | - [ ] 设备预置位查询 |
| | | - [X] 设备配置查询 |
| | | - [X] 设备预置位查询 |
| | | - [X] 状态信息报送 |
| | | - [X] 设备视音频文件检索 |
| | | - [X] 历史视音频的回放 |
| | |
| | | `ffmpeg_cmd_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| | | `rtp_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| | | `mediaServerId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, |
| | | `enable_hls` bit(1) DEFAULT NULL, |
| | | `enable_audio` bit(1) DEFAULT NULL, |
| | | `enable_mp4` bit(1) DEFAULT NULL, |
| | | `enable` bit(1) NOT NULL, |
| | | `status` bit(1) NOT NULL, |
| | |
| | | |
| | | alter table device |
| | | modify hostAddress varchar(50) null; |
| | | |
| | | alter table stream_proxy |
| | | change enable_hls enable_audio bit null; |
| | | |
| | | |
| | |
| | | package com.genersoft.iot.vmp.conf; |
| | | |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.gb28181.event.alarm.AlarmEventListener; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.http.HttpStatus; |
| | | import org.springframework.http.ResponseEntity; |
| | | import org.springframework.security.authentication.BadCredentialsException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.ResponseStatus; |
| | |
| | | */ |
| | | @ExceptionHandler(ControllerException.class) |
| | | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) |
| | | public WVPResult<String> exceptionHandler(ControllerException e) { |
| | | return WVPResult.fail(e.getCode(), e.getMsg()); |
| | | public ResponseEntity<WVPResult<String>> exceptionHandler(ControllerException e) { |
| | | return new ResponseEntity<>(WVPResult.fail(e.getCode(), e.getMsg()), HttpStatus.OK); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @ExceptionHandler(BadCredentialsException.class) |
| | | @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) |
| | | public WVPResult<String> exceptionHandler(BadCredentialsException e) { |
| | | return WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage()); |
| | | public ResponseEntity<WVPResult<String>> exceptionHandler(BadCredentialsException e) { |
| | | return new ResponseEntity<>(WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage()), HttpStatus.OK); |
| | | } |
| | | } |
| | |
| | | |
| | | private Boolean gbSendStreamStrict = Boolean.FALSE; |
| | | |
| | | private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; |
| | | |
| | | private String serverId = "000000"; |
| | | |
| | | private String thirdPartyGBIdReg = "[\\s\\S]*"; |
| | |
| | | public void setGbSendStreamStrict(Boolean gbSendStreamStrict) { |
| | | this.gbSendStreamStrict = gbSendStreamStrict; |
| | | } |
| | | |
| | | public Boolean getSyncChannelOnDeviceOnline() { |
| | | return syncChannelOnDeviceOnline; |
| | | } |
| | | |
| | | public void setSyncChannelOnDeviceOnline(Boolean syncChannelOnDeviceOnline) { |
| | | this.syncChannelOnDeviceOnline = syncChannelOnDeviceOnline; |
| | | } |
| | | } |
| | |
| | |
|
| | | import com.genersoft.iot.vmp.common.StreamInfo;
|
| | | import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.*;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.Device;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
|
| | | import com.genersoft.iot.vmp.gb28181.bean.InviteStreamCallback;
|
| | | import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
|
| | | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
| | |
| | | import gov.nist.javax.sip.message.SIPRequest;
|
| | |
|
| | | import javax.sip.InvalidArgumentException;
|
| | | import javax.sip.PeerUnavailableException;
|
| | | import javax.sip.SipException;
|
| | | import javax.sip.message.Message;
|
| | | import javax.sip.message.Request;
|
| | | import java.text.ParseException;
|
| | | import javax.sip.message.Message;
|
| | | import javax.sip.message.Request;
|
| | |
| | | */
|
| | | void deviceConfigCmd(Device device);
|
| | |
|
| | | /**
|
| | | /**
|
| | | * 设备配置命令:basicParam
|
| | | *
|
| | | * @param device 视频设备
|
| | |
| | | * @param heartBeatCount 心跳超时次数(可选)
|
| | | */
|
| | | void deviceBasicConfigCmd(Device device, String channelId, String name, String expiration, String heartBeatInterval, String heartBeatCount, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
| | | |
| | |
|
| | | /**
|
| | | * 查询设备状态
|
| | | *
|
| | |
| | | // 修改数据
|
| | | streamProxyService.stop(param.getApp(), param.getStream());
|
| | | }else {
|
| | | // 无人观看不做处理
|
| | | ret.put("close", false);
|
| | | }
|
| | | return ret;
|
| | |
| | | } |
| | | |
| | | public JSONObject addFFmpegSource(MediaServerItem mediaServerItem, String src_url, String dst_url, String timeout_ms, |
| | | boolean enable_hls, boolean enable_mp4, String ffmpeg_cmd_key){ |
| | | boolean enable_audio, boolean enable_mp4, String ffmpeg_cmd_key){ |
| | | logger.info(src_url); |
| | | logger.info(dst_url); |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("src_url", src_url); |
| | | param.put("dst_url", dst_url); |
| | | param.put("timeout_ms", timeout_ms); |
| | | param.put("enable_hls", enable_hls); |
| | | param.put("enable_mp4", enable_mp4); |
| | | param.put("ffmpeg_cmd_key", ffmpeg_cmd_key); |
| | | return sendPost(mediaServerItem, "addFFmpegSource",param, null); |
| | |
| | | return sendPost(mediaServerItem, "restartServer",null, null); |
| | | } |
| | | |
| | | public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_hls, boolean enable_mp4, String rtp_type) { |
| | | public JSONObject addStreamProxy(MediaServerItem mediaServerItem, String app, String stream, String url, boolean enable_audio, boolean enable_mp4, String rtp_type) { |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("vhost", "__defaultVhost__"); |
| | | param.put("app", app); |
| | | param.put("stream", stream); |
| | | param.put("url", url); |
| | | param.put("enable_hls", enable_hls?1:0); |
| | | param.put("enable_mp4", enable_mp4?1:0); |
| | | param.put("enable_rtmp", 1); |
| | | param.put("enable_fmp4", 1); |
| | | param.put("enable_audio", 1); |
| | | param.put("enable_rtsp", 1); |
| | | param.put("add_mute_audio", 1); |
| | | param.put("enable_audio", enable_audio?1:0); |
| | | param.put("rtp_type", rtp_type); |
| | | return sendPost(mediaServerItem, "addStreamProxy",param, null); |
| | | } |
| | |
| | | private String rtp_type; |
| | | @Schema(description = "是否启用") |
| | | private boolean enable; |
| | | @Schema(description = "是否启用HLS") |
| | | private boolean enable_hls; |
| | | @Schema(description = "是否启用音频") |
| | | private boolean enable_audio; |
| | | @Schema(description = "是否启用MP4") |
| | | private boolean enable_mp4; |
| | | @Schema(description = "是否 无人观看时删除") |
| | |
| | | |
| | | @Schema(description = "是否 无人观看时自动停用") |
| | | private boolean enable_disable_none_reader; |
| | | @Schema(description = "上级平台国标ID") |
| | | private String platformGbId; |
| | | @Schema(description = "创建时间") |
| | | private String createTime; |
| | | |
| | |
| | | this.enable = enable; |
| | | } |
| | | |
| | | public boolean isEnable_hls() { |
| | | return enable_hls; |
| | | } |
| | | |
| | | public void setEnable_hls(boolean enable_hls) { |
| | | this.enable_hls = enable_hls; |
| | | } |
| | | |
| | | public boolean isEnable_mp4() { |
| | | return enable_mp4; |
| | | } |
| | |
| | | this.enable_mp4 = enable_mp4; |
| | | } |
| | | |
| | | |
| | | public String getPlatformGbId() { |
| | | return platformGbId; |
| | | } |
| | | |
| | | public void setPlatformGbId(String platformGbId) { |
| | | this.platformGbId = platformGbId; |
| | | } |
| | | |
| | | @Override |
| | | public String getCreateTime() { |
| | | return createTime; |
| | | } |
| | | |
| | | @Override |
| | | public void setCreateTime(String createTime) { |
| | | this.createTime = createTime; |
| | | } |
| | |
| | | public void setEnable_disable_none_reader(boolean enable_disable_none_reader) { |
| | | this.enable_disable_none_reader = enable_disable_none_reader; |
| | | } |
| | | |
| | | public boolean isEnable_audio() { |
| | | return enable_audio; |
| | | } |
| | | |
| | | public void setEnable_audio(boolean enable_audio) { |
| | | this.enable_audio = enable_audio; |
| | | } |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| | | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | * @return |
| | | */ |
| | | ResourceBaceInfo getOverview(); |
| | | |
| | | /** |
| | | * 查询所有未分配的通道 |
| | | * @param platformId |
| | | * @return |
| | | */ |
| | | List<ChannelReduce> queryAllChannelList(String platformId); |
| | | } |
| | |
| | | int updateGbIdOrName(List<StreamPushItem> streamPushItemForUpdate); |
| | | |
| | | DeviceChannel getDeviceChannelListByStreamWithStatus(GbStream gbStream, String catalogId, ParentPlatform platform); |
| | | |
| | | /** |
| | | * 查询所有未分配的通道 |
| | | * @param platformId |
| | | * @return |
| | | */ |
| | | List<GbStream> getAllGBChannels(String platformId); |
| | | |
| | | /** |
| | | * 移除所有关联的通道 |
| | | * @param platformId |
| | | * @param catalogId |
| | | */ |
| | | void delAllPlatformInfo(String platformId, String catalogId); |
| | | } |
| | |
| | | */ |
| | | int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces, String catalogId); |
| | | |
| | | /** |
| | | * 移除目录下的所有通道 |
| | | * @param platformId |
| | | * @param catalogId |
| | | * @return |
| | | */ |
| | | int delAllChannelForGB(String platformId, String catalogId); |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| | | import com.genersoft.iot.vmp.vmanager.gb28181.platform.bean.ChannelReduce; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | public ResourceBaceInfo getOverview() { |
| | | return channelMapper.getOverview(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public List<ChannelReduce> queryAllChannelList(String platformId) { |
| | | return channelMapper.queryChannelListInAll(null, null, null, platformId, null); |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | package com.genersoft.iot.vmp.service.impl; |
| | | |
| | | import com.genersoft.iot.vmp.conf.DynamicTask; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager; |
| | | import com.genersoft.iot.vmp.gb28181.task.ISubscribeTask; |
| | |
| | | import com.genersoft.iot.vmp.service.IDeviceService; |
| | | import com.genersoft.iot.vmp.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.DeviceMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.PlatformChannelMapper; |
| | |
| | | TransactionDefinition transactionDefinition; |
| | | |
| | | @Autowired |
| | | private IVideoManagerStorage storage; |
| | | private UserSetting userSetting; |
| | | |
| | | @Autowired |
| | | private ISIPCommander commander; |
| | |
| | | if(device.getOnline() == 0){ |
| | | device.setOnline(1); |
| | | device.setCreateTime(now); |
| | | logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId()); |
| | | deviceMapper.update(device); |
| | | redisCatchStorage.updateDevice(device); |
| | | try { |
| | | commander.deviceInfoQuery(device); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage()); |
| | | if (userSetting.getSyncChannelOnDeviceOnline()) { |
| | | logger.info("[设备上线,离线状态下重新注册]: {},查询设备信息以及通道信息", device.getDeviceId()); |
| | | try { |
| | | commander.deviceInfoQuery(device); |
| | | } catch (InvalidArgumentException | SipException | ParseException e) { |
| | | logger.error("[命令发送失败] 查询设备信息: {}", e.getMessage()); |
| | | } |
| | | sync(device); |
| | | // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台 |
| | | } |
| | | sync(device); |
| | | // TODO 如果设备下的通道级联到了其他平台,那么需要发送事件或者notify给上级平台 |
| | | }else { |
| | | if (deviceChannelMapper.queryAllChannels(device.getDeviceId()).size() == 0) { |
| | | logger.info("[设备上线]: {},通道数为0,查询通道信息", device.getDeviceId()); |
| | |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.PlatformCatalogMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | import org.slf4j.Logger; |
| | |
| | | import org.springframework.transaction.TransactionDefinition; |
| | | import org.springframework.transaction.TransactionStatus; |
| | | import org.springframework.util.ObjectUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | |
| | | deviceChannel.setSecrecy("0"); |
| | | return deviceChannel; |
| | | } |
| | | |
| | | @Override |
| | | public List<GbStream> getAllGBChannels(String platformId) { |
| | | |
| | | return gbStreamMapper.selectAll(platformId, null, null, null); |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void delAllPlatformInfo(String platformId, String catalogId) { |
| | | if (platformId == null) { |
| | | return ; |
| | | } |
| | | ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId); |
| | | if (platform == null) { |
| | | return ; |
| | | } |
| | | if (ObjectUtils.isEmpty(catalogId)) { |
| | | catalogId = platform.getDeviceGBId(); |
| | | } |
| | | if (platformGbStreamMapper.delByPlatformAndCatalogId(platformId, catalogId) > 0) { |
| | | List<GbStream> gbStreams = platformGbStreamMapper.queryChannelInParentPlatformAndCatalog(platformId, catalogId); |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | for (GbStream gbStream : gbStreams) { |
| | | DeviceChannel deviceChannel = new DeviceChannel(); |
| | | deviceChannel.setChannelId(gbStream.getGbId()); |
| | | deviceChannelList.add(deviceChannel); |
| | | } |
| | | eventPublisher.catalogEventPublish(platformId, deviceChannelList, CatalogEvent.DEL); |
| | | } |
| | | } |
| | | } |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | |
| | | } |
| | | return deviceChannelList; |
| | | } |
| | | |
| | | @Override |
| | | public int delAllChannelForGB(String platformId, String catalogId) { |
| | | |
| | | int result; |
| | | if (platformId == null) { |
| | | return 0; |
| | | } |
| | | ParentPlatform platform = platformMapper.getParentPlatByServerGBId(platformId); |
| | | if (platform == null) { |
| | | return 0; |
| | | } |
| | | if (ObjectUtils.isEmpty(catalogId)) { |
| | | catalogId = platform.getDeviceGBId(); |
| | | } |
| | | |
| | | if ((result = platformChannelMapper.delChannelForGBByCatalogId(platformId, catalogId)) > 0) { |
| | | List<DeviceChannel> deviceChannels = platformChannelMapper.queryAllChannelInCatalog(platformId, catalogId); |
| | | eventPublisher.catalogEventPublish(platformId, deviceChannels, CatalogEvent.DEL); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.genersoft.iot.vmp.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.service.IMediaService; |
| | | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.storager.dao.GbStreamMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.ParentPlatformMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.PlatformGbStreamMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.StreamProxyMapper; |
| | | import com.genersoft.iot.vmp.service.IStreamProxyService; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| | |
| | | import org.springframework.transaction.TransactionStatus; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.util.*; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 视频代理业务 |
| | |
| | | param.getStream() ); |
| | | param.setDst_url(dstUrl); |
| | | StringBuffer resultMsg = new StringBuffer(); |
| | | boolean streamLive = false; |
| | | param.setMediaServerId(mediaInfo.getId()); |
| | | boolean saveResult; |
| | | // 更新 |
| | |
| | | if (param.isEnable()) { |
| | | JSONObject jsonObject = addStreamProxyToZlm(param); |
| | | if (jsonObject == null || jsonObject.getInteger("code") != 0) { |
| | | streamLive = false; |
| | | resultMsg.append(", 但是启用失败,请检查流地址是否可用"); |
| | | param.setEnable(false); |
| | | // 直接移除 |
| | |
| | | updateStreamProxy(param); |
| | | } |
| | | |
| | | |
| | | }else { |
| | | streamLive = true; |
| | | resultForStreamInfo = mediaService.getStreamInfoByAppAndStream( |
| | | mediaInfo, param.getApp(), param.getStream(), null, null); |
| | | |
| | | } |
| | | } |
| | | if ( !ObjectUtils.isEmpty(param.getPlatformGbId()) && streamLive) { |
| | | List<GbStream> gbStreams = new ArrayList<>(); |
| | | gbStreams.add(param); |
| | | if (gbStreamService.addPlatformInfo(gbStreams, param.getPlatformGbId(), param.getCatalogId())){ |
| | | return resultForStreamInfo; |
| | | }else { |
| | | resultMsg.append(", 关联国标平台[ " + param.getPlatformGbId() + " ]失败"); |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString()); |
| | | } |
| | | }else { |
| | | if (!streamLive) { |
| | | throw new ControllerException(ErrorCode.ERROR100.getCode(), resultMsg.toString()); |
| | | } |
| | | } |
| | | return resultForStreamInfo; |
| | |
| | | } |
| | | if ("default".equals(param.getType())){ |
| | | result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(), |
| | | param.isEnable_hls(), param.isEnable_mp4(), param.getRtp_type()); |
| | | param.isEnable_audio(), param.isEnable_mp4(), param.getRtp_type()); |
| | | }else if ("ffmpeg".equals(param.getType())) { |
| | | result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrc_url(), param.getDst_url(), |
| | | param.getTimeout_ms() + "", param.isEnable_hls(), param.isEnable_mp4(), |
| | | param.getTimeout_ms() + "", param.isEnable_audio(), param.isEnable_mp4(), |
| | | param.getFfmpeg_cmd_key()); |
| | | } |
| | | return result; |
| | |
| | | result = true; |
| | | streamProxy.setEnable(true); |
| | | updateStreamProxy(streamProxy); |
| | | }else { |
| | | logger.info("启用代理失败: {}/{}->{}({})", app, stream, jsonObject.getString("msg"), |
| | | streamProxy.getSrc_url() == null? streamProxy.getUrl():streamProxy.getSrc_url()); |
| | | } |
| | | } |
| | | return result; |
| | |
| | | package com.genersoft.iot.vmp.storager.dao; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.Device; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel; |
| | | import com.genersoft.iot.vmp.gb28181.bean.DeviceChannelInPlatform; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ResourceBaceInfo; |
| | |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| | | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| | | import com.genersoft.iot.vmp.vmanager.bean.StreamPushExcelDto; |
| | | import org.apache.ibatis.annotations.*; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | |
| | | |
| | | @Select("SELECT status FROM stream_push WHERE app=#{app} AND stream=#{stream}") |
| | | Boolean selectStatusForPush(String app, String stream); |
| | | |
| | | } |
| | |
| | | @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE dc.channelId='${channelId}' and pgc.platformId='${platformId}'") |
| | | List<DeviceChannel> queryChannelInParentPlatform(String platformId, String channelId); |
| | | |
| | | @Select("SELECT dc.* FROM platform_gb_channel pgc left join device_channel dc on dc.id = pgc.deviceChannelId WHERE pgc.platformId='${platformId}' and pgc.catalogId=#{catalogId}") |
| | | List<DeviceChannel> queryAllChannelInCatalog(String platformId, String catalogId); |
| | | |
| | | @Select(" select dc.channelId as id, dc.name as name, pgc.platformId as platformId, pgc.catalogId as parentId, 0 as childrenCount, 1 as type " + |
| | | " from device_channel dc left join platform_gb_channel pgc on dc.id = pgc.deviceChannelId " + |
| | | " where pgc.platformId=#{platformId} and pgc.catalogId=#{catalogId}") |
| | |
| | | "DELETE FROM platform_gb_channel WHERE platformId=#{serverGBId}" + |
| | | "</script>") |
| | | void delByPlatformId(String serverGBId); |
| | | |
| | | @Delete("<script> " + |
| | | "DELETE FROM platform_gb_channel WHERE platformId=#{platformId} and catalogId=#{catalogId}" + |
| | | "</script>") |
| | | int delChannelForGBByCatalogId(String platformId, String catalogId); |
| | | } |
| | |
| | | "</foreach>" + |
| | | "</script>") |
| | | void delByAppAndStreamsByPlatformId(List<GbStream> gbStreams, String platformId); |
| | | |
| | | @Delete("DELETE FROM platform_gb_stream WHERE platformId=#{platformId} and catalogId=#{catalogId}") |
| | | int delByPlatformAndCatalogId(String platformId, String catalogId); |
| | | } |
| | |
| | | public interface StreamProxyMapper { |
| | | |
| | | @Insert("INSERT INTO stream_proxy (type, name, app, stream,mediaServerId, url, src_url, dst_url, " + |
| | | "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" + |
| | | "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_audio, enable_mp4, enable, status, enable_remove_none_reader, enable_disable_none_reader, createTime) VALUES" + |
| | | "('${type}','${name}', '${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " + |
| | | "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, ${status}, " + |
| | | "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_audio}, ${enable_mp4}, ${enable}, ${status}, " + |
| | | "${enable_remove_none_reader}, ${enable_disable_none_reader}, '${createTime}' )") |
| | | int add(StreamProxyItem streamProxyDto); |
| | | |
| | |
| | | "timeout_ms=#{timeout_ms}, " + |
| | | "ffmpeg_cmd_key=#{ffmpeg_cmd_key}, " + |
| | | "rtp_type=#{rtp_type}, " + |
| | | "enable_hls=#{enable_hls}, " + |
| | | "enable_audio=#{enable_audio}, " + |
| | | "enable=#{enable}, " + |
| | | "status=#{status}, " + |
| | | "enable_remove_none_reader=#{enable_remove_none_reader}, " + |
| | |
| | | package com.genersoft.iot.vmp.storager.impl; |
| | | |
| | | import com.genersoft.iot.vmp.common.StreamInfo; |
| | | import com.genersoft.iot.vmp.conf.SipConfig; |
| | | import com.genersoft.iot.vmp.conf.UserSetting; |
| | | import com.genersoft.iot.vmp.gb28181.bean.*; |
| | | import com.genersoft.iot.vmp.gb28181.event.EventPublisher; |
| | | import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.genersoft.iot.vmp.service.bean.GPSMsgInfo; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.ObjectUtils; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | |
| | | return gbStreamMapper.updateStreamGPS(gpsMsgInfos); |
| | | } |
| | | |
| | | private List<DeviceChannel> getDeviceChannelListByChannelReduceList(List<ChannelReduce> channelReduces, String catalogId) { |
| | | List<DeviceChannel> deviceChannelList = new ArrayList<>(); |
| | | if (channelReduces.size() > 0){ |
| | | for (ChannelReduce channelReduce : channelReduces) { |
| | | DeviceChannel deviceChannel = queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId()); |
| | | deviceChannel.setParental(1); |
| | | deviceChannel.setParentId(catalogId); |
| | | deviceChannelList.add(deviceChannel); |
| | | } |
| | | } |
| | | return deviceChannelList; |
| | | } |
| | | |
| | | private DeviceChannel getDeviceChannelByCatalog(PlatformCatalog catalog) { |
| | | ParentPlatform platform = platformMapper.getParentPlatByServerGBId(catalog.getPlatformId()); |
| | |
| | | package com.genersoft.iot.vmp.vmanager.gb28181.gbStream; |
| | | |
| | | import com.genersoft.iot.vmp.gb28181.bean.GbStream; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.vmanager.gb28181.gbStream.bean.GbStreamParam; |
| | | import com.genersoft.iot.vmp.service.IGbStreamService; |
| | | import com.github.pagehelper.PageInfo; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.util.ObjectUtils; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Tag(name = "视频流关联到级联平台") |
| | | @CrossOrigin |
| | |
| | | @Operation(summary = "移除国标关联") |
| | | @DeleteMapping(value = "/del") |
| | | @ResponseBody |
| | | public Object del(@RequestBody GbStreamParam gbStreamParam){ |
| | | if (gbStreamService.delPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getGbStreams())) { |
| | | return "success"; |
| | | public void del(@RequestBody GbStreamParam gbStreamParam){ |
| | | |
| | | if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) { |
| | | if (gbStreamParam.isAll()) { |
| | | gbStreamService.delAllPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); |
| | | } |
| | | }else { |
| | | return "fail"; |
| | | gbStreamService.delPlatformInfo(gbStreamParam.getPlatformId(), gbStreamParam.getGbStreams()); |
| | | } |
| | | |
| | | } |
| | |
| | | @Operation(summary = "保存国标关联") |
| | | @PostMapping(value = "/add") |
| | | @ResponseBody |
| | | public Object add(@RequestBody GbStreamParam gbStreamParam){ |
| | | if (gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId())) { |
| | | return "success"; |
| | | public void add(@RequestBody GbStreamParam gbStreamParam){ |
| | | if (gbStreamParam.getGbStreams() == null || gbStreamParam.getGbStreams().size() == 0) { |
| | | if (gbStreamParam.isAll()) { |
| | | List<GbStream> allGBChannels = gbStreamService.getAllGBChannels(gbStreamParam.getPlatformId()); |
| | | gbStreamService.addPlatformInfo(allGBChannels, gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); |
| | | } |
| | | }else { |
| | | return "fail"; |
| | | gbStreamService.addPlatformInfo(gbStreamParam.getGbStreams(), gbStreamParam.getPlatformId(), gbStreamParam.getCatalogId()); |
| | | } |
| | | } |
| | | } |
| | |
| | | @Schema(description = "目录ID") |
| | | private String catalogId; |
| | | |
| | | @Schema(description = "关联所有通道") |
| | | private boolean all; |
| | | |
| | | @Schema(description = "流国标信息列表") |
| | | private List<GbStream> gbStreams; |
| | | |
| | |
| | | public void setGbStreams(List<GbStream> gbStreams) { |
| | | this.gbStreams = gbStreams; |
| | | } |
| | | |
| | | public boolean isAll() { |
| | | return all; |
| | | } |
| | | |
| | | public void setAll(boolean all) { |
| | | this.all = all; |
| | | } |
| | | } |
| | |
| | | import com.genersoft.iot.vmp.gb28181.bean.PlatformCatalog; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SubscribeHolder; |
| | | import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; |
| | | import com.genersoft.iot.vmp.service.IPlatformChannelService; |
| | | import com.genersoft.iot.vmp.service.IPlatformService; |
| | | import com.genersoft.iot.vmp.service.*; |
| | | import com.genersoft.iot.vmp.storager.IRedisCatchStorage; |
| | | import com.genersoft.iot.vmp.storager.IVideoManagerStorage; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | |
| | | |
| | | @Autowired |
| | | private IPlatformService platformService; |
| | | |
| | | @Autowired |
| | | private IDeviceChannelService deviceChannelService; |
| | | |
| | | @Autowired |
| | | private IGbStreamService gbStreamService; |
| | | |
| | | /** |
| | | * 获取国标服务的配置 |
| | |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("给上级平台添加国标通道API调用"); |
| | | } |
| | | int result = platformChannelService.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId()); |
| | | int result = 0; |
| | | if (param.getChannelReduces() == null || param.getChannelReduces().size() == 0) { |
| | | if (param.isAll()) { |
| | | logger.info("[国标级联]添加所有通道到上级平台, {}", param.getPlatformId()); |
| | | List<ChannelReduce> allChannelForDevice = deviceChannelService.queryAllChannelList(param.getPlatformId()); |
| | | result = platformChannelService.updateChannelForGB(param.getPlatformId(), allChannelForDevice, param.getCatalogId()); |
| | | } |
| | | }else { |
| | | result = platformChannelService.updateChannelForGB(param.getPlatformId(), param.getChannelReduces(), param.getCatalogId()); |
| | | } |
| | | if (result <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | |
| | | if (logger.isDebugEnabled()) { |
| | | logger.debug("给上级平台删除国标通道API调用"); |
| | | } |
| | | int result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); |
| | | |
| | | int result = 0; |
| | | if (param.getChannelReduces() == null || param.getChannelReduces().size() == 0) { |
| | | if (param.isAll()) { |
| | | logger.info("[国标级联]移除所有通道,上级平台, {}", param.getPlatformId()); |
| | | result = platformChannelService.delAllChannelForGB(param.getPlatformId(), param.getCatalogId()); |
| | | } |
| | | }else { |
| | | result = storager.delChannelForGB(param.getPlatformId(), param.getChannelReduces()); |
| | | } |
| | | if (result <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | |
| | | @Schema(description = "目录的国标编号") |
| | | private String catalogId; |
| | | |
| | | @Schema(description = "处理所有通道") |
| | | private boolean all; |
| | | |
| | | @Schema(description = "") |
| | | private List<ChannelReduce> channelReduces; |
| | | |
| | |
| | | public void setCatalogId(String catalogId) { |
| | | this.catalogId = catalogId; |
| | | } |
| | | |
| | | public boolean isAll() { |
| | | return all; |
| | | } |
| | | |
| | | public void setAll(boolean all) { |
| | | this.all = all; |
| | | } |
| | | } |
| | |
| | | resultHolder.invokeResult(msg); |
| | | }); |
| | | |
| | | if (userSetting.isUsePushingAsStatus()) { |
| | | if (userSetting.getUseSourceIpAsStreamIp()) { |
| | | // TODO 在点播未成功的情况下在此调用接口点播会导致返回的流地址ip错误 |
| | | deferredResultEx.setFilter(result1 -> { |
| | | WVPResult<StreamInfo> wvpResult1 = (WVPResult<StreamInfo>)result1; |
| | |
| | | }); |
| | | } |
| | | |
| | | |
| | | // 录像查询以channelId作为deviceId查询 |
| | | resultHolder.put(key, uuid, deferredResultEx); |
| | | |
| | |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | |
| | | @Operation(summary = "停止点播") |
| | | @Parameter(name = "deviceId", description = "设备国标编号", required = true) |
| | |
| | | json.put("deviceId", deviceId); |
| | | json.put("channelId", channelId); |
| | | return json; |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | logger.info("启用代理: " + app + "/" + stream); |
| | | boolean result = streamProxyService.start(app, stream); |
| | | if (!result) { |
| | | logger.info("启用代理失败: " + app + "/" + stream); |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | |
| | | # 国标级联发流严格模式,严格模式会使用与sdp信息中一致的端口发流,端口共享media.rtp.port-range,这会损失一些性能, |
| | | # 非严格模式使用随机端口发流,性能更好, 默认关闭 |
| | | gb-send-stream-strict: false |
| | | # 设备上线时是否自动同步通道 |
| | | sync-channel-on-device-online: false |
| | | |
| | | # 关闭在线文档(生产环境建议关闭) |
| | | springdoc: |
| | |
| | | <el-table-column label="类型" width="100" > |
| | | <template slot-scope="scope"> |
| | | <div slot="reference" class="name-wrapper"> |
| | | <el-tag size="medium">{{scope.row.type}}</el-tag> |
| | | <el-tag size="medium">{{scope.row.type === "default"? "直接代理":"FFMPEG代理"}}</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="createTime" label="创建时间" min-width="150" show-overflow-tooltip/> |
| | | <el-table-column label="转HLS" min-width="120" > |
| | | <el-table-column label="音频" min-width="120" > |
| | | <template slot-scope="scope"> |
| | | <div slot="reference" class="name-wrapper"> |
| | | <el-tag size="medium" v-if="scope.row.enable_hls">已启用</el-tag> |
| | | <el-tag size="medium" type="info" v-if="!scope.row.enable_hls">未启用</el-tag> |
| | | <el-tag size="medium" v-if="scope.row.enable_audio">已启用</el-tag> |
| | | <el-tag size="medium" type="info" v-if="!scope.row.enable_audio">未启用</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="MP4录制" min-width="120" > |
| | | <el-table-column label="录制" min-width="120" > |
| | | <template slot-scope="scope"> |
| | | <div slot="reference" class="name-wrapper"> |
| | | <el-tag size="medium" v-if="scope.row.enable_mp4">已启用</el-tag> |
| | |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="无人观看自动删除" min-width="160" > |
| | | <el-table-column label="无人观看" min-width="160" > |
| | | <template slot-scope="scope"> |
| | | <div slot="reference" class="name-wrapper"> |
| | | <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">已启用</el-tag> |
| | | <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader">未启用</el-tag> |
| | | <el-tag size="medium" v-if="scope.row.enable_remove_none_reader">移除</el-tag> |
| | | <el-tag size="medium" v-if="scope.row.enable_disable_none_reader">停用</el-tag> |
| | | <el-tag size="medium" type="info" v-if="!scope.row.enable_remove_none_reader && !scope.row.enable_disable_none_reader">不做处理</el-tag> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | currentPage:1, |
| | | count:15, |
| | | total:0, |
| | | getListLoading: false, |
| | | startBtnLoading: false |
| | | }; |
| | | }, |
| | |
| | | }, |
| | | mounted() { |
| | | this.initData(); |
| | | this.updateLooper = setInterval(this.initData, 1000); |
| | | this.startUpdateList() |
| | | }, |
| | | destroyed() { |
| | | this.$destroy('videojs'); |
| | |
| | | initData: function() { |
| | | this.getStreamProxyList(); |
| | | }, |
| | | stopUpdateList: function (){ |
| | | window.clearInterval(this.updateLooper) |
| | | }, |
| | | startUpdateList: function (){ |
| | | this.updateLooper = setInterval(this.initData, 1000); |
| | | }, |
| | | currentChange: function(val){ |
| | | this.currentPage = val; |
| | | this.getStreamProxyList(); |
| | |
| | | }, |
| | | getStreamProxyList: function() { |
| | | let that = this; |
| | | this.getListLoading = true; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:`/api/proxy/list`, |
| | |
| | | } |
| | | that.streamProxyList = res.data.data.list; |
| | | } |
| | | that.getListLoading = false; |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | | }); |
| | | }, |
| | | addStreamProxy: function(){ |
| | | this.$refs.streamProxyEdit.openDialog(null, this.initData) |
| | | }, |
| | | addOnvif: function(){ |
| | | this.getListLoading = true; |
| | | this.getListLoading = true; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:`/api/onvif/search?timeout=3000`, |
| | | }).then((res) =>{ |
| | | this.getListLoading = false; |
| | | if (res.data.code === 0 ){ |
| | | if (res.data.data.length > 0) { |
| | | this.$refs.onvifEdit.openDialog(res.data.data, (url)=>{ |
| | |
| | | } |
| | | |
| | | }).catch((error)=> { |
| | | this.getListLoading = false; |
| | | this.$message.error(error.response.data.msg); |
| | | }); |
| | | |
| | |
| | | }, |
| | | play: function(row){ |
| | | let that = this; |
| | | this.getListLoading = true; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:`/api/push/getPlayUrl`, |
| | |
| | | mediaServerId: row.mediaServerId |
| | | } |
| | | }).then(function (res) { |
| | | that.getListLoading = false; |
| | | if (res.data.code === 0) { |
| | | that.$refs.devicePlayer.openDialog("streamPlay", null, null, { |
| | | streamInfo: res.data.data, |
| | |
| | | |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | | }); |
| | | |
| | | }, |
| | | deleteStreamProxy: function(row){ |
| | | let that = this; |
| | | this.getListLoading = true; |
| | | that.$axios({ |
| | | method:"delete", |
| | | url:"/api/proxy/del", |
| | |
| | | stream: row.stream |
| | | } |
| | | }).then((res)=>{ |
| | | that.getListLoading = false; |
| | | that.initData() |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | | }); |
| | | }, |
| | | start: function(row){ |
| | | let that = this; |
| | | this.getListLoading = true; |
| | | this.stopUpdateList() |
| | | this.$set(row, 'startBtnLoading', true) |
| | | this.$axios({ |
| | | method: 'get', |
| | |
| | | app: row.app, |
| | | stream: row.stream |
| | | } |
| | | }).then(function (res) { |
| | | that.getListLoading = false; |
| | | that.$set(row, 'startBtnLoading', false) |
| | | }).then((res)=> { |
| | | if (res.data.code === 0){ |
| | | that.initData() |
| | | this.initData() |
| | | }else { |
| | | that.$message({ |
| | | this.$message({ |
| | | showClose: true, |
| | | message: "保存失败,请检查地址是否可用!", |
| | | message: "启动失败,请检查地址是否可用!", |
| | | type: "error", |
| | | }); |
| | | } |
| | | |
| | | }).catch(function (error) { |
| | | this.$set(row, 'startBtnLoading', false) |
| | | this.startUpdateList() |
| | | }).catch((error)=> { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | | that.$set(row, 'startBtnLoading', false) |
| | | this.$message({ |
| | | showClose: true, |
| | | message: "启动失败,请检查地址是否可用!", |
| | | type: "error", |
| | | }); |
| | | this.$set(row, 'startBtnLoading', false) |
| | | this.startUpdateList() |
| | | }); |
| | | }, |
| | | stop: function(row){ |
| | | let that = this; |
| | | this.getListLoading = true; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url:`/api/proxy/stop`, |
| | |
| | | stream: row.stream |
| | | } |
| | | }).then(function (res) { |
| | | that.getListLoading = false; |
| | | that.initData() |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | that.getListLoading = false; |
| | | }); |
| | | }, |
| | | refresh: function (){ |
| | |
| | | <el-option label="组播" value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="国标平台"> |
| | | <el-select |
| | | v-model="proxyParam.platformGbId" |
| | | style="width: 100%" |
| | | placeholder="请选择国标平台" |
| | | > |
| | | <el-option |
| | | v-for="item in platformList" |
| | | :key="item.name" |
| | | :label="item.name" |
| | | :value="item.serverGBId"> |
| | | <span style="float: left">{{ item.name }}</span> |
| | | <span style="float: right; color: #8492a6; font-size: 13px">{{ item.serverGBId }}</span> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="无人观看" prop="rtp_type" > |
| | | <el-select |
| | | @change="noneReaderHandler" |
| | | v-model="proxyParam.none_reader" |
| | | style="width: 100%" |
| | | placeholder="请选择无人观看的处理方式" |
| | | > |
| | | <el-option label="不做处理" value="0"></el-option> |
| | | <el-option label="停用" value="1"></el-option> |
| | | <el-option label="移除" value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="其他选项"> |
| | | <div style="float: left;"> |
| | | <el-checkbox label="启用" v-model="proxyParam.enable" ></el-checkbox> |
| | | <el-checkbox label="转HLS" v-model="proxyParam.enable_hls" ></el-checkbox> |
| | | <el-checkbox label="MP4录制" v-model="proxyParam.enable_mp4" ></el-checkbox> |
| | | <el-checkbox label="无人观看自动删除" v-model="proxyParam.enable_remove_none_reader" @change="removeNoneReader"></el-checkbox> |
| | | <el-checkbox label="无人观看停止拉流" v-model="proxyParam.enable_disable_none_reader" @change="disableNoneReaderHandType"></el-checkbox> |
| | | |
| | | <el-checkbox label="开启音频" v-model="proxyParam.enable_audio" ></el-checkbox> |
| | | <el-checkbox label="录制" v-model="proxyParam.enable_mp4" ></el-checkbox> |
| | | </div> |
| | | |
| | | </el-form-item> |
| | |
| | | gbId: null, |
| | | rtp_type: null, |
| | | enable: true, |
| | | enable_hls: true, |
| | | enable_audio: true, |
| | | enable_mp4: false, |
| | | none_reader: null, |
| | | enable_remove_none_reader: false, |
| | | enable_disable_none_reader: true, |
| | | enable_disable_none_reader: false, |
| | | platformGbId: null, |
| | | mediaServerId: null, |
| | | }, |
| | |
| | | this.listChangeCallback = callback; |
| | | if (proxyParam != null) { |
| | | this.proxyParam = proxyParam; |
| | | this.proxyParam.none_reader = null; |
| | | } |
| | | |
| | | let that = this; |
| | |
| | | }, |
| | | onSubmit: function () { |
| | | this.dialogLoading = true; |
| | | var that = this; |
| | | that.$axios({ |
| | | this.noneReaderHandler(); |
| | | this.$axios({ |
| | | method: 'post', |
| | | url:`/api/proxy/save`, |
| | | data: that.proxyParam |
| | | }).then(function (res) { |
| | | that.dialogLoading = false; |
| | | data: this.proxyParam |
| | | }).then((res)=> { |
| | | this.dialogLoading = false; |
| | | if (typeof (res.data.code) != "undefined" && res.data.code === 0) { |
| | | that.$message({ |
| | | this.$message({ |
| | | showClose: true, |
| | | message: res.data.msg, |
| | | type: "success", |
| | | }); |
| | | that.showDialog = false; |
| | | if (that.listChangeCallback != null) { |
| | | that.listChangeCallback(); |
| | | that.dialogLoading = false; |
| | | this.showDialog = false; |
| | | if (this.listChangeCallback != null) { |
| | | this.listChangeCallback(); |
| | | this.dialogLoading = false; |
| | | } |
| | | } |
| | | }).catch(function (error) { |
| | | }).catch((error) =>{ |
| | | console.log(error); |
| | | this.dialogLoading = false; |
| | | }); |
| | |
| | | this.platform.expires = "300"; |
| | | } |
| | | }, |
| | | removeNoneReader: function(checked) { |
| | | this.proxyParam.enable_disable_none_reader = !checked; |
| | | noneReaderHandler: function() { |
| | | if (this.proxyParam.none_reader === null || this.proxyParam.none_reader === "0") { |
| | | this.proxyParam.enable_disable_none_reader = false; |
| | | this.proxyParam.enable_remove_none_reader = false; |
| | | }else if (this.proxyParam.none_reader === "1"){ |
| | | this.proxyParam.enable_disable_none_reader = true; |
| | | this.proxyParam.enable_remove_none_reader = false; |
| | | }else if (this.proxyParam.none_reader ==="2"){ |
| | | this.proxyParam.enable_disable_none_reader = false; |
| | | this.proxyParam.enable_remove_none_reader = true; |
| | | } |
| | | }, |
| | | disableNoneReaderHandType: function(checked) { |
| | | this.proxyParam.enable_remove_none_reader = !checked; |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | |
| | | } |
| | | |
| | | if (res.data.data != null) { |
| | | if (res.data.syncIng) { |
| | | if (res.data.data.syncIng) { |
| | | if (res.data.data.total == 0) { |
| | | if (res.data.data.errorMsg !== null ){ |
| | | this.msg = res.data.data.errorMsg; |
| | | this.syncStatus = "exception" |
| | | }else { |
| | | this.msg = `等待同步中`; |
| | | this.timmer = setTimeout(this.getProgress, 300) |
| | | } |
| | | }else { |
| | | if (res.data.data.total == res.data.data.current) { |
| | | this.syncStatus = "success" |
| | | this.percentage = 100; |
| | | this.msg = '同步成功'; |
| | | }else { |
| | | if (res.data.data.errorMsg !== null ){ |
| | | this.msg = res.data.data.errorMsg; |
| | | this.syncStatus = "exception" |
| | | }else { |
| | | this.total = res.data.data.total; |
| | | this.current = res.data.data.current; |
| | | this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100; |
| | | this.msg = `同步中...[${res.data.data.current}/${res.data.data.total}]`; |
| | | this.timmer = setTimeout(this.getProgress, 300) |
| | | } |
| | | } |
| | | this.msg = `等待同步中`; |
| | | this.timmer = setTimeout(this.getProgress, 300) |
| | | }else { |
| | | this.total = res.data.data.total; |
| | | this.current = res.data.data.current; |
| | | this.percentage = Math.floor(Number(res.data.data.current)/Number(res.data.data.total)* 10000)/100; |
| | | this.msg = `同步中...[${res.data.data.current}/${res.data.data.total}]`; |
| | | this.timmer = setTimeout(this.getProgress, 300) |
| | | } |
| | | }else { |
| | | this.syncStatus = "success" |
| | | this.percentage = 100; |
| | | this.msg = '同步成功'; |
| | | if (res.data.data.errorMsg){ |
| | | this.msg = res.data.data.errorMsg; |
| | | this.syncStatus = "exception" |
| | | }else { |
| | | this.syncStatus = "success" |
| | | this.percentage = 100; |
| | | this.msg = '同步成功'; |
| | | setTimeout(()=>{ |
| | | this.showDialog = false; |
| | | }, 3000) |
| | | } |
| | | } |
| | | } |
| | | }else { |
| | |
| | | <el-option label="在线" value="true"></el-option> |
| | | <el-option label="离线" value="false"></el-option> |
| | | </el-select> |
| | | <el-button v-if="catalogId !== null" icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button> |
| | | <el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" @click="batchAdd">批量添加</el-button> |
| | | <el-button v-if="catalogId !== null" icon="el-icon-delete" size="mini" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button> |
| | | <el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" :disabled="gbChannels.length === 0 || multipleSelection.length === 0" @click="batchAdd">批量添加</el-button> |
| | | <el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" @click="add()">全部添加</el-button> |
| | | <el-button v-if="catalogId !== null" type="danger" icon="el-icon-delete" size="mini" @click="remove()">全部移除</el-button> |
| | | </div> |
| | | |
| | | <el-table ref="gbChannelsTable" :data="gbChannels" border style="width: 100%" :height="winHeight" :row-key="(row)=> row.deviceId + row.channelId" @selection-change="handleSelectionChange"> |
| | |
| | | this.initData(); |
| | | }, |
| | | add: function (row) { |
| | | let all = typeof(row) === "undefined" |
| | | this.getCatalogFromUser((catalogId)=> { |
| | | this.$axios({ |
| | | method:"post", |
| | | url:"/api/platform/update_channel_for_gb", |
| | | data:{ |
| | | platformId: this.platformId, |
| | | channelReduces: [row], |
| | | all: all, |
| | | channelReduces: all?[]:[row], |
| | | catalogId: catalogId |
| | | } |
| | | }).then((res)=>{ |
| | |
| | | |
| | | }, |
| | | remove: function (row) { |
| | | console.log(row) |
| | | let all = typeof(row) === "undefined" |
| | | this.$confirm(`确定移除${all?"所有通道":""}吗?`, '提示', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | console.log(row) |
| | | |
| | | this.$axios({ |
| | | method:"delete", |
| | | url:"/api/platform/del_channel_for_gb", |
| | | data:{ |
| | | platformId: this.platformId, |
| | | channelReduces: [row] |
| | | } |
| | | }).then((res)=>{ |
| | | console.log("移除成功") |
| | | this.getChannelList(); |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | this.$axios({ |
| | | method:"delete", |
| | | url:"/api/platform/del_channel_for_gb", |
| | | data:{ |
| | | platformId: this.platformId, |
| | | all: all, |
| | | channelReduces: all?[]:[row], |
| | | } |
| | | }).then((res)=>{ |
| | | console.log("移除成功") |
| | | this.getChannelList(); |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }).catch(() => { |
| | | |
| | | }); |
| | | |
| | | |
| | | }, |
| | | // checkedChange: function (val) { |
| | | // let that = this; |
| | |
| | | </el-select> |
| | | <el-button v-if="catalogId !== null" icon="el-icon-delete" size="mini" style="margin-right: 1rem;" :disabled="gbStreams.length === 0 || multipleSelection.length === 0" type="danger" @click="batchDel">批量移除</el-button> |
| | | <el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" :disabled="gbStreams.length === 0 || multipleSelection.length === 0" @click="batchAdd">批量添加</el-button> |
| | | <el-button v-if="catalogId === null" icon="el-icon-plus" size="mini" style="margin-right: 1rem;" @click="add()">全部添加</el-button> |
| | | <el-button v-if="catalogId !== null" type="danger" icon="el-icon-delete" size="mini" style="margin-right: 1rem;" @click="remove()">全部移除</el-button> |
| | | </div> |
| | | <el-table ref="gbStreamsTable" :data="gbStreams" border style="width: 100%" :height="winHeight" :row-key="(row)=> row.app + row.stream" @selection-change="handleSelectionChange"> |
| | | <el-table-column align="center" type="selection" :reserve-selection="true" width="55"> |
| | |
| | | |
| | | }, |
| | | add: function (row, scope) { |
| | | let all = typeof(row) === "undefined" |
| | | this.getCatalogFromUser((catalogId)=>{ |
| | | this.$axios({ |
| | | method:"post", |
| | |
| | | data:{ |
| | | platformId: this.platformId, |
| | | catalogId: catalogId, |
| | | gbStreams: [row], |
| | | all: all, |
| | | gbStreams: all?[]:[row], |
| | | } |
| | | }).then((res)=>{ |
| | | console.log("保存成功") |
| | |
| | | |
| | | }, |
| | | remove: function (row, scope) { |
| | | this.$axios({ |
| | | method:"delete", |
| | | url:"/api/gbStream/del", |
| | | data:{ |
| | | platformId: this.platformId, |
| | | gbStreams: [row], |
| | | } |
| | | }).then((res)=>{ |
| | | console.log("移除成功") |
| | | // this.gbStreams.splice(scope.$index,1) |
| | | this.getChannelList(); |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | let all = typeof(row) === "undefined" |
| | | this.$confirm(`确定移除${all?"所有通道":""}吗?`, '提示', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | |
| | | this.$axios({ |
| | | method:"delete", |
| | | url:"/api/gbStream/del", |
| | | data:{ |
| | | platformId: this.platformId, |
| | | all: all, |
| | | gbStreams: all?[]:[row], |
| | | } |
| | | }).then((res)=>{ |
| | | console.log("移除成功") |
| | | // this.gbStreams.splice(scope.$index,1) |
| | | this.getChannelList(); |
| | | }).catch(function (error) { |
| | | console.log(error); |
| | | }); |
| | | }).catch(() => { |
| | | |
| | | }); |
| | | |
| | | }, |
| | | getChannelList: function () { |
| | | let that = this; |