Merge branch 'master' into 1078

This commit is contained in:
648540858
2024-03-13 16:46:21 +08:00
17 changed files with 129 additions and 157 deletions

View File

@@ -1,130 +0,0 @@
#很久没维护了,已经与定前版本不匹配
FROM ubuntu:20.04 AS build
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
EXPOSE 18080/tcp
EXPOSE 5060/tcp
EXPOSE 5060/udp
EXPOSE 6379/tcp
EXPOSE 18081/tcp
EXPOSE 80/tcp
EXPOSE 1935/tcp
EXPOSE 554/tcp
EXPOSE 554/udp
EXPOSE 30000-30500/tcp
EXPOSE 30000-30500/udp
ENV LC_ALL zh_CN.UTF-8
# 使用了自己的settings.xml作为maven的源,加快打包速度
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" && \
apt-get install -y --no-install-recommends openjdk-11-jre git maven nodejs npm build-essential tcl language-pack-zh-hans \
cmake curl vim ca-certificates tzdata libmysqlclient-dev redis-server libssl-dev libx264-dev libfaac-dev ffmpeg
WORKDIR /home
RUN git clone https://gitee.com/pan648540858/maven.git && \
cp maven/settings.xml /usr/share/maven/conf/ && \
git clone https://gitee.com/pan648540858/wvp-GB28181.git && \
git clone https://gitee.com/pan648540858/wvp-pro-assist.git
# 编译前端界面
WORKDIR /home/wvp-GB28181/web_src
RUN npm install && \
npm run build && \
mkdir -p /opt/wvp/config && \
mkdir -p /opt/assist/config && \
cp /home/wvp-GB28181/src/main/resources/application-dev.yml /opt/wvp/config/application.yml && \
cp /home/wvp-pro-assist/src/main/resources/application-dev.yml /opt/assist/config/application.yml
# wvp打包
WORKDIR /home/wvp-GB28181
RUN mvn compile && \
mvn package && \
cp /home/wvp-GB28181/target/wvp*.jar /opt/wvp/
# wvp 录像管理打包
WORKDIR /home/wvp-pro-assist
RUN mvn compile && \
mvn package && \
cp /home/wvp-pro-assist/target/*.jar /opt/assist/
# zlm打包
WORKDIR /home
RUN mkdir -p /opt/media && \
git clone --depth=1 https://gitee.com/xia-chu/ZLMediaKit && \
cd ZLMediaKit && git submodule update --init --recursive && \
mkdir -p build release/linux/Release/ &&\
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 && \
rm -rf ../release/linux/Release/config.ini && \
cp -r ../release/linux/Release/* /opt/media && \
mkdir -p /opt/media/www/record
# 清理
RUN rm -rf /home/wiki && \
rm -rf /home/wvp-GB28181 && \
apt-get autoremove -y git maven nodejs npm && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*dic
WORKDIR /opt/wvp
RUN echo '#!/bin/bash' > run.sh && \
echo 'echo ${WVP_IP}' >> run.sh && \
echo 'echo ${WVP_CONFIG}' >> run.sh && \
echo 'redis-server --daemonize yes --bind 0.0.0.0' >> run.sh && \
echo 'cd /opt/assist' >> run.sh && \
echo 'nohup java -jar *.jar --userSettings.record=/opt/media/www/record/ &' >> run.sh && \
echo 'nohup /opt/media/MediaServer -d -m 3 &' >> run.sh && \
echo 'cd /opt/wvp' >> run.sh && \
echo 'if [-n "${WVP_CONFIG}"]; then' >> run.sh && \
echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 ${WVP_CONFIG}' >> run.sh && \
echo 'else' >> run.sh && \
echo ' java -jar *.jar --spring.config.location=/opt/wvp/config/application.yml --media.record-assist-port=18081 --media.ip=127.0.0.1 --media.sdp-ip=${WVP_IP} --sip.ip=${WVP_IP} --media.stream-ip=${WVP_IP}' >> run.sh && \
echo 'fi' >> run.sh
RUN chmod +x run.sh
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
EXPOSE 18080/tcp
EXPOSE 5060/tcp
EXPOSE 5060/udp
EXPOSE 6379/tcp
EXPOSE 18081/tcp
EXPOSE 80/tcp
EXPOSE 1935/tcp
EXPOSE 554/tcp
EXPOSE 554/udp
EXPOSE 30000-30500/tcp
EXPOSE 30000-30500/udp
ENV LC_ALL zh_CN.UTF-8
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" && \
apt-get install -y --no-install-recommends openjdk-11-jre tcl language-pack-zh-hans \
ca-certificates tzdata libmysqlclient21 redis-server libssl1.1 libx264-155 libfaac0 ffmpeg && \
apt-get autoremove -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*dic
WORKDIR /opt/wvp
COPY --from=build /opt /opt
CMD ["sh", "run.sh"]

38
pom.xml
View File

@@ -382,6 +382,44 @@
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<excludes>
<exclude>**/all-application.yml</exclude>
<exclude>**/application.yml</exclude>
<exclude>**/application-*.yml</exclude>
<exclude>**/local.jks</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution> <!-- 复制配置文件 -->
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application.yml</include>
<include>application-*.yml</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>

