修复编辑通道编号后无法点播的BUG
parent
fa063b3fda
commit
875285418b
|
@ -201,8 +201,7 @@ public class GBRecordController {
|
||||||
try {
|
try {
|
||||||
cmder.streamByeCmd(device, channelId, stream, null);
|
cmder.streamByeCmd(device, channelId, stream, null);
|
||||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||||
log.error("[停止历史媒体下载]停止历史媒体下载,发送BYE失败 {}", e.getMessage());
|
log.warn("[停止历史媒体下载]停止历史媒体下载,发送BYE失败 {}", e.getMessage());
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,11 +165,11 @@ public class PlayController {
|
||||||
}
|
}
|
||||||
|
|
||||||
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
Device device = deviceService.getDeviceByDeviceId(deviceId);
|
||||||
DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
|
DeviceChannel channel = deviceChannelService.getOneForSource(deviceId, channelId);
|
||||||
Assert.notNull(device, "设备不存在");
|
Assert.notNull(device, "设备不存在");
|
||||||
Assert.notNull(channel, "通道不存在");
|
Assert.notNull(channel, "通道不存在");
|
||||||
|
String streamId = String.format("%s_%s", device.getDeviceId(), channel.getDeviceId());
|
||||||
playService.stopPlay(device, channel);
|
playService.stop(InviteSessionType.PLAY, device, channel, streamId);
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
json.put("deviceId", deviceId);
|
json.put("deviceId", deviceId);
|
||||||
json.put("channelId", channelId);
|
json.put("channelId", channelId);
|
||||||
|
|
|
@ -6,17 +6,16 @@ import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ServiceException;
|
import com.genersoft.iot.vmp.conf.exception.ServiceException;
|
||||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
|
||||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IPlayService;
|
import com.genersoft.iot.vmp.gb28181.service.IPlayService;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||||
|
@ -159,11 +158,11 @@ public class PlaybackController {
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + " 未找到");
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "设备:" + deviceId + " 未找到");
|
||||||
}
|
}
|
||||||
try {
|
DeviceChannel deviceChannel = channelService.getOneForSource(deviceId, channelId);
|
||||||
cmder.streamByeCmd(device, channelId, stream, null);
|
if (deviceChannel == null) {
|
||||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "通道:" + deviceChannel + " 未找到");
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "发送bye失败: " + e.getMessage());
|
|
||||||
}
|
}
|
||||||
|
playService.stop(InviteSessionType.PLAYBACK, device, deviceChannel, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -743,6 +743,57 @@ public interface DeviceChannelMapper {
|
||||||
" </script>"})
|
" </script>"})
|
||||||
DeviceChannel getOne(@Param("id") int id);
|
DeviceChannel getOne(@Param("id") int id);
|
||||||
|
|
||||||
|
@Select(value = {" <script>" +
|
||||||
|
" SELECT " +
|
||||||
|
" id,\n" +
|
||||||
|
" device_db_id,\n" +
|
||||||
|
" create_time,\n" +
|
||||||
|
" update_time,\n" +
|
||||||
|
" sub_count,\n" +
|
||||||
|
" stream_id,\n" +
|
||||||
|
" has_audio,\n" +
|
||||||
|
" gps_time,\n" +
|
||||||
|
" stream_identification,\n" +
|
||||||
|
" channel_type,\n" +
|
||||||
|
" device_id,\n" +
|
||||||
|
" name,\n" +
|
||||||
|
" manufacturer,\n" +
|
||||||
|
" model,\n" +
|
||||||
|
" owner,\n" +
|
||||||
|
" civil_code,\n" +
|
||||||
|
" block,\n" +
|
||||||
|
" address,\n" +
|
||||||
|
" parental,\n" +
|
||||||
|
" parent_id,\n" +
|
||||||
|
" safety_way,\n" +
|
||||||
|
" register_way,\n" +
|
||||||
|
" cert_num,\n" +
|
||||||
|
" certifiable,\n" +
|
||||||
|
" err_code,\n" +
|
||||||
|
" end_time,\n" +
|
||||||
|
" secrecy,\n" +
|
||||||
|
" ip_address,\n" +
|
||||||
|
" port,\n" +
|
||||||
|
" password,\n" +
|
||||||
|
" status,\n" +
|
||||||
|
" longitude,\n" +
|
||||||
|
" latitude,\n" +
|
||||||
|
" ptz_type,\n" +
|
||||||
|
" position_type,\n" +
|
||||||
|
" room_type,\n" +
|
||||||
|
" use_type,\n" +
|
||||||
|
" supply_light_type,\n" +
|
||||||
|
" direction_type,\n" +
|
||||||
|
" resolution,\n" +
|
||||||
|
" business_group_id,\n" +
|
||||||
|
" download_speed,\n" +
|
||||||
|
" svc_space_support_mod,\n" +
|
||||||
|
" svc_time_support_mode\n" +
|
||||||
|
" from wvp_device_channel " +
|
||||||
|
" where id=#{id}" +
|
||||||
|
" </script>"})
|
||||||
|
DeviceChannel getOneForSource(@Param("id") int id);
|
||||||
|
|
||||||
@Select(value = {" <script>" +
|
@Select(value = {" <script>" +
|
||||||
" SELECT " +
|
" SELECT " +
|
||||||
" id,\n" +
|
" id,\n" +
|
||||||
|
@ -795,6 +846,58 @@ public interface DeviceChannelMapper {
|
||||||
DeviceChannel getOneByDeviceId(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
DeviceChannel getOneByDeviceId(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
||||||
|
|
||||||
|
|
||||||
|
@Select(value = {" <script>" +
|
||||||
|
" SELECT " +
|
||||||
|
" id,\n" +
|
||||||
|
" device_db_id,\n" +
|
||||||
|
" create_time,\n" +
|
||||||
|
" update_time,\n" +
|
||||||
|
" sub_count,\n" +
|
||||||
|
" stream_id,\n" +
|
||||||
|
" has_audio,\n" +
|
||||||
|
" gps_time,\n" +
|
||||||
|
" stream_identification,\n" +
|
||||||
|
" channel_type,\n" +
|
||||||
|
" device_id,\n" +
|
||||||
|
" name,\n" +
|
||||||
|
" manufacturer,\n" +
|
||||||
|
" model,\n" +
|
||||||
|
" owner,\n" +
|
||||||
|
" civil_code,\n" +
|
||||||
|
" block,\n" +
|
||||||
|
" address,\n" +
|
||||||
|
" parental,\n" +
|
||||||
|
" parent_id,\n" +
|
||||||
|
" safety_way,\n" +
|
||||||
|
" register_way,\n" +
|
||||||
|
" cert_num,\n" +
|
||||||
|
" certifiable,\n" +
|
||||||
|
" err_code,\n" +
|
||||||
|
" end_time,\n" +
|
||||||
|
" secrecy,\n" +
|
||||||
|
" ip_address,\n" +
|
||||||
|
" port,\n" +
|
||||||
|
" password,\n" +
|
||||||
|
" status,\n" +
|
||||||
|
" longitude,\n" +
|
||||||
|
" latitude,\n" +
|
||||||
|
" ptz_type,\n" +
|
||||||
|
" position_type,\n" +
|
||||||
|
" room_type,\n" +
|
||||||
|
" use_type,\n" +
|
||||||
|
" supply_light_type,\n" +
|
||||||
|
" direction_type,\n" +
|
||||||
|
" resolution,\n" +
|
||||||
|
" business_group_id,\n" +
|
||||||
|
" download_speed,\n" +
|
||||||
|
" svc_space_support_mod,\n" +
|
||||||
|
" svc_time_support_mode\n" +
|
||||||
|
" from wvp_device_channel " +
|
||||||
|
" where device_db_id=#{deviceDbId} and coalesce(gb_device_id, device_id) = #{channelId}" +
|
||||||
|
" </script>"})
|
||||||
|
DeviceChannel getOneByDeviceIdForSource(@Param("deviceDbId") int deviceDbId, @Param("channelId") String channelId);
|
||||||
|
|
||||||
|
|
||||||
@Update(value = {"UPDATE wvp_device_channel SET stream_id=null WHERE id=#{channelId}"})
|
@Update(value = {"UPDATE wvp_device_channel SET stream_id=null WHERE id=#{channelId}"})
|
||||||
void stopPlayById(@Param("channelId") Integer channelId);
|
void stopPlayById(@Param("channelId") Integer channelId);
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,10 @@ public class MobilePositionEventLister implements ApplicationListener<MobilePosi
|
||||||
List<Platform> parentPlatformsForGB = platformChannelService.queryPlatFormListByChannelDeviceId(event.getMobilePosition().getChannelId(), platforms);
|
List<Platform> parentPlatformsForGB = platformChannelService.queryPlatFormListByChannelDeviceId(event.getMobilePosition().getChannelId(), platforms);
|
||||||
|
|
||||||
for (Platform platform : parentPlatformsForGB) {
|
for (Platform platform : parentPlatformsForGB) {
|
||||||
log.info("[向上级发送MobilePosition] 通道:{},平台:{}, 位置: {}:{}", event.getMobilePosition().getChannelId(),
|
if (log.isDebugEnabled()){
|
||||||
platform.getServerGBId(), event.getMobilePosition().getLongitude(), event.getMobilePosition().getLatitude());
|
log.debug("[向上级发送MobilePosition] 通道:{},平台:{}, 位置: {}:{}", event.getMobilePosition().getChannelId(),
|
||||||
|
platform.getServerGBId(), event.getMobilePosition().getLongitude(), event.getMobilePosition().getLatitude());
|
||||||
|
}
|
||||||
SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
|
SubscribeInfo subscribe = subscribeHolder.getMobilePositionSubscribe(platform.getServerGBId());
|
||||||
try {
|
try {
|
||||||
GPSMsgInfo gpsMsgInfo = GPSMsgInfo.getInstance(event.getMobilePosition());
|
GPSMsgInfo gpsMsgInfo = GPSMsgInfo.getInstance(event.getMobilePosition());
|
||||||
|
|
|
@ -70,6 +70,8 @@ public interface IDeviceChannelService {
|
||||||
*/
|
*/
|
||||||
DeviceChannel getOne(String deviceId, String channelId);
|
DeviceChannel getOne(String deviceId, String channelId);
|
||||||
|
|
||||||
|
DeviceChannel getOneForSource(String deviceId, String channelId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 直接批量更新通道
|
* 直接批量更新通道
|
||||||
*/
|
*/
|
||||||
|
@ -120,5 +122,7 @@ public interface IDeviceChannelService {
|
||||||
|
|
||||||
DeviceChannel getOneById(Integer channelId);
|
DeviceChannel getOneById(Integer channelId);
|
||||||
|
|
||||||
|
DeviceChannel getOneForSourceById(Integer channelId);
|
||||||
|
|
||||||
DeviceChannel getBroadcastChannel(int deviceDbId);
|
DeviceChannel getBroadcastChannel(int deviceDbId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package com.genersoft.iot.vmp.gb28181.service;
|
package com.genersoft.iot.vmp.gb28181.service;
|
||||||
|
|
||||||
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ServiceException;
|
import com.genersoft.iot.vmp.conf.exception.ServiceException;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.controller.bean.AudioBroadcastEvent;
|
||||||
import com.genersoft.iot.vmp.media.bean.MediaInfo;
|
import com.genersoft.iot.vmp.media.bean.MediaInfo;
|
||||||
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
import com.genersoft.iot.vmp.media.bean.MediaServer;
|
||||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||||
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
|
||||||
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
|
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
|
||||||
import com.genersoft.iot.vmp.gb28181.controller.bean.AudioBroadcastEvent;
|
|
||||||
import gov.nist.javax.sip.message.SIPResponse;
|
import gov.nist.javax.sip.message.SIPResponse;
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
import javax.sip.InvalidArgumentException;
|
||||||
|
@ -58,11 +60,14 @@ public interface IPlayService {
|
||||||
|
|
||||||
void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
|
void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
|
||||||
|
|
||||||
void stopPlay(Device device, DeviceChannel channel);
|
void stop(InviteSessionType type, Device device, DeviceChannel channel, String stream);
|
||||||
|
|
||||||
|
void stop(InviteInfo inviteInfo);
|
||||||
|
|
||||||
void play(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
void play(CommonGBChannel channel, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
void playBack(CommonGBChannel channel, Long startTime, Long stopTime, ErrorCallback<StreamInfo> callback);
|
void playBack(CommonGBChannel channel, Long startTime, Long stopTime, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
void download(CommonGBChannel channel, Long startTime, Long stopTime, Integer downloadSpeed, ErrorCallback<StreamInfo> callback);
|
void download(CommonGBChannel channel, Long startTime, Long stopTime, Integer downloadSpeed, ErrorCallback<StreamInfo> callback);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,6 +252,15 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||||
return channelMapper.getOneByDeviceId(device.getId(), channelId);
|
return channelMapper.getOneByDeviceId(device.getId(), channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceChannel getOneForSource(String deviceId, String channelId){
|
||||||
|
Device device = deviceMapper.getDeviceByDeviceId(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到设备:" + deviceId);
|
||||||
|
}
|
||||||
|
return channelMapper.getOneByDeviceIdForSource(device.getId(), channelId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void batchUpdateChannel(List<DeviceChannel> channels) {
|
public synchronized void batchUpdateChannel(List<DeviceChannel> channels) {
|
||||||
String now = DateUtil.getNow();
|
String now = DateUtil.getNow();
|
||||||
|
@ -595,6 +604,11 @@ public class DeviceChannelServiceImpl implements IDeviceChannelService {
|
||||||
return channelMapper.getOne(channelId);
|
return channelMapper.getOne(channelId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DeviceChannel getOneForSourceById(Integer channelId) {
|
||||||
|
return channelMapper.getOneForSource(channelId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeviceChannel getBroadcastChannel(int deviceDbId) {
|
public DeviceChannel getBroadcastChannel(int deviceDbId) {
|
||||||
List<DeviceChannel> channels = channelMapper.getByDeviceId(deviceDbId);
|
List<DeviceChannel> channels = channelMapper.getByDeviceId(deviceDbId);
|
||||||
|
|
|
@ -226,6 +226,15 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else if ("rtp".equals(event.getApp())) {
|
||||||
|
// 释放ssrc
|
||||||
|
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, event.getStream());
|
||||||
|
if (inviteInfo != null && inviteInfo.getStatus() == InviteSessionStatus.ok
|
||||||
|
&& inviteInfo.getStreamInfo() != null && inviteInfo.getSsrcInfo() != null) {
|
||||||
|
// 发送bye
|
||||||
|
stop(inviteInfo);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +295,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
log.warn("[点播] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId);
|
log.warn("[点播] 单端口收流时不支持TCP主动方式收流 deviceId: {},channelId:{}", deviceId, channelId);
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "单端口收流时不支持TCP主动方式收流");
|
||||||
}
|
}
|
||||||
DeviceChannel channel = deviceChannelService.getOne(deviceId, channelId);
|
DeviceChannel channel = deviceChannelService.getOneForSource(deviceId, channelId);
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
log.warn("[点播] 未找到通道 deviceId: {},channelId:{}", deviceId, channelId);
|
log.warn("[点播] 未找到通道 deviceId: {},channelId:{}", deviceId, channelId);
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到通道");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到通道");
|
||||||
|
@ -1529,24 +1538,56 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopPlay(Device device, DeviceChannel channel) {
|
public void stop(InviteSessionType type, Device device, DeviceChannel channel, String stream) {
|
||||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(type, stream);
|
||||||
if (inviteInfo == null) {
|
if (inviteInfo == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到");
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到");
|
||||||
}
|
}
|
||||||
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
||||||
try {
|
try {
|
||||||
log.info("[停止点播] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||||
cmder.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null, null);
|
cmder.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null, null);
|
||||||
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||||
log.error("[命令发送失败] 停止点播, 发送BYE: {}", e.getMessage());
|
log.error("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
|
||||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, channel.getId());
|
inviteStreamService.removeInviteInfoByDeviceAndChannel(inviteInfo.getType(), channel.getId());
|
||||||
deviceChannelService.stopPlay(channel.getId());
|
if (inviteInfo.getType() == InviteSessionType.PLAY) {
|
||||||
|
deviceChannelService.stopPlay(channel.getId());
|
||||||
|
}
|
||||||
if (inviteInfo.getStreamInfo() != null) {
|
if (inviteInfo.getStreamInfo() != null) {
|
||||||
mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), inviteInfo.getStream());
|
receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), inviteInfo.getSsrcInfo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(InviteInfo inviteInfo) {
|
||||||
|
Assert.notNull(inviteInfo, "参数异常");
|
||||||
|
DeviceChannel channel = deviceChannelService.getOneForSourceById(inviteInfo.getChannelId());
|
||||||
|
if (channel == null) {
|
||||||
|
log.warn("[停止点播] 发现通道不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Device device = deviceService.getDevice(channel.getDeviceDbId());
|
||||||
|
if (device == null) {
|
||||||
|
log.warn("[停止点播] 发现设备不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
|
||||||
|
try {
|
||||||
|
log.info("[停止点播/回放/下载] {}/{}", device.getDeviceId(), channel.getDeviceId());
|
||||||
|
cmder.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null, null);
|
||||||
|
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
|
||||||
|
log.warn("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inviteStreamService.removeInviteInfoByDeviceAndChannel(inviteInfo.getType(), channel.getId());
|
||||||
|
if (inviteInfo.getType() == InviteSessionType.PLAY) {
|
||||||
|
deviceChannelService.stopPlay(channel.getId());
|
||||||
|
}
|
||||||
|
if (inviteInfo.getStreamInfo() != null) {
|
||||||
|
receiveRtpServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServer(), inviteInfo.getSsrcInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,9 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
|
||||||
if (parentPlatform == null) {
|
if (parentPlatform == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.info("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getChannelId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
|
if (log.isDebugEnabled()) {
|
||||||
|
log.info("[发送 移动位置订阅] {}/{}->{},{}", parentPlatform.getServerGBId(), gpsMsgInfo.getChannelId(), gpsMsgInfo.getLng(), gpsMsgInfo.getLat());
|
||||||
|
}
|
||||||
|
|
||||||
String characterSet = parentPlatform.getCharacterSet();
|
String characterSet = parentPlatform.getCharacterSet();
|
||||||
StringBuffer deviceStatusXml = new StringBuffer(600);
|
StringBuffer deviceStatusXml = new StringBuffer(600);
|
||||||
|
|
|
@ -198,7 +198,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||||
String content = createSendSdp(sendRtpItem, inviteInfo, sdpIp);
|
String content = createSendSdp(sendRtpItem, inviteInfo, sdpIp);
|
||||||
// 超时未收到Ack应该回复bye,当前等待时间为10秒
|
// 超时未收到Ack应该回复bye,当前等待时间为10秒
|
||||||
dynamicTask.startDelay(inviteInfo.getCallId(), () -> {
|
dynamicTask.startDelay(inviteInfo.getCallId(), () -> {
|
||||||
log.info("Ack 等待超时");
|
log.info("[Ack ] 等待超时, {}/{}", inviteInfo.getCallId(), channel.getGbDeviceId());
|
||||||
mediaServerService.releaseSsrc(streamInfo.getMediaServer().getId(), sendRtpItem.getSsrc());
|
mediaServerService.releaseSsrc(streamInfo.getMediaServer().getId(), sendRtpItem.getSsrc());
|
||||||
// 回复bye
|
// 回复bye
|
||||||
sendBye(platform, inviteInfo.getCallId());
|
sendBye(platform, inviteInfo.getCallId());
|
||||||
|
|
|
@ -2,11 +2,14 @@ package com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.Platform;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpInfo;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
import com.genersoft.iot.vmp.gb28181.service.IDeviceChannelService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
import com.genersoft.iot.vmp.gb28181.service.IInviteStreamService;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
|
import com.genersoft.iot.vmp.gb28181.service.IPlatformService;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.service.IPlayService;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||||
|
@ -70,6 +73,9 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
|
||||||
@Autowired
|
@Autowired
|
||||||
private IDeviceChannelService deviceChannelService;
|
private IDeviceChannelService deviceChannelService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IPlayService playService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISendRtpServerService sendRtpServerService;
|
private ISendRtpServerService sendRtpServerService;
|
||||||
|
|
||||||
|
@ -96,19 +102,8 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
|
||||||
if (ssrcTransaction != null) {
|
if (ssrcTransaction != null) {
|
||||||
log.info("[录像流]推送完毕,关流通知, device: {}, channelId: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
|
log.info("[录像流]推送完毕,关流通知, device: {}, channelId: {}", ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId());
|
||||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
|
||||||
if (inviteInfo.getStreamInfo() != null) {
|
if (inviteInfo != null) {
|
||||||
inviteInfo.getStreamInfo().setProgress(1);
|
playService.stop(inviteInfo);
|
||||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
|
||||||
}
|
|
||||||
DeviceChannel deviceChannel = deviceChannelService.getOneById(ssrcTransaction.getChannelId());
|
|
||||||
if (deviceChannel == null) {
|
|
||||||
log.warn("[级联消息发送]:未找到国标设备通道: {}", ssrcTransaction.getChannelId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
cmder.streamByeCmd(device, deviceChannel.getDeviceId(), null, callIdHeader.getCallId());
|
|
||||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
|
||||||
log.error("[录像流]推送完毕,收到关流通知, 发送BYE失败 {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
// 去除监听流注销自动停止下载的监听
|
// 去除监听流注销自动停止下载的监听
|
||||||
Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId());
|
Hook hook = Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcTransaction.getStream(), ssrcTransaction.getMediaServerId());
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package com.genersoft.iot.vmp.service.impl;
|
package com.genersoft.iot.vmp.service.impl;
|
||||||
|
|
||||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||||
|
import com.genersoft.iot.vmp.common.InviteSessionStatus;
|
||||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.service.*;
|
import com.genersoft.iot.vmp.gb28181.service.*;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.session.SSRCFactory;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.SipInviteSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||||
|
@ -30,10 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.sip.InvalidArgumentException;
|
|
||||||
import javax.sip.SipException;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -58,6 +56,9 @@ public class MediaServiceImpl implements IMediaService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IInviteStreamService inviteStreamService;
|
private IInviteStreamService inviteStreamService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SSRCFactory ssrcFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IDeviceChannelService deviceChannelService;
|
private IDeviceChannelService deviceChannelService;
|
||||||
|
|
||||||
|
@ -228,7 +229,7 @@ public class MediaServiceImpl implements IMediaService {
|
||||||
// 国标流, 点播/录像回放/录像下载
|
// 国标流, 点播/录像回放/录像下载
|
||||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream);
|
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, stream);
|
||||||
// 点播
|
// 点播
|
||||||
if (inviteInfo != null) {
|
if (inviteInfo != null && inviteInfo.getStatus() == InviteSessionStatus.ok) {
|
||||||
// 录像下载
|
// 录像下载
|
||||||
if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) {
|
if (inviteInfo.getType() == InviteSessionType.DOWNLOAD) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -237,54 +238,8 @@ public class MediaServiceImpl implements IMediaService {
|
||||||
if (deviceChannel == null) {
|
if (deviceChannel == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 收到无人观看说明流也没有在往上级推送
|
|
||||||
if (sendRtpServerService.isChannelSendingRTP(deviceChannel.getId())) {
|
|
||||||
List<SendRtpInfo> sendRtpItems = sendRtpServerService.queryByChannelId(deviceChannel.getId());
|
|
||||||
if (!sendRtpItems.isEmpty()) {
|
|
||||||
for (SendRtpInfo sendRtpItem : sendRtpItems) {
|
|
||||||
Platform parentPlatform = platformService.queryPlatformByServerGBId(sendRtpItem.getTargetId());
|
|
||||||
CommonGBChannel channel = channelService.getOne(sendRtpItem.getChannelId());
|
|
||||||
if (channel == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
commanderForPlatform.streamByeCmd(parentPlatform, sendRtpItem, channel);
|
|
||||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
|
||||||
log.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
sendRtpServerService.delete(sendRtpItem);
|
|
||||||
if (InviteStreamType.PUSH == sendRtpItem.getPlayType()) {
|
|
||||||
redisCatchStorage.sendPlatformStopPlayMsg(sendRtpItem, parentPlatform, channel);
|
|
||||||
redisCatchStorage.sendPlatformStopPlayMsg(sendRtpItem, parentPlatform, channel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Device device = deviceService.getDeviceByDeviceId(inviteInfo.getDeviceId());
|
|
||||||
if (device != null) {
|
|
||||||
try {
|
|
||||||
DeviceChannel channel = deviceChannelService.getOneById(inviteInfo.getChannelId());
|
|
||||||
// 多查询一次防止已经被处理了
|
|
||||||
InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
|
||||||
if (info != null && channel != null) {
|
|
||||||
commander.streamByeCmd(device, channel.getDeviceId(), inviteInfo.getStream(), null);
|
|
||||||
} else {
|
|
||||||
log.info("[无人观看] 未找到设备的点播信息: {}, 流:{}", inviteInfo.getDeviceId(), stream);
|
|
||||||
}
|
|
||||||
} catch (InvalidArgumentException | ParseException | SipException |
|
|
||||||
SsrcTransactionNotFoundException e) {
|
|
||||||
log.error("[无人观看]点播, 发送BYE失败 {}", e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.info("[无人观看] 未找到设备: {},流:{}", inviteInfo.getDeviceId(), stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
|
||||||
deviceChannelService.stopPlay(inviteInfo.getChannelId());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}else {
|
||||||
List<SendRtpInfo> sendRtpItemList = sendRtpServerService.queryByStream(stream);
|
|
||||||
if (!sendRtpItemList.isEmpty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if ("talk".equals(app) || "broadcast".equals(app)) {
|
} else if ("talk".equals(app) || "broadcast".equals(app)) {
|
||||||
|
@ -296,20 +251,21 @@ public class MediaServiceImpl implements IMediaService {
|
||||||
if (streamProxy != null) {
|
if (streamProxy != null) {
|
||||||
if (streamProxy.isEnableRemoveNoneReader()) {
|
if (streamProxy.isEnableRemoveNoneReader()) {
|
||||||
// 无人观看自动移除
|
// 无人观看自动移除
|
||||||
result = true;
|
|
||||||
streamProxyService.delteByAppAndStream(app, stream);
|
streamProxyService.delteByAppAndStream(app, stream);
|
||||||
log.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, stream, streamProxy.getSrcUrl());
|
log.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, stream, streamProxy.getSrcUrl());
|
||||||
|
return true;
|
||||||
} else if (streamProxy.isEnableDisableNoneReader()) {
|
} else if (streamProxy.isEnableDisableNoneReader()) {
|
||||||
// 无人观看停用
|
// 无人观看停用
|
||||||
result = true;
|
|
||||||
// 修改数据
|
// 修改数据
|
||||||
streamProxyService.stopByAppAndStream(app, stream);
|
streamProxyService.stopByAppAndStream(app, stream);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// 无人观看不做处理
|
// 无人观看不做处理
|
||||||
result = false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue