| | |
| | | /** |
| | | * ç»å½ID |
| | | */ |
| | | private Integer loginId; |
| | | private Long loginId; |
| | | /** |
| | | * å¨çº¿ç¶æ 0-离线 1-å¨çº¿ |
| | | */ |
| | |
| | | /** |
| | | * èµ·å§ééå· |
| | | */ |
| | | private Integer startDChan; |
| | | private Integer startChan; |
| | | /** |
| | | * ééæ° |
| | | */ |
| | |
| | | import com.ruoyi.device.camera.domain.ArdCameras; |
| | | import com.ruoyi.device.camera.domain.CameraCmd; |
| | | import com.ruoyi.device.channel.domain.ArdChannel; |
| | | import com.ruoyi.media.domain.Vtdu; |
| | | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.List; |
| | |
| | | |
| | | //æ¬å°å½å忢 |
| | | AjaxResult localRecordStop(CameraCmd cmd); |
| | | |
| | | } |
| | |
| | | package com.ruoyi.device.channel.service; |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.ruoyi.device.camera.domain.ArdCameras; |
| | | import com.ruoyi.device.channel.domain.ArdChannel; |
| | | |
| | | /** |
| | |
| | | * @return ç»æ |
| | | */ |
| | | public int deleteArdChannelByDeviceId(String deviceId); |
| | | /** |
| | | * @Author åèä¹ |
| | | * @Description è·å2个ééå表ç交é |
| | | * @Date 2024/7/10 9:38 |
| | | * @Param |
| | | * @return |
| | | */ |
| | | public List<ArdChannel> sameList(List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList); |
| | | /** |
| | | * @Author åèä¹ |
| | | * @Description å2个ééå表çå·®é |
| | | * @Date 2024/7/10 9:39 |
| | | * @Param |
| | | * @return |
| | | */ |
| | | public List<ArdChannel> diffList(List<ArdChannel> firstArrayList, List<ArdChannel> secondArrayList); |
| | | |
| | | /** |
| | | * @Author åèä¹ |
| | |
| | | * @Param |
| | | * @return |
| | | */ |
| | | public void asyncChannel(List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList); |
| | | public void asyncChannel(ArdCameras ardCameras, List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList); |
| | | } |
| | |
| | | package com.ruoyi.device.channel.service.impl; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import com.ruoyi.common.utils.uuid.IdUtils; |
| | | import com.ruoyi.device.camera.domain.ArdCameras; |
| | | import com.ruoyi.device.camera.factory.CameraSDK; |
| | | import com.ruoyi.device.camera.factory.CameraSDKFactory; |
| | | import com.ruoyi.device.camera.mapper.ArdCamerasMapper; |
| | | import com.ruoyi.media.mapper.VtduMapper; |
| | | import com.ruoyi.media.service.IVtduService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.ruoyi.device.channel.mapper.ArdChannelMapper; |
| | |
| | | public class ArdChannelServiceImpl implements IArdChannelService { |
| | | @Resource |
| | | private ArdChannelMapper ardChannelMapper; |
| | | |
| | | @Resource |
| | | private CameraSDKFactory cameraSDKFactory; |
| | | @Resource |
| | | private IVtduService vtduService; |
| | | /** |
| | | * æ¥è¯¢éé管ç |
| | | * |
| | |
| | | return ardChannelMapper.deleteArdChannelByDeviceId(deviceId); |
| | | } |
| | | |
| | | //æ±ä¸¤ä¸ªå¯¹è±¡Listç交é |
| | | @Override |
| | | public List<ArdChannel> sameList(List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList) { |
| | | List<ArdChannel> resultList = newArrayList.stream() |
| | | .filter(item -> oldArrayList.stream().map(e -> e.getChanNo()) |
| | | .collect(Collectors.toList()).contains(item.getChanNo())) |
| | | .collect(Collectors.toList()); |
| | | return resultList; |
| | | } |
| | | public void asyncChannel(ArdCameras ardCameras,List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList) { |
| | | // å°å表转æ¢ä¸ºæ å°ä»¥æé«æ§è½ |
| | | Map<Integer, ArdChannel> oldMap = oldArrayList.stream() |
| | | .collect(Collectors.toMap(ArdChannel::getChanNo, channel -> channel)); |
| | | Map<Integer, ArdChannel> newMap = newArrayList.stream() |
| | | .collect(Collectors.toMap(ArdChannel::getChanNo, channel -> channel)); |
| | | |
| | | //æ±ä¸¤ä¸ªå¯¹è±¡Listçå·®é |
| | | @Override |
| | | public List<ArdChannel> diffList(List<ArdChannel> firstArrayList, List<ArdChannel> secondArrayList) { |
| | | List<ArdChannel> resultList = firstArrayList.stream() |
| | | .filter(item -> !secondArrayList.stream().map(e -> e.getChanNo()).collect(Collectors.toList()).contains(item.getChanNo())) |
| | | .collect(Collectors.toList()); |
| | | return resultList; |
| | | } |
| | | // éè¦æ´æ°çæ°æ® |
| | | newArrayList.stream() |
| | | .filter(channel -> { |
| | | ArdChannel oldChannel = oldMap.get(channel.getChanNo()); |
| | | return oldChannel != null && !oldChannel.getName().equals(channel.getName()); |
| | | }) |
| | | .forEach(channel -> { |
| | | ArdChannel oldChannel = oldMap.get(channel.getChanNo()); |
| | | channel.setId(oldChannel.getId()); |
| | | updateArdChannel(channel); |
| | | }); |
| | | |
| | | @Override |
| | | public void asyncChannel(List<ArdChannel> oldArrayList, List<ArdChannel> newArrayList) { |
| | | //éè¦æ´æ°çæ°æ®,åæ°é¡ºåºæ³¨æ |
| | | sameList(oldArrayList, newArrayList).stream().forEach(ardChannel -> { |
| | | updateArdChannel(ardChannel); |
| | | }); |
| | | //éè¦å é¤çæ°æ® |
| | | diffList(oldArrayList, newArrayList).stream().forEach(ardChannel -> { |
| | | deleteArdChannelById(ardChannel.getId()); |
| | | }); |
| | | //éè¦æ°å¢çæ°æ® |
| | | diffList(newArrayList, oldArrayList).stream().forEach(ardChannel -> { |
| | | insertArdChannel(ardChannel); |
| | | }); |
| | | // éè¦å é¤çæ°æ® |
| | | oldArrayList.stream() |
| | | .filter(channel -> !newMap.containsKey(channel.getChanNo())) |
| | | .forEach(channel -> { |
| | | deleteArdChannelById(channel.getId()); |
| | | vtduService.deleteVtduByName(channel.getDeviceId() + "_" + channel.getChanNo()); |
| | | }); |
| | | |
| | | // éè¦æ°å¢çæ°æ® |
| | | newArrayList.stream() |
| | | .filter(channel -> !oldMap.containsKey(channel.getChanNo())) |
| | | .forEach(channel -> { |
| | | insertArdChannel(channel); |
| | | vtduService.addChanToVtdu(ardCameras, channel); |
| | | }); |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.common.annotation.Anonymous;
|
| | | import com.ruoyi.common.core.controller.BaseController;
|
| | | import com.ruoyi.common.core.domain.AjaxResult;
|
| | | import com.ruoyi.common.core.domain.BaseEntity;
|
| | | import com.ruoyi.common.core.page.TableDataInfo;
|
| | | import com.ruoyi.common.utils.StringUtils;
|
| | | import com.ruoyi.common.utils.uuid.IdUtils;
|
| | | import com.ruoyi.media.domain.Config;
|
| | | import com.ruoyi.media.domain.Paths;
|
| | | import com.ruoyi.media.domain.StreamInfo;
|
| | | import com.ruoyi.media.domain.Vtdu;
|
| | | import com.ruoyi.media.service.IMediaService;
|
| | |
| | | @PreAuthorize("@ss.hasPermi('media:stream:remove')")
|
| | | @DeleteMapping("/{sessionId}")
|
| | | public AjaxResult removePullStreamSession(@PathVariable String sessionId) {
|
| | | List<StreamInfo> pullStreamList = mediaService.getPullStreamList();
|
| | | List<StreamInfo> pullStreamList = mediaService.getPullStreamList(1,1000);
|
| | | StreamInfo streamInfo = pullStreamList.stream()
|
| | | .filter(object -> object.getId().equals(sessionId))
|
| | | .collect(Collectors.toList()).get(0);
|
| | |
| | | @GetMapping("/path/list")
|
| | | @ApiOperation("è·åå½åééå表")
|
| | | @ApiOperationSupport(order = 5)
|
| | | public TableDataInfo getPaths() {
|
| | | public TableDataInfo getPaths(Integer pageNum,Integer pageSize) {
|
| | | startPage();
|
| | | return getDataTable(mediaService.paths());
|
| | | return getDataTable(mediaService.paths(pageNum,pageSize));
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | @GetMapping("/getRtspSessionById")
|
| | | @ApiOperation("æIDæ¥è¯¢ææµè¯¦æ
")
|
| | | public AjaxResult getRtspSessionById(String sessionId) {
|
| | | List<StreamInfo> pullStreamList = mediaService.getPullStreamList();
|
| | | List<StreamInfo> pullStreamList = mediaService.getPullStreamList(1,1000);
|
| | | StreamInfo streamInfo = pullStreamList.stream()
|
| | | .filter(object -> object.getId().equals(sessionId))
|
| | | .collect(Collectors.toList()).get(0);
|
| | |
| | | @GetMapping("/pushList")
|
| | | @ApiOperation("è·åæ¨æµå表")
|
| | | @ApiOperationSupport(order = 6)
|
| | | public TableDataInfo getPushStreamList() {
|
| | | public TableDataInfo getPushStreamList(Integer pageNum,Integer pageSize) {
|
| | | startPage();
|
| | | return getDataTable(mediaService.getPushStreamList());
|
| | | return getDataTable(mediaService.getPushStreamList(pageNum,pageSize));
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | @GetMapping("/pullList")
|
| | | @ApiOperation("è·åææµå表")
|
| | | @ApiOperationSupport(order = 7)
|
| | | public TableDataInfo getPullStreamList() {
|
| | | public TableDataInfo getPullStreamList(Integer pageNum,Integer pageSize) {
|
| | | startPage();
|
| | | return getDataTable(mediaService.getPullStreamList());
|
| | | return getDataTable(mediaService.getPullStreamList(pageNum,pageSize));
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | |
| | | void removePath(String name); |
| | | |
| | | List<StreamInfo> paths(); |
| | | List<StreamInfo> paths(Integer pageNum,Integer pageSize); |
| | | |
| | | List<String> getNameList(); |
| | | |
| | |
| | | |
| | | RtmpSession getRtmpSessionById(String sessionId); |
| | | |
| | | List<StreamInfo> getPushStreamList(); |
| | | List<StreamInfo> getPushStreamList(Integer pageNum,Integer pageSize); |
| | | |
| | | List<StreamInfo> getPullStreamList(); |
| | | List<StreamInfo> getPullStreamList(Integer pageNum,Integer pageSize); |
| | | |
| | | Boolean kickRtspSession(String sessionId); |
| | | |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | import com.ruoyi.device.camera.domain.ArdCameras; |
| | | import com.ruoyi.device.channel.domain.ArdChannel; |
| | | import com.ruoyi.media.domain.Vtdu; |
| | | |
| | |
| | | * @Param |
| | | */ |
| | | public void asyncVtdu(List<Vtdu> vtdus, List<String> names); |
| | | |
| | | //æ·»å ééè³æµåªä½ |
| | | void addChanToVtdu(ArdCameras camera, ArdChannel channel); |
| | | } |
| | |
| | | import com.ruoyi.media.service.IMediaService; |
| | | import com.ruoyi.utils.forest.MediaClient; |
| | | import com.ruoyi.utils.tools.ArdTool; |
| | | import io.swagger.models.auth.In; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.boot.ApplicationArguments; |
| | |
| | | if (StringUtils.isNotEmpty(conf.getRunOnDemand())) { |
| | | runOn = conf.getRunOnDemand(); |
| | | info.setMode("0"); |
| | | } else { |
| | | info.setMode("1"); |
| | | } |
| | | //RTSPæºå°å |
| | | Matcher matcher = Pattern.compile("rtsp://[^\\s\"]+").matcher(runOn); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<StreamInfo> paths() { |
| | | Paths paths = mediaClient.paths(); |
| | | public List<StreamInfo> paths(Integer pageNum, Integer pageSize) { |
| | | Paths paths = mediaClient.paths(pageNum - 1, pageSize); |
| | | List<Items> items = paths.getItems(); |
| | | List<StreamInfo> pathInfoList = new ArrayList<>(); |
| | | for (Items item : items) { |
| | |
| | | |
| | | @Override |
| | | public RtspSession getRtspSessionById(String sessionId) { |
| | | String list = mediaClient.getRtspsessionById(sessionId); |
| | | RtspSession rtspSession = JSONObject.parseObject(list, RtspSession.class); |
| | | return rtspSession; |
| | | return mediaClient.getRtspsessionById(sessionId); |
| | | } |
| | | |
| | | @Override |
| | | public WebrtcSession getWebrtcSessionById(String sessionId) { |
| | | String list = mediaClient.getWebrtcsessionById(sessionId); |
| | | WebrtcSession webrtcSession = JSONObject.parseObject(list, WebrtcSession.class); |
| | | return webrtcSession; |
| | | return mediaClient.getWebrtcsessionById(sessionId); |
| | | } |
| | | |
| | | @Override |
| | | public RtmpSession getRtmpSessionById(String sessionId) { |
| | | String list = mediaClient.getRtmpsessionById(sessionId); |
| | | RtmpSession rtmpSession = JSONObject.parseObject(list, RtmpSession.class); |
| | | return rtmpSession; |
| | | return mediaClient.getRtmpsessionById(sessionId); |
| | | } |
| | | |
| | | /** |
| | |
| | | * 2023/8/29 9:37:05 |
| | | */ |
| | | @Override |
| | | public List<StreamInfo> getPushStreamList() { |
| | | public List<StreamInfo> getPushStreamList(Integer pageNum, Integer pageSize) { |
| | | List<StreamInfo> PushStreamInfoList = new ArrayList<>(); |
| | | Paths paths = mediaClient.paths(); |
| | | Paths paths = mediaClient.paths(pageNum - 1, pageSize); |
| | | List<Items> items = paths.getItems(); |
| | | for (Items item : items) { |
| | | StreamInfo info = new StreamInfo(); |
| | |
| | | * 2023/8/29 9:37:05 |
| | | */ |
| | | @Override |
| | | public List<StreamInfo> getPullStreamList() { |
| | | public List<StreamInfo> getPullStreamList(Integer pageNum, Integer pageSize) { |
| | | List<StreamInfo> PullStreamInfoList = new ArrayList<>(); |
| | | Paths paths = mediaClient.paths(); |
| | | Paths paths = mediaClient.paths(pageNum - 1, pageSize); |
| | | List<Items> items = paths.getItems(); |
| | | for (Items item : items) { |
| | | List<Readers> readers = item.getReaders(); |
| | |
| | | public List<String> getNameList() { |
| | | List<String> nameList = new ArrayList<>(); |
| | | try { |
| | | Paths paths = mediaClient.paths(); |
| | | Paths paths = mediaClient.paths(0, 1000); |
| | | List<Items> items = paths.getItems(); |
| | | for (Items item : items) { |
| | | nameList.add(item.getName()); |
| | |
| | | import java.util.stream.Collectors;
|
| | |
|
| | | import com.ruoyi.common.utils.DateUtils;
|
| | | import com.ruoyi.device.camera.domain.ArdCameras;
|
| | | import com.ruoyi.device.camera.domain.CameraCmd;
|
| | | import com.ruoyi.device.camera.factory.CameraSDK;
|
| | | import com.ruoyi.device.camera.factory.CameraSDKFactory;
|
| | | import com.ruoyi.device.channel.domain.ArdChannel;
|
| | | import com.ruoyi.media.domain.StreamInfo;
|
| | | import com.ruoyi.media.service.IMediaService;
|
| | | import lombok.extern.slf4j.Slf4j;
|
| | | import org.springframework.beans.factory.annotation.Value;
|
| | | import org.springframework.stereotype.Service;
|
| | | import com.ruoyi.media.mapper.VtduMapper;
|
| | | import com.ruoyi.media.domain.Vtdu;
|
| | |
| | | private VtduMapper vtduMapper;
|
| | | @Resource
|
| | | private IMediaService mediaService;
|
| | |
|
| | | @Resource
|
| | | private CameraSDKFactory cameraSDKFactory;
|
| | | @Value("${mediamtx.host}")
|
| | | String mediamtxHost;
|
| | | /**
|
| | | * æ¥è¯¢æµåªä½ç®¡ç
|
| | | *
|
| | |
| | | */
|
| | | @Override
|
| | | public Vtdu selectVtduByName(String name) {
|
| | |
|
| | | return vtduMapper.selectVtduByName(name);
|
| | | }
|
| | |
|
| | |
| | | */
|
| | | @Override
|
| | | public int insertVtdu(Vtdu vtdu) {
|
| | | log.debug("æµåªä½ã" + vtdu.getName() + "ãééæ·»å ");
|
| | | Map<String, String> map = mediaService.addPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode());
|
| | | vtdu.setRtspUrl(map.get("rtspUrl"));
|
| | | vtdu.setRtmpUrl(map.get("rtmpUrl"));
|
| | | vtdu.setWebrtcUrl(map.get("webrtcUrl"));
|
| | |
|
| | | vtdu.setName(vtdu.getName());
|
| | | vtdu.setRtspSource(vtdu.getRtspSource());
|
| | | vtdu.setIsCode(vtdu.getIsCode());
|
| | | vtdu.setMode(vtdu.getMode());
|
| | | vtdu.setCreateTime(DateUtils.getNowDate());
|
| | | return vtduMapper.insertVtdu(vtdu);
|
| | | }
|
| | |
|
| | |
| | | */
|
| | | @Override
|
| | | public int updateVtdu(Vtdu vtdu) {
|
| | | log.debug("æµåªä½ã" + vtdu.getName() + "ãééæ´æ°");
|
| | | Map<String, String> map = mediaService.editPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode());
|
| | | vtdu.setName(vtdu.getName());
|
| | | vtdu.setRtspSource(vtdu.getRtspSource());
|
| | |
| | | .collect(Collectors.toList());
|
| | | return nameList;
|
| | | } else {
|
| | |
|
| | | List<String> nameList = names.stream().filter(item -> !vtdus.stream().map(Vtdu::getName).collect(Collectors.toList()).contains(item))
|
| | | .collect(Collectors.toList());
|
| | | return nameList;
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | | //éè¦æ°å¢çï¼æµåªä½ä¸å°çï¼
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * @Author åèä¹
|
| | | * @Description 忥æ¬å°vtduåºåæµåªä½ä¸çæ°æ®
|
| | | * @Date 2024/7/10 15:26
|
| | | * @Param vtdus vtduåºçéå
|
| | | * @Param names æµåªä½çnameéå
|
| | | * @return
|
| | | * @Author åèä¹
|
| | | * @Description 忥æ¬å°vtduåºåæµåªä½ä¸çæ°æ®
|
| | | * @Date 2024/7/10 15:26
|
| | | * @Param vtdus vtduåºçéå
|
| | | * @Param names æµåªä½çnameéå
|
| | | */
|
| | | @Override
|
| | | public void asyncVtdu(List<Vtdu> vtdus, List<String> names) {
|
| | | //éè¦æ´æ°çæ°æ®,åæ°é¡ºåºæ³¨æ
|
| | | sameList(vtdus, names).stream().forEach(vtdu -> {
|
| | | mediaService.editPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode());
|
| | | StreamInfo streamInfo = mediaService.getPathInfo(vtdu.getName());
|
| | | if (!streamInfo.getRtspSource().equals(vtdu.getRtspSource())) {
|
| | | mediaService.editPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode());
|
| | | }
|
| | | });
|
| | | //éè¦å é¤çæ°æ®
|
| | | diffListToDel(vtdus, names).stream().forEach(name -> {
|
| | |
| | | mediaService.addPath(vtdu.getName(), vtdu.getRtspSource(), vtdu.getMode(), vtdu.getIsCode());
|
| | | });
|
| | | }
|
| | | @Override
|
| | | public void addChanToVtdu(ArdCameras camera, ArdChannel channel) {
|
| | | String name = camera.getId() + "_" + channel.getChanNo();
|
| | | String rtspSource="";
|
| | | switch (camera.getFactory())
|
| | | {
|
| | | case "1": rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream";break;
|
| | | case "2": rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/cam/realmonitor?channel=" + channel.getChanNo() + "&subtype=0";break;
|
| | | }
|
| | |
|
| | | //å 餿µåªä½
|
| | | if (selectVtduByName(name) != null) {
|
| | | deleteVtduByName(name);
|
| | | }
|
| | | //æ·»å å°æµåªä½
|
| | | CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo());
|
| | | CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(camera.getFactory());
|
| | | Map<String, Object> videoCompressionCfg = cameraSDK.getVideoCompressionCfg(cmd);
|
| | | Vtdu vtdu = new Vtdu();
|
| | | if (videoCompressionCfg.get("videoEncType") != null) {
|
| | | if (videoCompressionCfg.get("videoEncType").equals("æ åh264")) {
|
| | | vtdu.setIsCode("0");//é»è®¤ä¸è½¬ç
|
| | | } else {
|
| | | vtdu.setIsCode("1");//é»è®¤è½¬ç
|
| | | }
|
| | | } else {
|
| | | vtdu.setIsCode("0");//é»è®¤ä¸è½¬ç
|
| | | }
|
| | | vtdu.setRtspSource(rtspSource);
|
| | | vtdu.setName(name);
|
| | | vtdu.setMode("1");//é»è®¤CPU软解ç
|
| | | vtdu.setCameraId(camera.getId());
|
| | | String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name;
|
| | | String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name;
|
| | | String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name;
|
| | | vtdu.setRtmpUrl(rtmpUrl);
|
| | | vtdu.setWebrtcUrl(webrtcUrl);
|
| | | vtdu.setRtspUrl(rtspUrl);
|
| | | insertVtdu(vtdu);
|
| | | }
|
| | |
|
| | | }
|
| | |
| | | package com.ruoyi.utils.forest; |
| | | |
| | | import com.dtflys.forest.annotation.*; |
| | | import com.ruoyi.media.domain.Conf; |
| | | import com.ruoyi.media.domain.Config; |
| | | import com.ruoyi.media.domain.Items; |
| | | import com.ruoyi.media.domain.Paths; |
| | | import com.ruoyi.media.domain.*; |
| | | |
| | | import java.nio.file.Path; |
| | | |
| | |
| | | /** |
| | | * è·åè·¯å¾è¯¦æ
|
| | | */ |
| | | @Get(url ="/config/paths/get/{name}") |
| | | @Get(url = "/config/paths/get/{name}") |
| | | public Conf getPathInfo(@Var("name") String name); |
| | | |
| | | /** |
| | | * æ¥è¯¢ææè·¯å¾ |
| | | */ |
| | | @Get("/paths/list") |
| | | public Paths paths(); |
| | | @Get("/paths/list?page={pageNum}&itemsPerPage={pageSize}") |
| | | public Paths paths(@Var("pageNum") Integer pageNum, @Var("pageSize") Integer pageSize); |
| | | |
| | | /** |
| | | * æ¥è¯¢æærtspä¼è¯ |
| | |
| | | * æsessionIdæ¥è¯¢rtspä¼è¯ |
| | | */ |
| | | @Get("/rtspsessions/get/{sessionId}") |
| | | public String getRtspsessionById(@Var("sessionId") String sessionId); |
| | | public RtspSession getRtspsessionById(@Var("sessionId") String sessionId); |
| | | |
| | | /** |
| | | * æsessionIdæ¥è¯¢webrtcä¼è¯ |
| | | */ |
| | | @Get("/webrtcsessions/get/{sessionId}") |
| | | public String getWebrtcsessionById(@Var("sessionId") String sessionId); |
| | | public WebrtcSession getWebrtcsessionById(@Var("sessionId") String sessionId); |
| | | |
| | | /** |
| | | * æsessionIdæ¥è¯¢rtmpä¼è¯ |
| | | */ |
| | | @Get("/rtmpconns/get/{sessionId}") |
| | | public String getRtmpsessionById(@Var("sessionId") String sessionId); |
| | | public RtmpSession getRtmpsessionById(@Var("sessionId") String sessionId); |
| | | |
| | | /** |
| | | * æsessionIdå é¤rtspä¼è¯ |
| | |
| | | @Post("/webrtcsessions/kick/{sessionId}") |
| | | public String kickWebrtcSessions(@Var("sessionId") String sessionId); |
| | | |
| | | /** |
| | | * é
ç½®æµåªä½åæ° |
| | | */ |
| | | @Post("/config/set") |
| | | public String setConfig(@JSONBody Config config); |
| | | } |
| | |
| | | |
| | | return result; |
| | | } |
| | | public static String getChannelName(NetSDKLib.LLong hLoginHandle,Integer channel) { |
| | | |
| | | //æ¥è¯¢ééåç§° |
| | | public static String getChannelName(NetSDKLib.LLong hLoginHandle, Integer channel) { |
| | | String channelName = ""; |
| | | NetSDKLib.AV_CFG_ChannelName channelTitleName = new NetSDKLib.AV_CFG_ChannelName(); |
| | | if (ToolKits.GetDevConfig(hLoginHandle, channel, NetSDKLib.CFG_CMD_CHANNELTITLE, channelTitleName)) { |
| | | if (ToolKits.GetDevConfig(hLoginHandle, channel - 1, NetSDKLib.CFG_CMD_CHANNELTITLE, channelTitleName)) { |
| | | try { |
| | | channelName = new String(channelTitleName.szName, "GBK"); |
| | | } catch (Exception e) { |
| | |
| | | } |
| | | return channelName; |
| | | } |
| | | |
| | | public static boolean GetDevConfig(NetSDKLib.LLong hLoginHandle, int nChn, String strCmd, Structure cmdObject) { |
| | | boolean result = true; |
| | | IntByReference error = new IntByReference(0); |
| | |
| | | return result; |
| | | } |
| | | |
| | | //æ¥è¯¢ç¸æºç¶æ |
| | | public static boolean queryCameraState(NetSDKLib.LLong hLoginHandle, Integer chanNum, Integer chanNo) { |
| | | boolean bRet = false; |
| | | try { |
| | |
| | | stOut.read(); |
| | | ToolKits.GetPointerDataToStructArr(stOut.pCameraStateInfo, arrCameraStatus); // å°Pointeræ·è´å°æ°ç»å
å |
| | | final String[] connectionState = {"æªç¥", "æ£å¨è¿æ¥", "å·²è¿æ¥", "æªè¿æ¥", "ééæªé
ç½®,æ ä¿¡æ¯", "ééæé
ç½®,ä½è¢«ç¦ç¨"}; |
| | | log.debug(connectionState[arrCameraStatus[chanNo - 1].emConnectionState]); |
| | | |
| | | if (connectionState[arrCameraStatus[chanNo - 1].emConnectionState].equals("å·²è¿æ¥")) { |
| | | log.debug("éé" + arrCameraStatus[chanNo - 1].nChannel + connectionState[arrCameraStatus[chanNo - 1].emConnectionState]); |
| | | //log.debug("ééï¼" + arrCameraStatus[chanNo - 1].nChannel + "ç¶æï¼" + connectionState[arrCameraStatus[chanNo - 1].emConnectionState]); |
| | | bRet = true; |
| | | } else { |
| | | bRet = false; |
| | |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | } |
| | |
| | | NetSDKLib.LLong loginId = LoginModule.login(camera.getIp(), camera.getPort(), camera.getUsername(), camera.getPassword(), m_stDeviceInfo); |
| | | if (loginId.longValue() <= 0) { |
| | | camera.setChanNum(0); |
| | | camera.setLoginId(-1); |
| | | camera.setLoginId(-1l); |
| | | camera.setState("0"); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å é¤ç®¡çéé |
| | |
| | | log.error("设å¤[" + camera.getIp() + ":" + camera.getPort() + "]ç»å½å¤±è´¥:" + getErrorCodePrint()); |
| | | return AjaxResult.warn(ErrorCode.getErrorCode(LoginModule.netsdk.CLIENT_GetLastError())); |
| | | } |
| | | |
| | | log.debug("设å¤[" + camera.getIp() + ":" + camera.getPort() + "]ç»å½æå:" + (int) loginId.longValue()); |
| | | camera.setState("1"); |
| | | camera.setChanNum(m_stDeviceInfo.byChanNum); |
| | | camera.setStartDChan(1); |
| | | camera.setLoginId((int) loginId.longValue()); |
| | | camera.setStartChan(1); |
| | | camera.setLoginId(loginId.longValue()); |
| | | GlobalVariable.loginMap.put(camera.getId(), loginId); |
| | | //è·åææ°éé |
| | | List<ArdChannel> ardChannelList = getChannels(camera); |
| | |
| | | ardChannelList.stream().forEach(channel -> { |
| | | ardChannelService.insertArdChannel(channel); |
| | | }); |
| | | camera.setChanNum(ardChannelList.size()); |
| | | camera.setChannelList(ardChannelList); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //é
ç½®å°æµåªä½ |
| | | addVtdu(camera); |
| | | //é鿹鿷»å å°æµåªä½ |
| | | batchAddVtdu(camera); |
| | | } |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å建å¼å¯¼éå |
| | | createGuideQueue(camera); |
| | | return AjaxResult.success("设å¤ç»å½æå"); |
| | |
| | | NetSDKLib.LLong loginId = LoginModule.login(camera.getIp(), camera.getPort(), camera.getUsername(), camera.getPassword(), m_stDeviceInfo); |
| | | if (loginId.longValue() <= 0) { |
| | | camera.setChanNum(0); |
| | | camera.setLoginId(-1); |
| | | camera.setLoginId(-1l); |
| | | camera.setState("0"); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å é¤ç®¡çéé |
| | |
| | | log.error("设å¤[" + camera.getIp() + ":" + camera.getPort() + "]ç»å½å¤±è´¥:" + getErrorCodePrint()); |
| | | return AjaxResult.warn(getErrorCodePrint()); |
| | | } |
| | | log.debug("设å¤[" + camera.getIp() + ":" + camera.getPort() + "]ç»å½æå:" + loginId); |
| | | camera.setState("1"); |
| | | camera.setChanNum(m_stDeviceInfo.byChanNum); |
| | | camera.setStartDChan(1); |
| | | camera.setLoginId((int) loginId.longValue()); |
| | | camera.setStartChan(1); |
| | | camera.setLoginId((Long) loginId.longValue()); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | GlobalVariable.loginMap.put(camera.getId(), loginId); |
| | | |
| | |
| | | ardChannelList.stream().forEach(channel -> { |
| | | ardChannelService.insertArdChannel(channel); |
| | | }); |
| | | camera.setChanNum(ardChannelList.size()); |
| | | camera.setChannelList(ardChannelList); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //é
ç½®å°æµåªä½ |
| | | addVtdu(camera); |
| | | //é鿹鿷»å å°æµåªä½ |
| | | batchAddVtdu(camera); |
| | | } |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å建å¼å¯¼éå |
| | | createGuideQueue(camera); |
| | | return AjaxResult.success("ç»å½æå"); |
| | |
| | | } |
| | | } |
| | | |
| | | //æ·»å å°æµåªä½ |
| | | private void addVtdu(ArdCameras camera) { |
| | | //é鿹鿷»å å°æµåªä½ |
| | | public void batchAddVtdu(ArdCameras camera) { |
| | | camera.getChannelList().stream().forEach(channel -> { |
| | | String name = camera.getId() + "_" + channel.getChanNo(); |
| | | String rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/cam/realmonitor?channel=" + channel.getChanNo() + "&subtype=0"; |
| | | //å 餿µåªä½ |
| | | if (vtduService.selectVtduByName(name) != null) { |
| | | vtduService.deleteVtduByName(name); |
| | | } |
| | | //æ·»å å°æµåªä½ |
| | | CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo()); |
| | | Map<String, Object> videoCompressionCfg = getVideoCompressionCfg(cmd); |
| | | Vtdu vtdu = new Vtdu(); |
| | | if (videoCompressionCfg.get("videoEncType") != null) { |
| | | if (videoCompressionCfg.get("videoEncType").equals("æ åh264")) { |
| | | vtdu.setIsCode("0");//é»è®¤ä¸è½¬ç |
| | | } else { |
| | | vtdu.setIsCode("1");//é»è®¤è½¬ç |
| | | } |
| | | } else { |
| | | vtdu.setIsCode("0");//é»è®¤ä¸è½¬ç |
| | | } |
| | | vtdu.setRtspSource(rtspSource); |
| | | vtdu.setName(name); |
| | | vtdu.setMode("1");//é»è®¤CPU软解ç |
| | | vtdu.setCameraId(camera.getId()); |
| | | vtduService.insertVtdu(vtdu); |
| | | vtduService.addChanToVtdu(camera, channel); |
| | | }); |
| | | } |
| | | |
| | | |
| | | //å建å¼å¯¼éå |
| | | private void createGuideQueue(ArdCameras camera) { |
| | |
| | | |
| | | //è·åéé |
| | | public List<ArdChannel> getChannels(ArdCameras camera) { |
| | | if (camera.getLoginId().equals(-1)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | LLong loginId = new LLong(camera.getLoginId()); |
| | | List<ArdChannel> ardChannelList = new ArrayList<>(); |
| | | for (int i = 1; i < camera.getChanNum() + 1; i++) { |
| | | ArdChannel channel = new ArdChannel(); |
| | | String chanName = ConfigModule.getChannelName(loginId, i - 1).trim(); |
| | | log.debug("è·åééåç§°ï¼" + chanName); |
| | | String chanName = ConfigModule.getChannelName(loginId, i).trim(); |
| | | channel.setName(chanName.equals("") ? "éé" + i : chanName); |
| | | channel.setDeviceId(camera.getId()); |
| | | channel.setChanNo(i); |
| | |
| | | if (dwResult == 1) {
|
| | | GlobalVariable.loginMap.put(camera.getId(), lUserID);
|
| | | log.debug(camera.getIp() + ":" + camera.getPort() + "ç»å½æå");
|
| | | camera.setLoginId(lUserID);
|
| | | camera.setLoginId((long)lUserID);
|
| | | camera.setState("1");
|
| | | camera.setChanNum((int) lpDeviceinfo.byChanNum);
|
| | | camera.setStartDChan((int) lpDeviceinfo.byStartDChan);
|
| | | camera.setStartChan((int) lpDeviceinfo.byStartDChan);
|
| | | //è·åææ°éé
|
| | | List<ArdChannel> cameraChannelList = hikClientService.getChannels(camera);
|
| | | if (cameraChannelList.size() > 0) {
|
| | |
| | | } else {
|
| | | log.debug(camera.getIp() + ":" + camera.getPort() + "ç»å½å¤±è´¥");
|
| | | camera.setChanNum(0);
|
| | | camera.setLoginId(-1);
|
| | | camera.setLoginId(-1l);
|
| | | camera.setState("0");
|
| | | }
|
| | | ardCamerasService.updateArdCameras(camera);
|
| | |
| | | String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator; |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true); |
| | | } else { |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog" , true); |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true); |
| | | } |
| | | String m_sDeviceIP = camera.getIp(); |
| | | String m_sUsername = camera.getUsername(); |
| | |
| | | if (lUserID < 0) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | camera.setChanNum(0); |
| | | camera.setLoginId(-1); |
| | | camera.setLoginId(-1l); |
| | | camera.setState("0"); |
| | | //å é¤ç®¡çéé |
| | | ardChannelService.deleteArdChannelByDeviceId(camera.getId()); |
| | |
| | | } |
| | | GlobalVariable.loginMap.put(camera.getId(), lUserID); |
| | | GlobalVariable.loginCameraMap.put(lUserID, camera); |
| | | camera.setLoginId(lUserID); |
| | | camera.setLoginId((long)lUserID); |
| | | camera.setState("1"); |
| | | int chanNum = m_strDeviceInfo.struDeviceV30.byChanNum; |
| | | int startDchan = m_strDeviceInfo.struDeviceV30.byStartDChan + 1; |
| | |
| | | startDchan = m_strDeviceInfo.struDeviceV30.byStartDChan; |
| | | } |
| | | camera.setChanNum(chanNum); |
| | | camera.setStartDChan(startDchan); |
| | | camera.setStartChan(startDchan); |
| | | //è·åææ°éé |
| | | List<ArdChannel> cameraChannelList = getChannels(camera); |
| | | if (cameraChannelList.size() > 0) { |
| | |
| | | ardChannelService.insertArdChannel(channel); |
| | | }); |
| | | camera.setChannelList(cameraChannelList); |
| | | camera.setChanNum(cameraChannelList.size()); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //æ·»å å°æµåªä½ |
| | | addVtdu(camera); |
| | | //camera.setChanNum(cameraChannelList.size()); |
| | | //é鿹鿷»å å°æµåªä½ |
| | | batchAddVtdu(camera); |
| | | } |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å建å¼å¯¼éå |
| | | createGuideQueue(camera); |
| | | return AjaxResult.success("设å¤ç»å½æå"); |
| | | } catch (Exception ex) { |
| | | log.error("设å¤ç»å½å¼å¸¸" , ex); |
| | | log.error("设å¤ç»å½å¼å¸¸", ex); |
| | | return AjaxResult.error("设å¤ç»å½å¼å¸¸" + ex.getMessage()); |
| | | } |
| | | } |
| | |
| | | String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator; |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true); |
| | | } else { |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog" , true); |
| | | hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true); |
| | | } |
| | | String m_sDeviceIP = camera.getIp(); |
| | | String m_sUsername = camera.getUsername(); |
| | |
| | | if (lUserID < 0) { |
| | | int errorCode = hCNetSDK.NET_DVR_GetLastError(); |
| | | camera.setChanNum(0); |
| | | camera.setLoginId(-1); |
| | | camera.setLoginId(-1l); |
| | | camera.setState("0"); |
| | | //å é¤ç®¡çéé |
| | | ardChannelService.deleteArdChannelByDeviceId(camera.getId()); |
| | |
| | | |
| | | GlobalVariable.loginMap.put(camera.getId(), lUserID); |
| | | GlobalVariable.loginCameraMap.put(lUserID, camera); |
| | | camera.setLoginId(lUserID); |
| | | camera.setLoginId((long)lUserID); |
| | | camera.setState("1"); |
| | | int chanNum = m_strDeviceInfo.struDeviceV30.byChanNum; |
| | | int startDchan = m_strDeviceInfo.struDeviceV30.byStartDChan + 1; |
| | |
| | | startDchan = m_strDeviceInfo.struDeviceV30.byStartDChan; |
| | | } |
| | | camera.setChanNum(chanNum); |
| | | camera.setStartDChan(startDchan); |
| | | camera.setStartChan(startDchan); |
| | | //è·åææ°éé |
| | | List<ArdChannel> cameraChannelList = getChannels(camera); |
| | | if (cameraChannelList.size() > 0) { |
| | |
| | | ardChannelService.insertArdChannel(channel); |
| | | }); |
| | | camera.setChannelList(cameraChannelList); |
| | | camera.setChanNum(cameraChannelList.size()); |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //æ·»å å°æµåªä½ |
| | | addVtdu(camera); |
| | | //camera.setChanNum(cameraChannelList.size()); |
| | | //é鿹鿷»å å°æµåªä½ |
| | | batchAddVtdu(camera); |
| | | } |
| | | ardCamerasService.updateArdCameras(camera); |
| | | //å建å¼å¯¼éå |
| | | createGuideQueue(camera); |
| | | return AjaxResult.success("设å¤ç»å½æå"); |
| | | } catch (Exception ex) { |
| | | log.error("注å设å¤å¼å¸¸" , ex); |
| | | log.error("注å设å¤å¼å¸¸", ex); |
| | | return AjaxResult.error("注å设å¤å¼å¸¸" + ex.getMessage()); |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | //æ·»å å°æµåªä½ |
| | | private void addVtdu(ArdCameras camera) { |
| | | //é鿹鿷»å å°æµåªä½ |
| | | public void batchAddVtdu(ArdCameras camera) { |
| | | try { |
| | | camera.getChannelList().stream().forEach(channel->{ |
| | | String name = camera.getId() + "_" + channel.getChanNo(); |
| | | String rtspSource = "rtsp://" + camera.getUsername() + ":" + camera.getPassword() + "@" + camera.getIp() + ":" + camera.getRtspPort() + "/h264/ch" + channel.getChanNo() + "/main/av_stream"; |
| | | //å 餿µåªä½ |
| | | if (vtduService.selectVtduByName(name) != null) { |
| | | vtduService.deleteVtduByName(name); |
| | | } |
| | | //æ·»å å°æµåªä½ |
| | | Vtdu vtdu = new Vtdu(); |
| | | vtdu.setRtspSource(rtspSource); |
| | | vtdu.setName(name); |
| | | CameraCmd cmd = new CameraCmd(camera.getId(), channel.getChanNo()); |
| | | Map<String, Object> videoCompressionCfg = getVideoCompressionCfg(cmd); |
| | | if (videoCompressionCfg.get("videoEncType").equals("æ åh264")) { |
| | | vtdu.setIsCode("0");//é»è®¤ä¸è½¬ç |
| | | } else { |
| | | vtdu.setIsCode("1");//é»è®¤è½¬ç |
| | | } |
| | | vtdu.setMode("1");//é»è®¤CPU软解ç |
| | | vtdu.setCameraId(camera.getId()); |
| | | vtduService.insertVtdu(vtdu); |
| | | camera.getChannelList().stream().forEach(channel -> { |
| | | vtduService.addChanToVtdu(camera, channel); |
| | | }); |
| | | } catch (Exception ex) { |
| | | log.error("ééæ·»å å°æµåªä½å¼å¸¸ï¼" + ex.getMessage()); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * @æè¿° 注éç»å½ |
| | |
| | | nFrameRate = "æªç¥"; |
| | | break; |
| | | } |
| | | map.put("resolution" , resolution);//å辨ç |
| | | map.put("videoBitrate" , videoBitrate);//æ¯ç¹ç |
| | | map.put("videoEncType" , videoEncType);//ç¼ç |
| | | map.put("nFrameRate" , nFrameRate);//帧ç |
| | | map.put("resolution", resolution);//å辨ç |
| | | map.put("videoBitrate", videoBitrate);//æ¯ç¹ç |
| | | map.put("videoEncType", videoEncType);//ç¼ç |
| | | map.put("nFrameRate", nFrameRate);//帧ç |
| | | |
| | | } else { |
| | | int code = hCNetSDK.NET_DVR_GetLastError(); |
| | |
| | | double z = d.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue(); |
| | | //log.debug("Tåç´åæ°ä¸º: " + p + "Pæ°´å¹³åæ°ä¸º: " + t + "Zåååæ°ä¸º: " + z); |
| | | Map<String, Object> ptzMap = new HashMap<>(); |
| | | ptzMap.put("p" , p); |
| | | ptzMap.put("t" , t); |
| | | ptzMap.put("z" , z); |
| | | ptzMap.put("p", p); |
| | | ptzMap.put("t", t); |
| | | ptzMap.put("z", z); |
| | | return AjaxResult.success(ptzMap); |
| | | } |
| | | |
| | |
| | | float fTilt = lpPTZAbsoluteEX_cfg.struPTZCtrl.fTilt; |
| | | float t = fTilt < 0 ? fTilt + 360 : fTilt; |
| | | float z = lpPTZAbsoluteEX_cfg.struPTZCtrl.fZoom; |
| | | ptzMap.put("p" , p); |
| | | ptzMap.put("t" , t); |
| | | ptzMap.put("z" , z); |
| | | ptzMap.put("p", p); |
| | | ptzMap.put("t", t); |
| | | ptzMap.put("z", z); |
| | | return AjaxResult.success(ptzMap); |
| | | } catch (Exception ex) { |
| | | log.error("è·åé«ç²¾åº¦PTZç»å¯¹ä½ç½®å¼å¸¸:" + ex.getMessage()); |
| | |
| | | return AjaxResult.success("设置é«ç²¾åº¦PTZåæ°æå"); |
| | | |
| | | } catch (Exception ex) { |
| | | log.error("设置é«ç²¾åº¦PTZåæ°å¼å¸¸" , ex); |
| | | log.error("设置é«ç²¾åº¦PTZåæ°å¼å¸¸", ex); |
| | | return AjaxResult.error("设置é«ç²¾åº¦PTZåæ°å¼å¸¸:" + ex); |
| | | } |
| | | } |
| | |
| | | log.error("设置ptz失败,请ç¨åéè¯" + code); |
| | | return AjaxResult.warn("设置ptz失败:" + SdkErrorCodeEnum.getDescByCode(code) + "(" + code + ")"); |
| | | } |
| | | return AjaxResult.success("å¼å¯¼åæ æå",correctPitch); |
| | | return AjaxResult.success("å¼å¯¼åæ æå", correctPitch); |
| | | } catch (Exception ex) { |
| | | log.error("å¼å¯¼åæ å¼å¸¸:" + ex.getMessage()); |
| | | return AjaxResult.error("å¼å¯¼åæ å¼å¸¸:" + ex.getMessage()); |
| | |
| | | String wZoomPosMax = df.format((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPosMax)) / 10); |
| | | String wZoomPosMin = df.format((float) Integer.parseInt(Integer.toHexString(m_ptzPosCurrent.wZoomPosMin)) / 10); |
| | | Map<String, Object> ptzScopeMap = new HashMap<>(); |
| | | ptzScopeMap.put("pMax" , wPanPosMax); |
| | | ptzScopeMap.put("pMin" , wPanPosMin); |
| | | ptzScopeMap.put("tMax" , wTiltPosMax); |
| | | ptzScopeMap.put("tMin" , wTiltPosMin); |
| | | ptzScopeMap.put("zMax" , wZoomPosMax); |
| | | ptzScopeMap.put("zMin" , wZoomPosMin); |
| | | ptzScopeMap.put("pMax", wPanPosMax); |
| | | ptzScopeMap.put("pMin", wPanPosMin); |
| | | ptzScopeMap.put("tMax", wTiltPosMax); |
| | | ptzScopeMap.put("tMin", wTiltPosMin); |
| | | ptzScopeMap.put("zMax", wZoomPosMax); |
| | | ptzScopeMap.put("zMin", wZoomPosMin); |
| | | return AjaxResult.success(ptzScopeMap); |
| | | } |
| | | } |
| | |
| | | boolean bool = hCNetSDK.NET_DVR_SetDVRConfig(userId, NET_DVR_SET_CCDPARAMCFG, chanNo, point, struDayNigh.size()); |
| | | if (!bool) { |
| | | int code = hCNetSDK.NET_DVR_GetLastError(); |
| | | log.error("åæ¢çº¢å¤å¤±è´¥ ErrorCode:{},ErrorInfo:{}" , code, SdkErrorCodeEnum.getDescByCode(code)); |
| | | log.error("åæ¢çº¢å¤å¤±è´¥ ErrorCode:{},ErrorInfo:{}", code, SdkErrorCodeEnum.getDescByCode(code)); |
| | | return AjaxResult.warn("åæ¢çº¢å¤å¤±è´¥:" + SdkErrorCodeEnum.getDescByCode(code) + "(" + code + ")"); |
| | | } |
| | | log.debug("åæ¢çº¢å¤æå"); |
| | |
| | | |
| | | //è·åIPéé |
| | | public List<ArdChannel> getChannels(ArdCameras camera) { |
| | | if (camera.getLoginId().equals(-1)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | //è·åéé |
| | | List<ArdChannel> channelList = new ArrayList<>(); |
| | | try { |
| | |
| | | m_strIpparaCfg.write(); |
| | | //lpIpParaConfig æ¥æ¶æ°æ®çç¼å²æé |
| | | Pointer lpIpParaConfig = m_strIpparaCfg.getPointer(); |
| | | boolean bRet = hCNetSDK.NET_DVR_GetDVRConfig(camera.getLoginId(), HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0, lpIpParaConfig, m_strIpparaCfg.size(), ibrBytesReturned); |
| | | boolean bRet = hCNetSDK.NET_DVR_GetDVRConfig(camera.getLoginId().intValue(), HCNetSDK.NET_DVR_GET_IPPARACFG_V40, 0, lpIpParaConfig, m_strIpparaCfg.size(), ibrBytesReturned); |
| | | m_strIpparaCfg.read(); |
| | | //log.debug("èµ·å§æ°åééå·ï¼" + m_strIpparaCfg.dwStartDChan);//m_strIpparaCfg.dwDChanNum |
| | | for (int iChannum = 0; iChannum < camera.getChanNum(); iChannum++) { |
| | | ArdChannel channel = new ArdChannel(); |
| | | int chanNo = iChannum + camera.getStartDChan(); |
| | | int chanNo = iChannum + camera.getStartChan(); |
| | | HCNetSDK.NET_DVR_PICCFG_V40 strPicCfg = new HCNetSDK.NET_DVR_PICCFG_V40(); |
| | | strPicCfg.dwSize = strPicCfg.size(); |
| | | strPicCfg.write(); |
| | | Pointer pStrPicCfg = strPicCfg.getPointer(); |
| | | NativeLong lChannel = new NativeLong(chanNo); |
| | | IntByReference pInt = new IntByReference(0); |
| | | boolean b_GetPicCfg = hCNetSDK.NET_DVR_GetDVRConfig(camera.getLoginId(), HCNetSDK.NET_DVR_GET_PICCFG_V40, lChannel.intValue(), pStrPicCfg, strPicCfg.size(), pInt); |
| | | boolean b_GetPicCfg = hCNetSDK.NET_DVR_GetDVRConfig(camera.getLoginId().intValue(), HCNetSDK.NET_DVR_GET_PICCFG_V40, lChannel.intValue(), pStrPicCfg, strPicCfg.size(), pInt); |
| | | if (!b_GetPicCfg) { |
| | | // log.error("è·åå¾ååæ°å¤±è´¥ï¼é误ç ï¼" + hCNetSDK.NET_DVR_GetLastError()); |
| | | } |
| | |
| | | } |
| | | struGisInfo.read(); |
| | | Map<String, Object> map = new HashMap<>(); |
| | | map.put("p" , struGisInfo.struPtzPos.fPanPos); |
| | | map.put("t" , struGisInfo.struPtzPos.fTiltPos < 0 ? struGisInfo.struPtzPos.fTiltPos + 360 : struGisInfo.struPtzPos.fTiltPos); |
| | | map.put("z" , struGisInfo.struPtzPos.fZoomPos); |
| | | map.put("fHorFieldAngle" , struGisInfo.fHorizontalValue);// æ°´å¹³è§åºè§ |
| | | map.put("fVerFieldAngle" , struGisInfo.fVerticalValue);// åç´è§åºè§ |
| | | map.put("p", struGisInfo.struPtzPos.fPanPos); |
| | | map.put("t", struGisInfo.struPtzPos.fTiltPos < 0 ? struGisInfo.struPtzPos.fTiltPos + 360 : struGisInfo.struPtzPos.fTiltPos); |
| | | map.put("z", struGisInfo.struPtzPos.fZoomPos); |
| | | map.put("fHorFieldAngle", struGisInfo.fHorizontalValue);// æ°´å¹³è§åºè§ |
| | | map.put("fVerFieldAngle", struGisInfo.fVerticalValue);// åç´è§åºè§ |
| | | return AjaxResult.success(map); |
| | | |
| | | } |
| | |
| | | return AjaxResult.warn("æ¬å°å½ååæµå¤±è´¥:" + SdkErrorCodeEnum.getDescByCode(code) + "(" + code + ")"); |
| | | } |
| | | log.debug("æ¬å°å½åå¼å§"); |
| | | return AjaxResult.success("å½åå¼å§" , lRealHandle); |
| | | return AjaxResult.success("å½åå¼å§", lRealHandle); |
| | | } catch (Exception ex) { |
| | | log.error("æ¬å°å½åå¼å§å¼å¸¸" + ex.getMessage()); |
| | | return AjaxResult.error("æ¬å°å½åå¼å§å¼å¸¸" + ex.getMessage()); |
| | |
| | | <result property="gdtype" column="gdtype"/>
|
| | | <result property="factory" column="factory"/>
|
| | | <result property="chanNum" column="channel"/>
|
| | | <result property="startChan" column="start_chan"/>
|
| | | <result property="longitude" column="longitude"/>
|
| | | <result property="latitude" column="latitude"/>
|
| | | <result property="altitude" column="altitude"/>
|
| | |
| | | c.gdtype,
|
| | | c.factory,
|
| | | c.channel,
|
| | | c.start_chan,
|
| | | c.longitude,
|
| | | c.latitude,
|
| | | c.altitude,
|
| | |
| | | <if test="gdtype != null and gdtype != ''">and c.gdtype = #{gdtype}</if>
|
| | | <if test="factory != null and factory != ''">and c.factory = #{factory}</if>
|
| | | <if test="chanNum != null ">and c.channel = #{chanNum}</if>
|
| | | <if test="startChan != null ">and c.start_chan = #{startChan}</if>
|
| | | <if test="longitude != null ">and c.longitude = #{longitude}</if>
|
| | | <if test="latitude != null ">and c.latitude = #{latitude}</if>
|
| | | <if test="altitude != null ">and c.altitude = #{altitude}</if>
|
| | |
| | | <if test="gdtype != null and gdtype != ''">and c.gdtype = #{gdtype}</if>
|
| | | <if test="factory != null and factory != ''">and c.factory = #{factory}</if>
|
| | | <if test="chanNum != null ">and c.channel = #{chanNum}</if>
|
| | | <if test="startChan != null ">and c.start_chan= #{startChan}</if>
|
| | | <if test="longitude != null ">and c.longitude = #{longitude}</if>
|
| | | <if test="latitude != null ">and c.latitude = #{latitude}</if>
|
| | | <if test="altitude != null ">and c.altitude = #{altitude}</if>
|
| | |
| | | <if test="factory != null">factory,</if>
|
| | | <if test="towerId != null">tower_id,</if>
|
| | | <if test="chanNum != null">channel,</if>
|
| | | <if test="startChan != null">start_chan,</if>
|
| | | <if test="longitude != null">longitude,</if>
|
| | | <if test="latitude != null">latitude,</if>
|
| | | <if test="altitude != null">altitude,</if>
|
| | |
| | | <if test="factory != null">#{factory},</if>
|
| | | <if test="towerId != null">#{towerId},</if>
|
| | | <if test="chanNum != null">#{chanNum},</if>
|
| | | <if test="startChan != null">#{startChan},</if>
|
| | | <if test="longitude != null">#{longitude},</if>
|
| | | <if test="latitude != null">#{latitude},</if>
|
| | | <if test="altitude != null">#{altitude},</if>
|
| | |
| | | <if test="factory != null">factory = #{factory},</if>
|
| | | <if test="towerId != null">tower_id = #{towerId},</if>
|
| | | <if test="chanNum != null">channel = #{chanNum},</if>
|
| | | <if test="startChan != null">start_chan = #{startChan},</if>
|
| | | <if test="longitude != null">longitude = #{longitude},</if>
|
| | | <if test="latitude != null">latitude = #{latitude},</if>
|
| | | <if test="altitude != null">altitude = #{altitude},</if>
|
| | |
| | | |
| | | let webrtcClient; |
| | | //whepæä½æ¹æ³ |
| | | const restartPause = 2000; |
| | | const retryPause = 2000; |
| | | |
| | | const video = document.getElementById('video'); |
| | | const message = document.getElementById('message'); |
| | | |
| | | let nonAdvertisedCodecs = []; |
| | | let pc = null; |
| | | let restartTimeout = null; |
| | | let sessionUrl = ''; |
| | | let offerData = ''; |
| | | let queuedCandidates = []; |
| | | let defaultControls = false; |
| | | |
| | | const setMessage = (str) => { |
| | | if (str !== '') { |
| | | video.controls = false; |
| | | } else { |
| | | video.controls = defaultControls; |
| | | } |
| | | message.innerText = str; |
| | | }; |
| | | |
| | | const unquoteCredential = (v) => ( |
| | | JSON.parse(`"${v}"`) |
| | | ); |
| | | |
| | | const linkToIceServers = (links) => ( |
| | | (links !== null) ? links.split(', ').map((link) => { |
| | | const m = link.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i); |
| | |
| | | if (m[3] !== undefined) { |
| | | ret.username = unquoteCredential(m[3]); |
| | | ret.credential = unquoteCredential(m[4]); |
| | | ret.credentialType = "password"; |
| | | ret.credentialType = 'password'; |
| | | } |
| | | |
| | | return ret; |
| | | }) : [] |
| | | ); |
| | | const parseOffer = (offer) => { |
| | | |
| | | const parseOffer = (sdp) => { |
| | | const ret = { |
| | | iceUfrag: '', |
| | | icePwd: '', |
| | | medias: [], |
| | | }; |
| | | |
| | | for (const line of offer.split('\r\n')) { |
| | | for (const line of sdp.split('\r\n')) { |
| | | if (line.startsWith('m=')) { |
| | | ret.medias.push(line.slice('m='.length)); |
| | | } else if (ret.iceUfrag === '' && line.startsWith('a=ice-ufrag:')) { |
| | |
| | | |
| | | return ret; |
| | | }; |
| | | const generateSdpFragment = (offerData, candidates) => { |
| | | |
| | | const enableStereoPcmau = (section) => { |
| | | let lines = section.split('\r\n'); |
| | | |
| | | lines[0] += ' 118'; |
| | | lines.splice(lines.length - 1, 0, 'a=rtpmap:118 PCMU/8000/2'); |
| | | lines.splice(lines.length - 1, 0, 'a=rtcp-fb:118 transport-cc'); |
| | | |
| | | lines[0] += ' 119'; |
| | | lines.splice(lines.length - 1, 0, 'a=rtpmap:119 PCMA/8000/2'); |
| | | lines.splice(lines.length - 1, 0, 'a=rtcp-fb:119 transport-cc'); |
| | | |
| | | return lines.join('\r\n'); |
| | | }; |
| | | |
| | | const enableMultichannelOpus = (section) => { |
| | | let lines = section.split('\r\n'); |
| | | |
| | | lines[0] += " 112"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:112 multiopus/48000/3"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:112 channel_mapping=0,2,1;num_streams=2;coupled_streams=1"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:112 transport-cc"); |
| | | |
| | | lines[0] += " 113"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:113 multiopus/48000/4"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:113 channel_mapping=0,1,2,3;num_streams=2;coupled_streams=2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:113 transport-cc"); |
| | | |
| | | lines[0] += " 114"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:114 multiopus/48000/5"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:114 channel_mapping=0,4,1,2,3;num_streams=3;coupled_streams=2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:114 transport-cc"); |
| | | |
| | | lines[0] += " 115"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:115 multiopus/48000/6"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:115 channel_mapping=0,4,1,2,3,5;num_streams=4;coupled_streams=2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:115 transport-cc"); |
| | | |
| | | lines[0] += " 116"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:116 multiopus/48000/7"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:116 channel_mapping=0,4,1,2,3,5,6;num_streams=4;coupled_streams=4"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:116 transport-cc"); |
| | | |
| | | lines[0] += " 117"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:117 multiopus/48000/8"); |
| | | lines.splice(lines.length - 1, 0, "a=fmtp:117 channel_mapping=0,6,1,4,5,2,3,7;num_streams=5;coupled_streams=4"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:117 transport-cc"); |
| | | |
| | | return lines.join('\r\n'); |
| | | }; |
| | | |
| | | const enableL16 = (section) => { |
| | | let lines = section.split('\r\n'); |
| | | |
| | | lines[0] += " 120"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:120 L16/8000/2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:120 transport-cc"); |
| | | |
| | | lines[0] += " 121"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:121 L16/16000/2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:121 transport-cc"); |
| | | |
| | | lines[0] += " 122"; |
| | | lines.splice(lines.length - 1, 0, "a=rtpmap:122 L16/48000/2"); |
| | | lines.splice(lines.length - 1, 0, "a=rtcp-fb:122 transport-cc"); |
| | | |
| | | return lines.join('\r\n'); |
| | | }; |
| | | |
| | | const enableStereoOpus = (section) => { |
| | | let opusPayloadFormat = ''; |
| | | let lines = section.split('\r\n'); |
| | | |
| | | for (let i = 0; i < lines.length; i++) { |
| | | if (lines[i].startsWith('a=rtpmap:') && lines[i].toLowerCase().includes('opus/')) { |
| | | opusPayloadFormat = lines[i].slice('a=rtpmap:'.length).split(' ')[0]; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (opusPayloadFormat === '') { |
| | | return section; |
| | | } |
| | | |
| | | for (let i = 0; i < lines.length; i++) { |
| | | if (lines[i].startsWith('a=fmtp:' + opusPayloadFormat + ' ')) { |
| | | if (!lines[i].includes('stereo')) { |
| | | lines[i] += ';stereo=1'; |
| | | } |
| | | if (!lines[i].includes('sprop-stereo')) { |
| | | lines[i] += ';sprop-stereo=1'; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return lines.join('\r\n'); |
| | | }; |
| | | |
| | | const editOffer = (sdp) => { |
| | | const sections = sdp.split('m='); |
| | | |
| | | for (let i = 0; i < sections.length; i++) { |
| | | if (sections[i].startsWith('audio')) { |
| | | sections[i] = enableStereoOpus(sections[i]); |
| | | |
| | | if (nonAdvertisedCodecs.includes('pcma/8000/2')) { |
| | | sections[i] = enableStereoPcmau(sections[i]); |
| | | } |
| | | |
| | | if (nonAdvertisedCodecs.includes('multiopus/48000/6')) { |
| | | sections[i] = enableMultichannelOpus(sections[i]); |
| | | } |
| | | |
| | | if (nonAdvertisedCodecs.includes('L16/48000/2')) { |
| | | sections[i] = enableL16(sections[i]); |
| | | } |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return sections.join('m='); |
| | | }; |
| | | |
| | | const generateSdpFragment = (od, candidates) => { |
| | | const candidatesByMedia = {}; |
| | | for (const candidate of candidates) { |
| | | const mid = candidate.sdpMLineIndex; |
| | |
| | | candidatesByMedia[mid].push(candidate); |
| | | } |
| | | |
| | | let frag = 'a=ice-ufrag:' + offerData.iceUfrag + '\r\n' |
| | | + 'a=ice-pwd:' + offerData.icePwd + '\r\n'; |
| | | let frag = 'a=ice-ufrag:' + od.iceUfrag + '\r\n' |
| | | + 'a=ice-pwd:' + od.icePwd + '\r\n'; |
| | | |
| | | let mid = 0; |
| | | |
| | | for (const media of offerData.medias) { |
| | | for (const media of od.medias) { |
| | | if (candidatesByMedia[mid] !== undefined) { |
| | | frag += 'm=' + media + '\r\n' |
| | | + 'a=mid:' + mid + '\r\n'; |
| | |
| | | } |
| | | |
| | | return frag; |
| | | } |
| | | }; |
| | | |
| | | class WHEPClient { |
| | | constructor(whepUrl, videoId) { |
| | | this.video = videoId; |
| | | this.wurl = new URL('whep', whepUrl); |
| | | this.pc = null; |
| | | this.restartTimeout = null; |
| | | this.eTag = ''; |
| | | this.queuedCandidates = []; |
| | | this.start(); |
| | | } |
| | | const loadStream = () => { |
| | | requestICEServers(); |
| | | }; |
| | | |
| | | start() { |
| | | console.log("requesting ICE servers"); |
| | | fetch(this.wurl, { |
| | | method: 'OPTIONS', |
| | | }) |
| | | .then((res) => this.onIceServers(res)) |
| | | const supportsNonAdvertisedCodec = (codec, fmtp) => ( |
| | | new Promise((resolve, reject) => { |
| | | const pc = new RTCPeerConnection({ iceServers: [] }); |
| | | pc.addTransceiver('audio', { direction: 'recvonly' }); |
| | | pc.createOffer() |
| | | .then((offer) => { |
| | | if (offer.sdp.includes(' ' + codec)) { // codec is advertised, there's no need to add it manually |
| | | resolve(false); |
| | | return; |
| | | } |
| | | const sections = offer.sdp.split('m=audio'); |
| | | const lines = sections[1].split('\r\n'); |
| | | lines[0] += ' 118'; |
| | | lines.splice(lines.length - 1, 0, 'a=rtpmap:118 ' + codec); |
| | | if (fmtp !== undefined) { |
| | | lines.splice(lines.length - 1, 0, 'a=fmtp:118 ' + fmtp); |
| | | } |
| | | sections[1] = lines.join('\r\n'); |
| | | offer.sdp = sections.join('m=audio'); |
| | | return pc.setLocalDescription(offer); |
| | | }) |
| | | .then(() => { |
| | | return pc.setRemoteDescription(new RTCSessionDescription({ |
| | | type: 'answer', |
| | | sdp: 'v=0\r\n' |
| | | + 'o=- 6539324223450680508 0 IN IP4 0.0.0.0\r\n' |
| | | + 's=-\r\n' |
| | | + 't=0 0\r\n' |
| | | + 'a=fingerprint:sha-256 0D:9F:78:15:42:B5:4B:E6:E2:94:3E:5B:37:78:E1:4B:54:59:A3:36:3A:E5:05:EB:27:EE:8F:D2:2D:41:29:25\r\n' |
| | | + 'm=audio 9 UDP/TLS/RTP/SAVPF 118\r\n' |
| | | + 'c=IN IP4 0.0.0.0\r\n' |
| | | + 'a=ice-pwd:7c3bf4770007e7432ee4ea4d697db675\r\n' |
| | | + 'a=ice-ufrag:29e036dc\r\n' |
| | | + 'a=sendonly\r\n' |
| | | + 'a=rtcp-mux\r\n' |
| | | + 'a=rtpmap:118 ' + codec + '\r\n' |
| | | + ((fmtp !== undefined) ? 'a=fmtp:118 ' + fmtp + '\r\n' : ''), |
| | | })); |
| | | }) |
| | | .then(() => { |
| | | resolve(true); |
| | | }) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | resolve(false); |
| | | }) |
| | | .finally(() => { |
| | | pc.close(); |
| | | }); |
| | | } |
| | | }) |
| | | ); |
| | | |
| | | onIceServers(res) { |
| | | this.pc = new RTCPeerConnection({ |
| | | iceServers: linkToIceServers(res.headers.get('Link')), |
| | | const getNonAdvertisedCodecs = () => { |
| | | Promise.all([ |
| | | ['pcma/8000/2'], |
| | | ['multiopus/48000/6', 'channel_mapping=0,4,1,2,3,5;num_streams=4;coupled_streams=2'], |
| | | ['L16/48000/2'] |
| | | ].map((c) => supportsNonAdvertisedCodec(c[0], c[1]).then((r) => (r) ? c[0] : false))) |
| | | .then((c) => c.filter((e) => e !== false)) |
| | | .then((codecs) => { |
| | | nonAdvertisedCodecs = codecs; |
| | | loadStream(); |
| | | }); |
| | | }; |
| | | |
| | | const direction = "sendrecv"; |
| | | this.pc.addTransceiver("video", {direction}); |
| | | this.pc.addTransceiver("audio", {direction}); |
| | | const onError = (err) => { |
| | | if (restartTimeout === null) { |
| | | setMessage(err + ', retrying in some seconds'); |
| | | |
| | | this.pc.onicecandidate = (evt) => this.onLocalCandidate(evt); |
| | | this.pc.oniceconnectionstatechange = () => this.onConnectionState(); |
| | | if (pc !== null) { |
| | | pc.close(); |
| | | pc = null; |
| | | } |
| | | |
| | | this.pc.ontrack = (evt) => { |
| | | console.log("new track:", evt.track.kind); |
| | | document.getElementById(this.video).srcObject = evt.streams[0]; |
| | | }; |
| | | restartTimeout = window.setTimeout(() => { |
| | | restartTimeout = null; |
| | | loadStream(); |
| | | }, retryPause); |
| | | |
| | | this.pc.createOffer() |
| | | .then((offer) => this.onLocalOffer(offer)); |
| | | } |
| | | |
| | | onLocalOffer(offer) { |
| | | this.offerData = parseOffer(offer.sdp); |
| | | this.pc.setLocalDescription(offer); |
| | | |
| | | console.log("sending offer"); |
| | | console.log(this.wurl); |
| | | fetch(this.wurl, { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/sdp', |
| | | }, |
| | | body: offer.sdp, |
| | | }) |
| | | .then((res) => { |
| | | if (res.status !== 201) { |
| | | throw new Error('bad status code'); |
| | | } |
| | | // this.eTag = res.headers.get('ETag'); |
| | | this.eTag = res.headers.get("ETag") || res.headers.get('E-Tag'); |
| | | return res.text(); |
| | | }) |
| | | .then((sdp) => this.onRemoteAnswer(new RTCSessionDescription({ |
| | | type: 'answer', |
| | | sdp, |
| | | }))) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | if (sessionUrl) { |
| | | fetch(sessionUrl, { |
| | | method: 'DELETE', |
| | | }); |
| | | } |
| | | sessionUrl = ''; |
| | | |
| | | queuedCandidates = []; |
| | | } |
| | | }; |
| | | |
| | | onConnectionState() { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | console.log("peer connection state:", this.pc.iceConnectionState); |
| | | |
| | | switch (this.pc.iceConnectionState) { |
| | | case "disconnected": |
| | | this.scheduleRestart(); |
| | | } |
| | | } |
| | | |
| | | onRemoteAnswer(answer) { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | this.pc.setRemoteDescription(new RTCSessionDescription(answer)); |
| | | |
| | | if (this.queuedCandidates.length !== 0) { |
| | | this.sendLocalCandidates(this.queuedCandidates); |
| | | this.queuedCandidates = []; |
| | | } |
| | | } |
| | | |
| | | onLocalCandidate(evt) { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | if (evt.candidate !== null) { |
| | | if (this.eTag === '') { |
| | | this.queuedCandidates.push(evt.candidate); |
| | | } else { |
| | | this.sendLocalCandidates([evt.candidate]) |
| | | const sendLocalCandidates = (candidates) => { |
| | | fetch(sessionUrl + window.location.search, { |
| | | method: 'PATCH', |
| | | headers: { |
| | | 'Content-Type': 'application/trickle-ice-sdpfrag', |
| | | 'If-Match': '*', |
| | | }, |
| | | body: generateSdpFragment(offerData, candidates), |
| | | }) |
| | | .then((res) => { |
| | | switch (res.status) { |
| | | case 204: |
| | | break; |
| | | case 404: |
| | | throw new Error('stream not found'); |
| | | default: |
| | | throw new Error(`bad status code ${res.status}`); |
| | | } |
| | | } |
| | | } |
| | | |
| | | sendLocalCandidates(candidates) { |
| | | fetch(this.wurl, { |
| | | method: 'PATCH', |
| | | headers: { |
| | | 'Content-Type': 'application/trickle-ice-sdpfrag', |
| | | 'If-Match': this.eTag, |
| | | }, |
| | | |
| | | body: generateSdpFragment(this.offerData, candidates), |
| | | }) |
| | | .then((res) => { |
| | | if (res.status !== 204) { |
| | | throw new Error('bad status code'); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | }); |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }; |
| | | |
| | | const onLocalCandidate = (evt) => { |
| | | if (restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | scheduleRestart() { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | if (evt.candidate !== null) { |
| | | if (sessionUrl === '') { |
| | | queuedCandidates.push(evt.candidate); |
| | | } else { |
| | | sendLocalCandidates([evt.candidate]) |
| | | } |
| | | } |
| | | }; |
| | | |
| | | if (this.pc !== null) { |
| | | this.pc.close(); |
| | | this.pc = null; |
| | | } |
| | | |
| | | this.restartTimeout = window.setTimeout(() => { |
| | | this.restartTimeout = null; |
| | | this.start(); |
| | | }, restartPause); |
| | | |
| | | this.eTag = ''; |
| | | this.queuedCandidates = []; |
| | | const onRemoteAnswer = (sdp) => { |
| | | if (restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | stop() { |
| | | if (this.pc) { |
| | | try { |
| | | this.pc.close(); |
| | | } catch (e) { |
| | | console.log("Failure close peer connection:" + e); |
| | | pc.setRemoteDescription(new RTCSessionDescription({ |
| | | type: 'answer', |
| | | sdp, |
| | | })) |
| | | .then(() => { |
| | | if (queuedCandidates.length !== 0) { |
| | | sendLocalCandidates(queuedCandidates); |
| | | queuedCandidates = []; |
| | | } |
| | | this.pc = null; |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }; |
| | | |
| | | const sendOffer = (offer) => { |
| | | fetch(new URL('whep', window.location.href) + window.location.search, { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/sdp', |
| | | }, |
| | | body: offer.sdp, |
| | | }) |
| | | .then((res) => { |
| | | switch (res.status) { |
| | | case 201: |
| | | break; |
| | | case 404: |
| | | throw new Error('stream not found'); |
| | | case 400: |
| | | return res.json().then((e) => { throw new Error(e.error); }); |
| | | default: |
| | | throw new Error(`bad status code ${res.status}`); |
| | | } |
| | | |
| | | sessionUrl = new URL(res.headers.get('location'), window.location.href).toString(); |
| | | |
| | | return res.text() |
| | | .then((sdp) => onRemoteAnswer(sdp)); |
| | | }) |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }; |
| | | |
| | | const createOffer = () => { |
| | | pc.createOffer() |
| | | .then((offer) => { |
| | | offer.sdp = editOffer(offer.sdp); |
| | | offerData = parseOffer(offer.sdp); |
| | | pc.setLocalDescription(offer) |
| | | .then(() => { |
| | | sendOffer(offer); |
| | | }) |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }) |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }; |
| | | |
| | | const onConnectionState = () => { |
| | | if (restartTimeout !== null) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (pc.iceConnectionState === 'disconnected') { |
| | | onError('peer connection closed'); |
| | | } |
| | | }; |
| | | |
| | | const onTrack = (evt) => { |
| | | setMessage(''); |
| | | video.srcObject = evt.streams[0]; |
| | | }; |
| | | |
| | | const requestICEServers = () => { |
| | | fetch(new URL('whep', window.location.href) + window.location.search, { |
| | | method: 'OPTIONS', |
| | | }) |
| | | .then((res) => { |
| | | pc = new RTCPeerConnection({ |
| | | iceServers: linkToIceServers(res.headers.get('Link')), |
| | | // https://webrtc.org/getting-started/unified-plan-transition-guide |
| | | sdpSemantics: 'unified-plan', |
| | | }); |
| | | |
| | | const direction = 'sendrecv'; |
| | | pc.addTransceiver('video', { direction }); |
| | | pc.addTransceiver('audio', { direction }); |
| | | |
| | | pc.onicecandidate = (evt) => onLocalCandidate(evt); |
| | | pc.oniceconnectionstatechange = () => onConnectionState(); |
| | | pc.ontrack = (evt) => onTrack(evt); |
| | | |
| | | createOffer(); |
| | | }) |
| | | .catch((err) => { |
| | | onError(err.toString()); |
| | | }); |
| | | }; |
| | | |
| | | const parseBoolString = (str, defaultVal) => { |
| | | str = (str || ''); |
| | | |
| | | if (['1', 'yes', 'true'].includes(str.toLowerCase())) { |
| | | return true; |
| | | } |
| | | if (['0', 'no', 'false'].includes(str.toLowerCase())) { |
| | | return false; |
| | | } |
| | | return defaultVal; |
| | | }; |
| | | |
| | | const loadAttributesFromQuery = () => { |
| | | const params = new URLSearchParams(window.location.search); |
| | | video.controls = parseBoolString(params.get('controls'), true); |
| | | video.muted = parseBoolString(params.get('muted'), true); |
| | | video.autoplay = parseBoolString(params.get('autoplay'), true); |
| | | video.playsInline = parseBoolString(params.get('playsinline'), true); |
| | | defaultControls = video.controls; |
| | | }; |
| | | |
| | | |
| | | function realView(whepUrl, videoId) { |
| | | console.log(whepUrl) |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en" xmlns:th="http://www.thymeleaf.org"> |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <title>æµè¯é¡µ</title> |
| | | <script th:src="@{/js/jquery-3.6.4.min.js}"></script> |
| | | <link rel="stylesheet" th:href="@{/css/bootstrap.css}"/> |
| | | <script th:src="@{/js/bootstrap.js}"></script> |
| | | <style> |
| | | .top-buffer { |
| | | margin-top: 10px; |
| | | } |
| | | .container { |
| | | border: 2px solid #1b6d85; |
| | | padding: 15px; |
| | | } |
| | | </style> |
| | | <body> |
| | | <div class="container"> |
| | | <div class="row"> |
| | | <div class="col-md-5"> |
| | | <div class="row top-buffer"> |
| | | 设å¤ï¼<select id="selectDev" style="width: 330px;"> |
| | | </select> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | ééï¼<select id="selectChn" style="width: 330px;"> |
| | | </select> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <div class="col-md-1 col-md-offset-1"> |
| | | <button id="up" type="button" class="btn btn-primary">ä¸</button> |
| | | </div> |
| | | <div class="col-md-6 col-md-offset-2"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="controlZoomIn" type="button" class="btn btn-primary">è°ç¦-</button> |
| | | <button id="controlZoomOut" type="button" class="btn btn-primary">è°ç¦+</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row "> |
| | | <div class="col-md-1"> |
| | | <button id="left" type="button" class="btn btn-primary">å·¦</button> |
| | | </div> |
| | | <div class="col-md-1 col-md-offset-1"> |
| | | <button id="right" type="button" class="btn btn-primary">å³</button> |
| | | </div> |
| | | <div class="col-md-6 col-md-offset-1"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="controlFocusNear" type="button" class="btn btn-primary">èç¦-</button> |
| | | <button id="controlFocusFar" type="button" class="btn btn-primary">èç¦+</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row "> |
| | | <div class="col-md-1 col-md-offset-1"> |
| | | <button id="down" type="button" class="btn btn-primary">ä¸</button> |
| | | </div> |
| | | <div class="col-md-6 col-md-offset-2"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="controlIrisOpen" type="button" class="btn btn-primary">å
å-</button> |
| | | <button id="controlIrisClose" type="button" class="btn btn-primary">å
å+</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="row "> |
| | | <div class="col-md-10"> |
| | | <div class="row top-buffer"> |
| | | <div class="input-group"> |
| | | <span class="input-group-addon">ç®çåæ å¼ï¼</span> |
| | | <input id="targetPostion" class="form-control" placeholder="ç®çåæ "/> |
| | | <button id="setTargetPostion" type="button" class="btn btn-default">æååæ </button> |
| | | </div> |
| | | <div class="input-group"> |
| | | <span class="input-group-addon">På¼ï¼</span> |
| | | <input id="p" class="form-control" placeholder="请è¾å
¥På¼"/> |
| | | </div> |
| | | <div class="input-group"> |
| | | <span class="input-group-addon">Tå¼ï¼</span> |
| | | <input id="t" class="form-control" placeholder="请è¾å
¥Tå¼"/> |
| | | </div> |
| | | <div class="input-group"> |
| | | <span class="input-group-addon">Zå¼ï¼</span> |
| | | <input id="z" class="form-control" placeholder="请è¾å
¥Zå¼"/> |
| | | </div> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="getPTZ" type="button" class="btn btn-default">è·åptz</button> |
| | | <button id="setPTZ" type="button" class="btn btn-default">设置ptz</button> |
| | | <button id="setPreset" type="button" class="btn btn-default">设é¢ç½®ç¹</button> |
| | | <button id="gotoPreset" type="button" class="btn btn-default">è°é¢ç½®ç¹</button> |
| | | <button id="setZeroPTZ" type="button" class="btn btn-default">è®¾ç½®é¶æ¹ä½è§</button> |
| | | </div> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="FocusMode" type="button" class="btn btn-default">æå¨èç¦</button> |
| | | <div id="focusDiv" class="input-group"> |
| | | <span class="input-group-addon">èç¦å¼ï¼</span> |
| | | <input id="focus" class="form-control" placeholder="èç¦å¼"/> |
| | | </div> |
| | | <button id="getFocusPos" type="button" class="btn btn-default">è·åèç¦å¼</button> |
| | | <button id="setFocusPos" type="button" class="btn btn-default">设置èç¦å¼</button> |
| | | </div> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="WiperPwron" type="button" class="btn btn-default">å¼å¯é¨å·</button> |
| | | <button id="Defogcfg" type="button" class="btn btn-default">å¼å¯éé¾</button> |
| | | <button id="Infrarecfg" type="button" class="btn btn-default">å¼å¯çº¢å¤</button> |
| | | <button id="HeateRpwron" type="button" class="btn btn-default">å¼å¯äºå°å ç</button> |
| | | <button id="CameraDeicing" type="button" class="btn btn-default">å¼å¯é头å ç</button> |
| | | </div> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <div class="btn-group" role="group"> |
| | | <button id="voice" type="button" class="btn btn-default">å¼å§è¯é³å¯¹è®²</button> |
| | | <button id="record" type="button" class="btn btn-default">å¼å§å½å</button> |
| | | <button id="saveCutPic" type="button" class="btn btn-default">å卿å¾</button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="col-md-6"> |
| | | <div class="row"> |
| | | <div class="row top-buffer"> |
| | | <button id="preview" type="button" class="btn btn-primary">é¢è§</button> |
| | | <button id="previewStop" type="button" class="btn btn-primary">忢</button> |
| | | </div> |
| | | <div class="row top-buffer"> |
| | | <video id="video" muted autoplay loop controls |
| | | style="width: 100%; height: 360px; object-fit: fill; border: 2px solid #3498db;"/> |
| | | </div> |
| | | <div class="row"> |
| | | <img class="thumbnail" id="imgContainer" |
| | | style="width: 100%; height: 360px; border: 2px solid #3498db;"/> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <script th:inline="javascript"> |
| | | var cameraId, chanNo,opt, optOpen, optClose, token; |
| | | window.onload = function () { |
| | | console.log(RTCRtpReceiver.getCapabilities('video').codecs) |
| | | opt = {"username": "admin", "password": "admin123"}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json' |
| | | }, |
| | | url: "../login", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | token = data.token; |
| | | getDeviceList();// è·å设å¤å表 |
| | | } |
| | | }) |
| | | // åå§åå
容 |
| | | console.log(cameraMap); |
| | | } |
| | | |
| | | //è·åè®¾å¤ |
| | | function getDeviceList() { |
| | | $.ajax({ |
| | | url: "../cameraSdk/list", |
| | | type: "get", |
| | | success: function (data) { |
| | | console.log(data); |
| | | var arr = data.data; |
| | | for (var i = 0; i < arr.length; i++) { |
| | | console.log(arr[i].id); |
| | | console.log(arr[i].name) |
| | | var camera = { |
| | | name: arr[i].name, |
| | | factory: arr[i].factory, |
| | | ipaddr: arr[i].ip, |
| | | username: arr[i].username, |
| | | password: arr[i].password, |
| | | port: arr[i].rtspPort, |
| | | longitude: arr[i].longitude, |
| | | latitude: arr[i].latitude, |
| | | altitude: arr[i].altitude |
| | | }; |
| | | cameraMap.set(arr[i].id, camera); |
| | | //å
å建好selectéé¢çoptionå
ç´ |
| | | var option = $("<option>"); |
| | | //ç»optionçtextèµå¼,è¿å°±æ¯ä½ ç¹å¼ä¸ææ¡è½å¤çå°çä¸è¥¿ |
| | | $(option).val(arr[i].id); |
| | | $(option).text(arr[i].name); |
| | | //è·åselect 䏿æ¡å¯¹è±¡,å¹¶å°optionæ·»å è¿select |
| | | $('#selectDev').append(option); |
| | | } |
| | | $("#selectDev").trigger("change"); |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //éæ©è®¾å¤ |
| | | $("#selectDev").change(function () { |
| | | // å¨è¿éå¤çéæ©äºä»¶ |
| | | var cameraId = $(this).find("option:selected").val(); |
| | | var name = $(this).find("option:selected").text(); |
| | | getChannelList(cameraId); |
| | | console.log("éæ©äºï¼" + cameraId + "---" + name); |
| | | }); |
| | | |
| | | //è·åéé |
| | | function getChannelList(cameraId) { |
| | | console.log(cameraId) |
| | | var myEntity = { |
| | | deviceId: cameraId, |
| | | pageNum: 1, |
| | | pageSize: 64 |
| | | } |
| | | var queryString = $.param(myEntity); |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../device/channel/list?" + queryString, |
| | | type: "get", |
| | | success: function (data) { |
| | | console.log(data); |
| | | var arr = data.rows; |
| | | $('#selectChn').empty(); |
| | | for (var i = 0; i < arr.length; i++) { |
| | | console.log(arr[i].chanNo); |
| | | console.log(arr[i].name); |
| | | //å
å建好selectéé¢çoptionå
ç´ |
| | | var option = document.createElement("option"); |
| | | //ç»optionçtextèµå¼,è¿å°±æ¯ä½ ç¹å¼ä¸ææ¡è½å¤çå°çä¸è¥¿ |
| | | $(option).text(arr[i].name); |
| | | $(option).val(arr[i].chanNo); |
| | | //è·åselect 䏿æ¡å¯¹è±¡,å¹¶å°optionæ·»å è¿select |
| | | $('#selectChn').append(option); |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | |
| | | //é¢è§ |
| | | $('#preview').click(() => { |
| | | var cameraId = $('#selectDev option:selected').val(); |
| | | var chanNo = $('#selectChn option:selected').val(); |
| | | console.log(cameraId + " " + chanNo) |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../vtdu/media/" + cameraId + "_" + chanNo, |
| | | type: "get", |
| | | dataType: "json", |
| | | success: function (data) { |
| | | realView(data.data.webrtcUrl + "/", "video"); |
| | | } |
| | | }) |
| | | }); |
| | | //忢 |
| | | $('#previewStop').click(() => { |
| | | webrtcClient.stop(); |
| | | }); |
| | | //äºå°ä¸ä¸å·¦å³ |
| | | $("#up").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 2; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | |
| | | }) |
| | | $("#up").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 2; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#down").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 8; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#down").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 8; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#left").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 4; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#left").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 4; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#right").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 6; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#right").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 6; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | //åå |
| | | $("#controlZoomIn").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 10; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlZoomIn").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 10; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlZoomOut").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 11; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlZoomOut").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 11; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | //åç¦ |
| | | $("#controlFocusNear").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 12; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlFocusNear").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 12; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlFocusFar").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 13; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlFocusFar").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 13; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | //å
å |
| | | $("#controlIrisOpen").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 14; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlIrisOpen").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 14; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlIrisClose").mousedown(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 15; |
| | | var enable = true; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | $("#controlIrisClose").mouseup(function () { |
| | | var url = "../cameraSdk/PTZControlWithSpeed"; |
| | | var code = 15; |
| | | var enable = false; |
| | | commondMethod(url, code, enable); |
| | | }) |
| | | |
| | | $("#setPreset").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 8, "presetIndex": 1}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/setPreset", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#gotoPreset").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 8, "presetIndex": 1}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/gotoPreset", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#getPTZ").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/getPTZ", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (datas) { |
| | | console.log(datas); |
| | | $("#p").val(datas.data.p); |
| | | $("#t").val(datas.data.t); |
| | | $("#z").val(datas.data.z); |
| | | } |
| | | }) |
| | | }) |
| | | $("#setPTZ").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | var p = $('#p').val(); |
| | | var t = $('#t').val(); |
| | | var z = $('#z').val(); |
| | | //å®ä¹ä¸ä¸ªå¸¦æMapåæ®µçå®ä½å¯¹è±¡ |
| | | var myEntity = { |
| | | chanNo: chanNo, |
| | | cameraId: cameraId, |
| | | ptzMap: { |
| | | p: p, |
| | | t: t, |
| | | z: z |
| | | } |
| | | }; |
| | | console.log(opt) |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/setPTZ", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(myEntity), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#setTargetPostion").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | var camera = cameraMap.get(cameraId); |
| | | var camP = camera.longitude + ',' + camera.latitude + ',' + camera.altitude; |
| | | var targetP = $('#targetPostion').val(); |
| | | var arr = targetP.split(","); |
| | | arr = arr.map(item => parseFloat(item)); |
| | | //å®ä¹ä¸ä¸ªå¸¦æMapåæ®µçå®ä½å¯¹è±¡ |
| | | var myEntity = { |
| | | chanNo: chanNo, |
| | | cameraId: cameraId, |
| | | targetPosition: arr |
| | | }; |
| | | console.log(myEntity) |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/setTargetPosition", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(myEntity), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#setZeroPTZ").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/setZeroPTZ", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#WiperPwron").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 8, "enable": true, "code": 16}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/PTZControlWithSpeed", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | }) |
| | | var defogflag = true; |
| | | $("#Defogcfg").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (defogflag) { |
| | | $(this).text("å
³ééé¾"); |
| | | defogflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/defogcfg", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | $(this).text("å¼å¯éé¾"); |
| | | defogflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/defogcfg", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | |
| | | }) |
| | | var infrareflag = true; |
| | | $("#Infrarecfg").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (infrareflag) { |
| | | $(this).text("å
³é红å¤"); |
| | | infrareflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/infrarecfg", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | |
| | | $(this).text("å¼å¯çº¢å¤"); |
| | | infrareflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/infrarecfg", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | var focusModeflag = true; |
| | | $("#FocusMode").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (focusModeflag) { |
| | | $(this).text("èªå¨èç¦"); |
| | | focusModeflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/focusMode", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | $(this).text("æå¨èç¦"); |
| | | focusModeflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/focusMode", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | $("#getFocusPos").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/getFocusPos", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (datas) { |
| | | console.log(datas); |
| | | $("#focus").val(datas.data); |
| | | } |
| | | }) |
| | | }) |
| | | var heateRpwronflag = true; |
| | | $("#HeateRpwron").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (heateRpwronflag) { |
| | | $(this).text("å
³éäºå°å ç"); |
| | | heateRpwronflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/heateRpwron", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | $(this).text("å¼å¯äºå°å ç"); |
| | | heateRpwronflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/heateRpwron", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | var CameraDeicingflag = true; |
| | | $("#CameraDeicing").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (CameraDeicingflag) { |
| | | $(this).text("å
³éé头å ç"); |
| | | CameraDeicingflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/cameraDeicing", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | $(this).text("å¼å¯é头å ç"); |
| | | CameraDeicingflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/cameraDeicing", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | $("#realCutPic").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/captureJPEGPicture", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data.data); |
| | | $("#imgContainer").attr("src", "data:image/png;base64," + data.data); |
| | | } |
| | | }) |
| | | }) |
| | | $("#saveCutPic").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/picCutCate", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data.data); |
| | | setTimeout(() => { |
| | | $('#imgContainer').attr('src', data.data); |
| | | }, 1000) |
| | | |
| | | } |
| | | }) |
| | | }) |
| | | var recordflag = true; |
| | | $("#record").click(function () { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | optOpen = {"cameraId": cameraId, "chanNo": chanNo, "enable": true}; |
| | | optClose = {"cameraId": cameraId, "chanNo": chanNo, "enable": false}; |
| | | if (recordflag) { |
| | | $(this).text("忢å½å"); |
| | | recordflag = false; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/record", |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(optOpen), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } else { |
| | | $(this).text("å¼å§å½å"); |
| | | recordflag = true; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../cameraSdk/record", |
| | | dataType: "json", |
| | | data: JSON.stringify(optClose), |
| | | type: "post", |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | var cameraMap = new Map(); |
| | | |
| | | /*äºå°å
Œ
±æ¹æ³*/ |
| | | function commondMethod(url, code, enable) { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 4, "enable": enable, "code": code}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: url, |
| | | type: "post", |
| | | dataType: "json", |
| | | data: JSON.stringify(opt), |
| | | success: function (data) { |
| | | console.log(data); |
| | | } |
| | | }) |
| | | } |
| | | |
| | | $('video').click(function (e) { |
| | | var cameraId = $('#selectDev option:selected').val(); |
| | | var chanNo = $('#selectChn option:selected').val(); |
| | | console.log(cameraId + " " + chanNo) |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | | 'Content-Type': 'application/json', |
| | | 'Authorization': token |
| | | }, |
| | | url: "../vtdu/media/" + cameraId + "_" + chanNo, |
| | | type: "get", |
| | | dataType: "json", |
| | | success: function (data) { |
| | | realView(data.data.webrtcUrl + "/", e.target.id); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | let webrtcClient; |
| | | //whepæä½æ¹æ³ |
| | | const restartPause = 2000; |
| | | const unquoteCredential = (v) => ( |
| | | JSON.parse(`"${v}"`) |
| | | ); |
| | | const linkToIceServers = (links) => ( |
| | | (links !== null) ? links.split(', ').map((link) => { |
| | | const m = link.match(/^<(.+?)>; rel="ice-server"(; username="(.*?)"; credential="(.*?)"; credential-type="password")?/i); |
| | | const ret = { |
| | | urls: [m[1]], |
| | | }; |
| | | |
| | | if (m[3] !== undefined) { |
| | | ret.username = unquoteCredential(m[3]); |
| | | ret.credential = unquoteCredential(m[4]); |
| | | ret.credentialType = "password"; |
| | | } |
| | | |
| | | return ret; |
| | | }) : [] |
| | | ); |
| | | const parseOffer = (offer) => { |
| | | const ret = { |
| | | iceUfrag: '', |
| | | icePwd: '', |
| | | medias: [], |
| | | }; |
| | | |
| | | for (const line of offer.split('\r\n')) { |
| | | if (line.startsWith('m=')) { |
| | | ret.medias.push(line.slice('m='.length)); |
| | | } else if (ret.iceUfrag === '' && line.startsWith('a=ice-ufrag:')) { |
| | | ret.iceUfrag = line.slice('a=ice-ufrag:'.length); |
| | | } else if (ret.icePwd === '' && line.startsWith('a=ice-pwd:')) { |
| | | ret.icePwd = line.slice('a=ice-pwd:'.length); |
| | | } |
| | | } |
| | | |
| | | return ret; |
| | | }; |
| | | const generateSdpFragment = (offerData, candidates) => { |
| | | const candidatesByMedia = {}; |
| | | for (const candidate of candidates) { |
| | | const mid = candidate.sdpMLineIndex; |
| | | if (candidatesByMedia[mid] === undefined) { |
| | | candidatesByMedia[mid] = []; |
| | | } |
| | | candidatesByMedia[mid].push(candidate); |
| | | } |
| | | |
| | | let frag = 'a=ice-ufrag:' + offerData.iceUfrag + '\r\n' |
| | | + 'a=ice-pwd:' + offerData.icePwd + '\r\n'; |
| | | |
| | | let mid = 0; |
| | | |
| | | for (const media of offerData.medias) { |
| | | if (candidatesByMedia[mid] !== undefined) { |
| | | frag += 'm=' + media + '\r\n' |
| | | + 'a=mid:' + mid + '\r\n'; |
| | | |
| | | for (const candidate of candidatesByMedia[mid]) { |
| | | frag += 'a=' + candidate.candidate + '\r\n'; |
| | | } |
| | | } |
| | | mid++; |
| | | } |
| | | |
| | | return frag; |
| | | } |
| | | |
| | | class WHEPClient { |
| | | constructor(whepUrl, videoId) { |
| | | this.video = videoId; |
| | | this.wurl = new URL('whep', whepUrl); |
| | | this.pc = null; |
| | | this.restartTimeout = null; |
| | | this.eTag = ''; |
| | | this.queuedCandidates = []; |
| | | this.start(); |
| | | } |
| | | |
| | | start() { |
| | | console.log("requesting ICE servers"); |
| | | fetch(this.wurl, { |
| | | method: 'OPTIONS', |
| | | }) |
| | | .then((res) => this.onIceServers(res)) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | }); |
| | | } |
| | | |
| | | onIceServers(res) { |
| | | this.pc = new RTCPeerConnection({ |
| | | iceServers: linkToIceServers(res.headers.get('Link')), |
| | | }); |
| | | |
| | | const direction = "sendrecv"; |
| | | this.pc.addTransceiver("video", {direction}); |
| | | this.pc.addTransceiver("audio", {direction}); |
| | | |
| | | this.pc.onicecandidate = (evt) => this.onLocalCandidate(evt); |
| | | this.pc.oniceconnectionstatechange = () => this.onConnectionState(); |
| | | |
| | | this.pc.ontrack = (evt) => { |
| | | console.log("new track:", evt.track.kind); |
| | | document.getElementById(this.video).srcObject = evt.streams[0]; |
| | | }; |
| | | |
| | | this.pc.createOffer() |
| | | .then((offer) => this.onLocalOffer(offer)); |
| | | } |
| | | |
| | | onLocalOffer(offer) { |
| | | this.offerData = parseOffer(offer.sdp); |
| | | this.pc.setLocalDescription(offer); |
| | | |
| | | console.log("sending offer"); |
| | | console.log(this.wurl); |
| | | fetch(this.wurl, { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/sdp', |
| | | }, |
| | | body: offer.sdp, |
| | | }) |
| | | .then((res) => { |
| | | if (res.status !== 201) { |
| | | throw new Error('bad status code'); |
| | | } |
| | | // this.eTag = res.headers.get('ETag'); |
| | | this.eTag = res.headers.get("ETag") || res.headers.get('E-Tag'); |
| | | return res.text(); |
| | | }) |
| | | .then((sdp) => this.onRemoteAnswer(new RTCSessionDescription({ |
| | | type: 'answer', |
| | | sdp, |
| | | }))) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | }); |
| | | } |
| | | |
| | | onConnectionState() { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | console.log("peer connection state:", this.pc.iceConnectionState); |
| | | |
| | | switch (this.pc.iceConnectionState) { |
| | | case "disconnected": |
| | | this.scheduleRestart(); |
| | | } |
| | | } |
| | | |
| | | onRemoteAnswer(answer) { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | this.pc.setRemoteDescription(new RTCSessionDescription(answer)); |
| | | |
| | | if (this.queuedCandidates.length !== 0) { |
| | | this.sendLocalCandidates(this.queuedCandidates); |
| | | this.queuedCandidates = []; |
| | | } |
| | | } |
| | | |
| | | onLocalCandidate(evt) { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | if (evt.candidate !== null) { |
| | | if (this.eTag === '') { |
| | | this.queuedCandidates.push(evt.candidate); |
| | | } else { |
| | | this.sendLocalCandidates([evt.candidate]) |
| | | } |
| | | } |
| | | } |
| | | |
| | | sendLocalCandidates(candidates) { |
| | | fetch(this.wurl, { |
| | | method: 'PATCH', |
| | | headers: { |
| | | 'Content-Type': 'application/trickle-ice-sdpfrag', |
| | | 'If-Match': this.eTag, |
| | | }, |
| | | |
| | | body: generateSdpFragment(this.offerData, candidates), |
| | | }) |
| | | .then((res) => { |
| | | if (res.status !== 204) { |
| | | throw new Error('bad status code'); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | console.log('error: ' + err); |
| | | this.scheduleRestart(); |
| | | }); |
| | | } |
| | | |
| | | scheduleRestart() { |
| | | if (this.restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | if (this.pc !== null) { |
| | | this.pc.close(); |
| | | this.pc = null; |
| | | } |
| | | |
| | | this.restartTimeout = window.setTimeout(() => { |
| | | this.restartTimeout = null; |
| | | this.start(); |
| | | }, restartPause); |
| | | |
| | | this.eTag = ''; |
| | | this.queuedCandidates = []; |
| | | } |
| | | |
| | | stop() { |
| | | if (this.pc) { |
| | | try { |
| | | this.pc.close(); |
| | | } catch (e) { |
| | | console.log("Failure close peer connection:" + e); |
| | | } |
| | | this.pc = null; |
| | | } |
| | | } |
| | | } |
| | | |
| | | function realView(whepUrl, videoId) { |
| | | console.log(whepUrl) |
| | | webrtcClient = new WHEPClient(whepUrl, videoId); |
| | | } |
| | | </script> |
| | | </body> |
| | | </html> |
| | |
| | |
|
| | | /**
|
| | | * @Author åèä¹
|
| | | * @Description 忥nvrééç¶æå®æ¶åæ¥æµåªä½
|
| | | * @Description 忥ééç¶æå®æ¶åæ¥æµåªä½
|
| | | * @Date 2024/7/9 16:01
|
| | | */
|
| | | public void nvrChannelState() {
|
| | | public void syncChannelState() {
|
| | | log.warn("宿¶åæ¥ééä»»å¡å¼å§");
|
| | | //è·åæænvr设å¤
|
| | | List<ArdCameras> ardCamerasList = iArdCamerasService.selectArdCamerasListNoDataScope(new ArdCameras());
|
| | | if (ardCamerasList.size() > 0) {
|
| | | ardCamerasList.stream()
|
| | | .filter(ardCameras -> ardCameras.getGdtype().equals("2"))
|
| | | .forEach(ardCameras -> {
|
| | | //éè¿SDKè·åNVRå½åéé
|
| | | //éè¿SDKè·åNVRå®é
éé
|
| | | CameraSDK cameraSDK = cameraSDKFactory.createCameraSDK(ardCameras.getFactory());
|
| | | List<ArdChannel> ardChannelList = cameraSDK.getChannels(ardCameras);
|
| | | //忥éé表
|
| | | ArdChannel ardChannel=new ArdChannel();
|
| | | ardChannel.setDeviceId(ardCameras.getId());
|
| | | List<ArdChannel> ardChannelListDb = ardChannelService.selectArdChannelList(ardChannel);
|
| | | ardChannelService.asyncChannel(ardChannelListDb,ardChannelList);
|
| | | //忥æµåªä½è¡¨
|
| | |
|
| | | //忥æµåªä½api
|
| | |
|
| | | ardChannelService.asyncChannel(ardCameras,ardChannelListDb,ardChannelList);
|
| | | });
|
| | | }
|
| | | }
|
| | |
| | | * åèä¹
|
| | | * 2023/10/13 14:13:53
|
| | | */
|
| | | public void vtdu() {
|
| | | public void syncVtdu() {
|
| | | log.warn("宿¶åæ¥æµåªä½ä»»å¡å¼å§");
|
| | | List<String> nameList = mediaService.getNameList();
|
| | | List<Vtdu> vtduList = vtduService.selectVtduList(new Vtdu());
|
| | | vtduService.asyncVtdu(vtduList,nameList);
|
| | | }
|
| | | }
|
| | | } |
| | |
| | | webrtcICEInterfaces: [] |
| | | # List of public IP addresses that are to be used as a host. |
| | | # This is used typically for servers that are behind 1:1 D-NAT. |
| | | webrtcICEHostNAT1To1IPs: [] |
| | | webrtcICEHostNAT1To1IPs: [192.168.1.227] |
| | | # Address of a ICE UDP listener in format host:port. |
| | | # If filled, ICE traffic will pass through a single UDP port, |
| | | # allowing the deployment of the server inside a container or behind a NAT. |
| | | webrtcICEUDPMuxAddress: |
| | | webrtcICEUDPMuxAddress: :8189 |
| | | # Address of a ICE TCP listener in format host:port. |
| | | # If filled, ICE traffic will pass through a single TCP port, |
| | | # allowing the deployment of the server inside a container or behind a NAT. |
| | | # Using this setting forces usage of the TCP protocol, which is not |
| | | # optimal for WebRTC. |
| | | webrtcICETCPMuxAddress: 192.168.1.227:19302 |
| | | webrtcICETCPMuxAddress: |
| | | |
| | | ############################################### |
| | | # Global settings -> SRT |