View File

@@ -25,6 +25,7 @@ public class AudioBroadcastManager {
public void update(AudioBroadcastCatch audioBroadcastCatch) {
if (SipUtils.isFrontEnd(audioBroadcastCatch.getDeviceId())) {
audioBroadcastCatch.setChannelId(audioBroadcastCatch.getDeviceId());
data.put(audioBroadcastCatch.getDeviceId(), audioBroadcastCatch);
}else {
data.put(audioBroadcastCatch.getDeviceId() + audioBroadcastCatch.getChannelId(), audioBroadcastCatch);

View File

@@ -977,7 +977,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
}
if (device != null) {
logger.info("收到设备" + requesterId + "的语音广播Invite请求");
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + broadcastCatch.getChannelId();
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId();
if (!SipUtils.isFrontEnd(device.getDeviceId())) {
key += broadcastCatch.getChannelId();
}
dynamicTask.stop(key);
try {
responseAck(request, Response.TRYING);

View File

@@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.response.ResponseMessageHandler;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
import com.genersoft.iot.vmp.service.IPlayService;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element;
@@ -77,7 +78,10 @@ public class BroadcastResponseMessageHandler extends SIPRequestProcessorParent i
audioBroadcastCatch.setStatus(AudioBroadcastCatchStatus.WaiteInvite);
audioBroadcastManager.update(audioBroadcastCatch);
// 等待invite消息 超时则结束
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId() + channelId;
String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId();
if (!SipUtils.isFrontEnd(device.getDeviceId())) {
key += audioBroadcastCatch.getChannelId();
}
dynamicTask.startDelay(key, ()->{
logger.info("[语音广播]等待invite消息超时{}/{}", device.getDeviceId(), channelId);
playService.stopAudioBroadcast(device.getDeviceId(), channelId);

View File

@@ -7,6 +7,7 @@ import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.github.pagehelper.PageInfo;
import java.util.List;
import java.util.Map;
/**
* 级联国标平台关联流业务接口
@@ -71,4 +72,7 @@ public interface IGbStreamService {
void delAllPlatformInfo(String platformId, String catalogId);
List<GbStream> getGbChannelWithGbid(String gbId);
Map<String, GbStream> getAllGBId();
}

View File

@@ -115,4 +115,7 @@ public interface IStreamPushService {
*/
ResourceBaseInfo getOverview();
Map<String, StreamPushItem> getAllAppAndStreamMap();
}

View File

@@ -575,8 +575,8 @@ public class DeviceServiceImpl implements IDeviceService {
}else if (device.getSubscribeCycleForMobilePosition() == 0) {
// 取消订阅
deviceInStore.setSubscribeCycleForCatalog(0);
removeCatalogSubscribe(deviceInStore, null);
deviceInStore.setSubscribeCycleForMobilePosition(0);
removeMobilePositionSubscribe(deviceInStore, null);
}
}
if (deviceInStore.getGeoCoordSys() != null) {

View File

@@ -19,11 +19,11 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@DS("master")
@@ -268,4 +268,9 @@ public class GbStreamServiceImpl implements IGbStreamService {
public List<GbStream> getGbChannelWithGbid(String gbId) {
return gbStreamMapper.selectByGBId(gbId);
}
@Override
public Map<String, GbStream> getAllGBId() {
return gbStreamMapper.getAllGBId();
}
}

View File

@@ -548,4 +548,9 @@ public class StreamPushServiceImpl implements IStreamPushService {
return new ResourceBaseInfo(total, online);
}
@Override
public Map<String, StreamPushItem> getAllAppAndStreamMap() {
return streamPushMapper.getAllAppAndStreamMap();
}
}

View File

@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.service.redisMsg;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.media.zlm.dto.StreamPushItem;
import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.service.IMediaServerService;
@@ -19,6 +20,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -57,7 +59,8 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener {
try {
List<StreamPushItem> streamPushItems = JSON.parseArray(new String(msg.getBody()), StreamPushItem.class);
//查询全部的app+stream 用于判断是添加还是修改
List<String> allAppAndStream = streamPushService.getAllAppAndStream();
Map<String, StreamPushItem> allAppAndStream = streamPushService.getAllAppAndStreamMap();
Map<String, GbStream> allGBId = gbStreamService.getAllGBId();
/**
* 用于存储更具APP+Stream过滤后的数据可以直接存入stream_push表与gb_stream表
@@ -67,9 +70,15 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener {
for (StreamPushItem streamPushItem : streamPushItems) {
String app = streamPushItem.getApp();
String stream = streamPushItem.getStream();
boolean contains = allAppAndStream.contains(app + stream);
boolean contains = allAppAndStream.containsKey(app + stream);
//不存在就添加
if (!contains) {
if (allGBId.containsKey(streamPushItem.getGbId())) {
GbStream gbStream = allGBId.get(streamPushItem.getGbId());
logger.warn("[REDIS消息-推流设备列表更新-INSERT] 国标编号重复: {}, 已分配给{}/{}",
streamPushItem.getGbId(), gbStream.getApp(), gbStream.getStream());
continue;
}
streamPushItem.setStreamType("push");
streamPushItem.setCreateTime(DateUtil.getNow());
streamPushItem.setMediaServerId(mediaServerService.getDefaultMediaServer().getId());
@@ -77,25 +86,31 @@ public class RedisPushStreamStatusListMsgListener implements MessageListener {
streamPushItem.setOriginTypeStr("rtsp_push");
streamPushItem.setTotalReaderCount("0");
streamPushItemForSave.add(streamPushItem);
allGBId.put(streamPushItem.getGbId(), streamPushItem);
} else {
if (allGBId.containsKey(streamPushItem.getGbId())) {
GbStream gbStream = allGBId.get(streamPushItem.getGbId());
logger.warn("[REDIS消息-推流设备列表更新-UPDATE] 国标编号重复: {}, 已分配给{}/{}",
streamPushItem.getGbId(), gbStream.getApp(), gbStream.getStream());
continue;
}
//存在就只修改 name和gbId
streamPushItemForUpdate.add(streamPushItem);
}
}
if (streamPushItemForSave.size() > 0) {
if (!streamPushItemForSave.isEmpty()) {
logger.info("添加{}条",streamPushItemForSave.size());
logger.info(JSONObject.toJSONString(streamPushItemForSave));
streamPushService.batchAdd(streamPushItemForSave);
}
if(streamPushItemForUpdate.size()>0){
if(!streamPushItemForUpdate.isEmpty()){
logger.info("修改{}条",streamPushItemForUpdate.size());
logger.info(JSONObject.toJSONString(streamPushItemForUpdate));
gbStreamService.updateGbIdOrName(streamPushItemForUpdate);
}
}catch (Exception e) {
logger.warn("[REDIS消息-推流设备列表更新] 发现未处理的异常, \r\n{}", JSON.toJSONString(message));
logger.warn("[REDIS消息-推流设备列表更新] 发现未处理的异常, \r\n{}", new String(message.getBody()));
logger.error("[REDIS消息-推流设备列表更新] 异常内容: ", e);
}
}

View File

@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
@@ -170,4 +171,7 @@ public interface GbStreamMapper {
@Select("SELECT status FROM wvp_stream_push WHERE app=#{app} AND stream=#{stream}")
Boolean selectStatusForPush(@Param("app") String app, @Param("stream") String stream);
@MapKey("gbId")
@Select("SELECT * from wvp_gb_stream")
Map<String, GbStream> getAllGBId();
}

View File

@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
@@ -195,4 +196,12 @@ public interface StreamPushMapper {
"</foreach>" +
"</script>")
List<StreamPushItem> getListIn(List<StreamPushItem> streamPushItems);
@MapKey("vhost")
@Select("SELECT CONCAT(wsp.app, wsp.stream) as vhost, wsp.app, wsp.stream, wgs.gb_id, wgs.name " +
" from wvp_stream_push wsp " +
" left join wvp_gb_stream wgs on wgs.app = wsp.app and wgs.stream = wsp.stream")
Map<String, StreamPushItem> getAllAppAndStreamMap();
}

View File

@@ -3,10 +3,9 @@ package com.genersoft.iot.vmp.vmanager.gb28181.gbStream;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
import com.genersoft.iot.vmp.conf.security.JwtUtils;
import com.genersoft.iot.vmp.gb28181.bean.GbStream;
import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
import com.genersoft.iot.vmp.service.IGbStreamService;
import com.genersoft.iot.vmp.service.IPlatformService;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.service.IStreamPushService;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.gb28181.gbStream.bean.GbStreamParam;
import com.github.pagehelper.PageInfo;
@@ -20,7 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Tag(name = "视频流关联到级联平台")
@@ -34,6 +32,9 @@ public class GbStreamController {
@Autowired
private IGbStreamService gbStreamService;
@Autowired
private IStreamPushService service;
@Autowired
private IPlatformService platformService;

View File

@@ -100,9 +100,9 @@
<span v-show="!scope.row.edit">{{ scope.row.location }}</span>
</template>
</el-table-column>
<el-table-column prop="PTZType" label="云台类型" min-width="100">
<el-table-column prop="ptztype" label="云台类型" min-width="100">
<template v-slot:default="scope">
<el-select v-show="scope.row.edit" v-model="scope.row.PTZType"
<el-select v-show="scope.row.edit" v-model="scope.row.ptztype"
placeholder="云台类型" filterable>
<el-option
v-for="(value, key) in ptzTypes"
@@ -111,7 +111,7 @@
:value="key"
/>
</el-select>
<div v-show="!scope.row.edit">{{ scope.row.PTZTypeText }}</div>
<div v-show="!scope.row.edit">{{ scope.row.ptztypeText }}</div>
</template>
</el-table-column>
<el-table-column label="开启音频" min-width="100">
@@ -312,7 +312,7 @@ export default {
that.total = res.data.data.total;
that.deviceChannelList = res.data.data.list;
that.deviceChannelList.forEach(e => {
e.PTZType = e.PTZType + "";
e.ptztype = e.ptztype + "";
that.$set(e, "edit", false);
that.$set(e, "location", "");
if (e.longitude && e.latitude) {
@@ -460,7 +460,7 @@ export default {
this.total = res.data.data.total;
this.deviceChannelList = res.data.data.list;
this.deviceChannelList.forEach(e => {
e.PTZType = e.PTZType + "";
e.ptztype = e.ptztype + "";
this.$set(e, "edit", false);
this.$set(e, "location", "");
if (e.longitude && e.latitude) {

View File

@@ -1,6 +1,6 @@
<template>
<div ref="container" @dblclick="fullscreenSwich"
style="width:100%;height:518px; min-height: 200px;background-color: #000000;margin:0 auto;position: relative;">
style="width:100%; height: 100%; background-color: #000000;margin:0 auto;position: relative;">
<div class="buttons-box" id="buttonsBox">
<div class="buttons-box-left">
<i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
@@ -49,16 +49,23 @@ export default {
created() {
let paramUrl = decodeURIComponent(this.$route.params.url)
this.$nextTick(() => {
console.log(2222)
this.updatePlayerDomSize()
window.onresize = () => {
this.updatePlayerDomSize()
}
window.onresize = this.updatePlayerDomSize
if (typeof (this.videoUrl) == "undefined") {
this.videoUrl = paramUrl;
}
this.btnDom = document.getElementById("buttonsBox");
})
},
// mounted() {
// const ro = new ResizeObserver(entries => {
// entries.forEach(entry => {
// this.updatePlayerDomSize()
// });
// });
// ro.observe(this.$refs.container);
// },
watch: {
videoUrl: {
handler(val, _) {
@@ -74,15 +81,18 @@ export default {
let dom = this.$refs.container;
let width = dom.parentNode.clientWidth
let height = (9 / 16) * width
console.log(height)
const clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight)
if (height > clientHeight) {
height = clientHeight
console.log(dom.clientHeight)
if (height > dom.clientHeight) {
height = dom.clientHeight
width = (16 / 9) * height
}
if (width > 0 && height > 0) {
dom.style.width = width + 'px';
dom.style.height = height + "px";
console.log(width)
console.log(height)
}
},
create() {

View File

@@ -7,7 +7,7 @@
v-if="Object.keys(this.player).length > 1">
<el-tab-pane label="Jessibuca" name="jessibuca">
<jessibucaPlayer v-if="activePlayer === 'jessibuca'" ref="jessibuca" :visible.sync="showVideoDialog"
:videoUrl="videoUrl" :error="videoError" :message="videoError" height="100px"
:videoUrl="videoUrl" :error="videoError" :message="videoError" style="height: 515px"
:hasAudio="hasAudio" fluent autoplay live></jessibucaPlayer>
</el-tab-pane>
<el-tab-pane label="WebRTC" name="webRTC">