修复三方接口获取播放地址失败

This commit is contained in:
lin
2025-11-05 23:08:05 +08:00
parent 0ab50eb1c0
commit 0607e1c3b2
9 changed files with 88 additions and 36 deletions

View File

@@ -31,7 +31,7 @@ public class VideoManagerConstants {
public static final String SIP_INVITE_SESSION_CALL_ID = SIP_INVITE_SESSION + "CALL_ID:";
public static final String SIP_INVITE_SESSION_STREAM = SIP_INVITE_SESSION + "STREAM:";
public static final String MEDIA_STREAM_AUTHORITY = "VMP_MEDIA_STREAM_AUTHORITY:";
public static final String MEDIA_STREAM_AUTHORITY = "VMP_MEDIA_STREAM_AUTHORITY";
public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";

View File

@@ -461,7 +461,7 @@ public interface DeviceMapper {
void batchUpdate(List<Device> devices);
@Update(value = {" <script>" +
@Select(value = {" <script>" +
"SELECT " +
"coalesce(custom_name, name) as name, " +
"id" +

View File

@@ -603,7 +603,7 @@ public class ChannelProvider {
public String queryListForSy(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) AND coalesce(wdc.gb_parent_id, wdc.parent_id) = #{groupDeviceId}");
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) AND coalesce(wdc.gb_parent_id, wdc.parent_id) = #{groupDeviceId}");
if (params.get("online") != null && (Boolean)params.get("online")) {
sqlBuild.append(" AND coalesce(wdc.gb_status, wdc.status) = 'ON'");
}
@@ -618,7 +618,7 @@ public class ChannelProvider {
public String queryListWithChildForSy(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) ");
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) ");
List<CameraGroup> groupList = (List<CameraGroup>)params.get("groupList");
@@ -692,7 +692,7 @@ public class ChannelProvider {
public String queryListInBox(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
@@ -711,7 +711,7 @@ public class ChannelProvider {
sqlBuild.append(" AND coalesce(wdc.gb_latitude, wdc.latitude) >= #{minLatitude} AND coalesce(wdc.gb_latitude, wdc.latitude) <= #{maxLatitude}");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
sqlBuild.append(" AND ( map_level <= #{level} or map_level is null )");
}
return sqlBuild.toString();
@@ -720,7 +720,7 @@ public class ChannelProvider {
public String queryListInCircleForMysql(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
@@ -740,7 +740,7 @@ public class ChannelProvider {
sqlBuild.append("AND ST_Distance_Sphere(point(coalesce(wdc.gb_longitude, wdc.longitude), coalesce(wdc.gb_latitude, wdc.latitude)), ST_GeomFromText('").append(geomTextBuilder).append("')) < #{radius}");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
sqlBuild.append(" AND ( map_level <= #{level} or map_level is null )");
}
return sqlBuild.toString();
@@ -749,7 +749,7 @@ public class ChannelProvider {
public String queryListInCircleForKingBase(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
@@ -769,7 +769,7 @@ public class ChannelProvider {
sqlBuild.append("AND ST_DistanceSphere(ST_MakePoint(coalesce(wdc.gb_longitude, wdc.longitude), coalesce(wdc.gb_latitude, wdc.latitude)), ST_GeomFromText('").append(geomTextBuilder).append("')) < #{radius}");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
sqlBuild.append(" AND ( map_level <= #{level} or map_level is null )");
}
return sqlBuild.toString();
@@ -778,7 +778,7 @@ public class ChannelProvider {
public String queryListInPolygonForMysql(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
@@ -807,7 +807,7 @@ public class ChannelProvider {
sqlBuild.append("AND ST_Within(point(coalesce(wdc.gb_longitude, wdc.longitude), coalesce(wdc.gb_latitude, wdc.latitude)), ST_GeomFromText('").append(geomTextBuilder).append("'))");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
sqlBuild.append(" AND ( map_level <= #{level} or map_level is null )");
}
return sqlBuild.toString();
@@ -816,7 +816,7 @@ public class ChannelProvider {
public String queryListInPolygonForKingBase(Map<String, Object> params ){
StringBuilder sqlBuild = new StringBuilder();
sqlBuild.append(BASE_SQL_FOR_CAMERA_DEVICE);
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null || ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
sqlBuild.append(" where wdc.channel_type = 0 AND wdc.data_type != 2 AND (wdc.gb_ptz_type is null or ( wdc.gb_ptz_type != 98 AND wdc.gb_ptz_type != 99)) " +
" AND coalesce(wdc.gb_parent_id, wdc.parent_id) in (");
sqlBuild.append(" ");
@@ -845,7 +845,7 @@ public class ChannelProvider {
sqlBuild.append("AND ST_Within(ST_MakePoint(coalesce(wdc.gb_longitude, wdc.longitude), coalesce(wdc.gb_latitude, wdc.latitude)), ST_GeomFromText('").append(geomTextBuilder).append("'))");
if (params.get("level") != null) {
sqlBuild.append(" AND ( map_level <= #{level} || map_level is null )");
sqlBuild.append(" AND ( map_level <= #{level} or map_level is null )");
}
return sqlBuild.toString();

View File

@@ -997,8 +997,10 @@ public class GbChannelServiceImpl implements IGbChannelService {
// 最大层级不进行抽稀, 将未进行抽稀的数据直接存储到这个层级
for (CommonGBChannel channel : channelListInExtent) {
if (!useCameraMap.containsKey(channel.getGbId())) {
channel.setMapLevel(zoom);
// 这个的key跟后面的不一致是因为无需抽稀 直接存储原始数据
cameraMapForZoom.put(channel.getGbId() + "", channel);
useCameraMap.put(channel.getGbId(), channel);
}
}
}else {

View File

@@ -288,7 +288,7 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
switch (notifyCatalogChannel.getType()) {
case STATUS_CHANGED:
deviceChannelService.updateChannelStatusForNotify(notifyCatalogChannel.getChannel());
CommonGBChannel channelForStatus = channelService.queryBySourceChannelId(notifyCatalogChannel.getChannel());
CommonGBChannel channelForStatus = channelService.queryCommonChannelByDeviceChannel(notifyCatalogChannel.getChannel());
if ("ON".equals(notifyCatalogChannel.getChannel().getStatus()) ) {
eventPublisher.channelEventPublish(channelForStatus, ChannelEvent.ChannelEventMessageType.ON);
}else {

View File

@@ -125,6 +125,10 @@ public class MobilePositionServiceImpl implements IMobilePositionService {
updateChannelMap.get(mobilePosition.getDeviceId()).put(mobilePosition.getChannelId(), deviceChannel);
}
List<String> deviceIds = new ArrayList<>(updateChannelMap.keySet());
if (deviceIds.isEmpty()) {
log.info("[移动位置订阅]为查询到对应的设备,消息已经忽略");
return;
}
List<Device> deviceList = deviceMapper.queryByDeviceIds(deviceIds);
for (Device device : deviceList) {
Map<Integer, DeviceChannel> channelMap = updateChannelMap.get(device.getDeviceId());

View File

@@ -15,7 +15,9 @@ import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.streamProxy.service.IStreamProxyService;
import com.genersoft.iot.vmp.streamPush.bean.StreamPush;
import com.genersoft.iot.vmp.streamPush.service.IStreamPushPlayService;
import com.genersoft.iot.vmp.streamPush.service.IStreamPushService;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.HttpUtils;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
@@ -80,7 +82,7 @@ public class CameraChannelController {
private DynamicTask dynamicTask;
@Autowired
private IStreamProxyService streamProxyService;
private IStreamPushService streamPushService;
@Value("${sy.ptz-control-time-interval}")
private int ptzControlTimeInterval = 300;
@@ -349,10 +351,13 @@ public class CameraChannelController {
@Parameter(name = "callId", description = "推流时携带的自定义鉴权ID", required = true)
@GetMapping(value = "/push/play")
@ResponseBody
public StreamContent getStreamInfoByAppAndStream(HttpServletRequest request,
public DeferredResult<WVPResult<StreamContent>> getStreamInfoByAppAndStream(HttpServletRequest request,
String app,
String stream,
String callId){
StreamPush streamPush = streamPushService.getPush(app, stream);
Assert.notNull(streamPush, "地址不存在");
// 权限校验
StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(app, stream);
if (streamAuthorityInfo == null
@@ -360,6 +365,16 @@ public class CameraChannelController {
|| !streamAuthorityInfo.getCallId().equals(callId)) {
throw new ControllerException(ErrorCode.ERROR100.getCode(), "播放地址鉴权失败");
}
DeferredResult<WVPResult<StreamContent>> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
result.onTimeout(()->{
WVPResult<StreamContent> fail = WVPResult.fail(ErrorCode.ERROR100.getCode(), "等待推流超时");
result.setResult(fail);
});
streamPushPlayService.start(streamPush.getId(), (code, msg, streamInfo) -> {
if (code == 0 && streamInfo != null) {
streamInfo=streamInfo.clone();//深拷贝
String host;
try {
URL url=new URL(request.getRequestURL().toString());
@@ -367,9 +382,12 @@ public class CameraChannelController {
} catch (MalformedURLException e) {
host=request.getLocalAddr();
}
StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStreamWithCheck(app, stream, null, host, true);
Assert.notNull(streamInfo, "地址不存在");
return new StreamContent(streamInfo);
streamInfo.changeStreamIp(host);
WVPResult<StreamContent> success = WVPResult.success(new StreamContent(streamInfo));
result.setResult(success);
}
}, null, null);
return result;
}
@ResponseBody

View File

@@ -45,10 +45,10 @@ public class SignAuthenticationFilter extends OncePerRequestFilter {
chain.doFilter(request, response);
return;
}
// if (request.getParameter("ccerty") != null) {
// chain.doFilter(request, response);
// return;
// }
if (request.getParameter("ccerty") != null) {
chain.doFilter(request, response);
return;
}
// 设置响应内容类型
response.setContentType("application/json;charset=UTF-8");

View File

@@ -18,6 +18,9 @@
<el-form-item label="流ID" prop="stream">
<el-input v-model="stream" autocomplete="off" />
</el-form-item>
<el-form-item label="CallID" prop="stream">
<el-input v-model="callId" autocomplete="off" />
</el-form-item>
<el-form-item label="媒体节点" prop="mediaServerId">
<el-select v-model="mediaServer" placeholder="请选择" style="width: 100%">
<el-option
@@ -80,6 +83,7 @@ export default {
showDialog: false,
app: null,
stream: null,
callId: null,
mediaServer: null,
mediaServerList: [],
pushKey: null,
@@ -91,33 +95,57 @@ export default {
if (!this.pushKey) {
return ''
}
if (this.callId) {
return crypto.createHash('md5').update(this.callId + '_' + this.pushKey, 'utf8').digest('hex')
}else {
return crypto.createHash('md5').update(this.pushKey, 'utf8').digest('hex')
}
},
rtsp(){
if (!this.mediaServer || !this.stream || !this.app) {
return ''
}
crypto.createHash('md5').update(this.pushKey, 'utf8').digest('hex')
if (this.callId) {
return `rtsp://${this.mediaServer.streamIp}:${this.mediaServer.rtspPort}/${this.app}/${this.stream}?callId=${this.callId}&sign=${this.sign}`
}else {
return `rtsp://${this.mediaServer.streamIp}:${this.mediaServer.rtspPort}/${this.app}/${this.stream}?sign=${this.sign}`
}
},
rtmp(){
if (!this.mediaServer || !this.stream || !this.app) {
return ''
}
if (this.callId) {
return `rtmp://${this.mediaServer.streamIp}:${this.mediaServer.rtmpPort}/${this.app}/${this.stream}?callId=${this.callId}&sign=${this.sign}`
}else {
return `rtmp://${this.mediaServer.streamIp}:${this.mediaServer.rtmpPort}/${this.app}/${this.stream}?sign=${this.sign}`
}
},
rtc(){
if (!this.mediaServer || !this.stream || !this.app) {
return ''
}
if (this.callId) {
return `http://${this.mediaServer.streamIp}:${this.mediaServer.httpPort}/index/api/webrtc?app=${this.app}&stream=${this.stream}&callId=${this.callId}&sign=${this.sign}`
}else {
return `http://${this.mediaServer.streamIp}:${this.mediaServer.httpPort}/index/api/webrtc?app=${this.app}&stream=${this.stream}&sign=${this.sign}`
}
},
rtcs(){
if (!this.mediaServer || !this.stream || !this.app) {
return ''
}
if (this.callId) {
return `https://${this.mediaServer.streamIp}:${this.mediaServer.httpSSlPort}/index/api/webrtc?app=${this.app}&stream=${this.stream}&callId=${this.callId}&sign=${this.sign}`
}else {
return `https://${this.mediaServer.streamIp}:${this.mediaServer.httpSSlPort}/index/api/webrtc?app=${this.app}&stream=${this.stream}&sign=${this.sign}`
}
}
},
created() {
this.initData()