Commit f33c3a36302749d8552b281de3dbe37f672bba86

Authored by 648540858
1 parent 66cadafd

添加重启后拉流代理自动恢复

sql/mysql.sql
@@ -444,6 +444,7 @@ CREATE TABLE `stream_proxy` ( @@ -444,6 +444,7 @@ CREATE TABLE `stream_proxy` (
444 `enable_hls` bit(1) DEFAULT NULL, 444 `enable_hls` bit(1) DEFAULT NULL,
445 `enable_mp4` bit(1) DEFAULT NULL, 445 `enable_mp4` bit(1) DEFAULT NULL,
446 `enable` bit(1) NOT NULL, 446 `enable` bit(1) NOT NULL,
  447 + `status` bit(1) NOT NULL,
447 `enable_remove_none_reader` bit(1) NOT NULL, 448 `enable_remove_none_reader` bit(1) NOT NULL,
448 `createTime` varchar(50) NOT NULL, 449 `createTime` varchar(50) NOT NULL,
449 PRIMARY KEY (`app`,`stream`) 450 PRIMARY KEY (`app`,`stream`)
sql/update.sql 0 → 100644
  1 +ALTER TABLE stream_proxy ADD status bit(1) not null;
0 \ No newline at end of file 2 \ No newline at end of file
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -332,6 +332,11 @@ public class ZLMHttpHookListener { @@ -332,6 +332,11 @@ public class ZLMHttpHookListener {
332 }else { 332 }else {
333 mediaServerService.removeCount(mediaServerId); 333 mediaServerService.removeCount(mediaServerId);
334 } 334 }
  335 + if (item.getOriginType() == OriginType.PULL.ordinal()
  336 + || item.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
  337 + // 设置拉流代理上线/离线
  338 + streamProxyService.updateStatus(regist, app, streamId);
  339 + }
335 if ("rtp".equals(app) && !regist ) { 340 if ("rtp".equals(app) && !regist ) {
336 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); 341 StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId);
337 if (streamInfo!=null){ 342 if (streamInfo!=null){
@@ -355,6 +360,7 @@ public class ZLMHttpHookListener { @@ -355,6 +360,7 @@ public class ZLMHttpHookListener {
355 || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { 360 || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) {
356 streamPushItem = zlmMediaListManager.addPush(item); 361 streamPushItem = zlmMediaListManager.addPush(item);
357 } 362 }
  363 +
358 List<GbStream> gbStreams = new ArrayList<>(); 364 List<GbStream> gbStreams = new ArrayList<>();
359 if (streamPushItem == null || streamPushItem.getGbId() == null) { 365 if (streamPushItem == null || streamPushItem.getGbId() == null) {
360 GbStream gbStream = storager.getGbStream(app, streamId); 366 GbStream gbStream = storager.getGbStream(app, streamId);
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
@@ -151,4 +151,5 @@ public class StreamProxyItem extends GbStream { @@ -151,4 +151,5 @@ public class StreamProxyItem extends GbStream {
151 public void setEnable_remove_none_reader(boolean enable_remove_none_reader) { 151 public void setEnable_remove_none_reader(boolean enable_remove_none_reader) {
152 this.enable_remove_none_reader = enable_remove_none_reader; 152 this.enable_remove_none_reader = enable_remove_none_reader;
153 } 153 }
  154 +
154 } 155 }
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
@@ -56,6 +56,16 @@ public interface IStreamProxyService { @@ -56,6 +56,16 @@ public interface IStreamProxyService {
56 boolean start(String app, String stream); 56 boolean start(String app, String stream);
57 57
58 /** 58 /**
  59 + * 更新状态
  60 + * @param status 状态
  61 + * @param app
  62 + * @param stream
  63 + */
  64 + int updateStatus(boolean status, String app, String stream);
  65 +
  66 +
  67 +
  68 + /**
59 * 停用用视频代理 69 * 停用用视频代理
60 * @param app 70 * @param app
61 * @param stream 71 * @param stream
src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java
@@ -14,8 +14,11 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; @@ -14,8 +14,11 @@ import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
14 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; 14 import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
15 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; 15 import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig;
16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; 16 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
  17 +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
17 import com.genersoft.iot.vmp.service.IMediaServerService; 18 import com.genersoft.iot.vmp.service.IMediaServerService;
  19 +import com.genersoft.iot.vmp.service.IStreamProxyService;
18 import com.genersoft.iot.vmp.service.bean.SSRCInfo; 20 import com.genersoft.iot.vmp.service.bean.SSRCInfo;
  21 +import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
19 import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; 22 import com.genersoft.iot.vmp.storager.dao.MediaServerMapper;
20 import com.genersoft.iot.vmp.utils.redis.JedisUtil; 23 import com.genersoft.iot.vmp.utils.redis.JedisUtil;
21 import com.genersoft.iot.vmp.utils.redis.RedisUtil; 24 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
@@ -71,6 +74,12 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -71,6 +74,12 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
71 private RedisUtil redisUtil; 74 private RedisUtil redisUtil;
72 75
73 @Autowired 76 @Autowired
  77 + private IVideoManagerStorager storager;
  78 +
  79 + @Autowired
  80 + private IStreamProxyService streamProxyService;
  81 +
  82 + @Autowired
74 private EventPublisher publisher; 83 private EventPublisher publisher;
75 84
76 @Autowired 85 @Autowired
@@ -231,6 +240,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -231,6 +240,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
231 public List<MediaServerItem> getAllOnline() { 240 public List<MediaServerItem> getAllOnline() {
232 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetup.getServerId(); 241 String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetup.getServerId();
233 Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1); 242 Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1);
  243 +
234 List<MediaServerItem> result = new ArrayList<>(); 244 List<MediaServerItem> result = new ArrayList<>();
235 if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { 245 if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) {
236 for (String mediaServerId : mediaServerIdSet) { 246 for (String mediaServerId : mediaServerIdSet) {
@@ -238,6 +248,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -238,6 +248,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
238 result.add((MediaServerItem) redisUtil.get(serverKey)); 248 result.add((MediaServerItem) redisUtil.get(serverKey));
239 } 249 }
240 } 250 }
  251 + Collections.reverse(result);
241 return result; 252 return result;
242 } 253 }
243 254
@@ -374,6 +385,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR @@ -374,6 +385,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR
374 resetOnlineServerItem(serverItem); 385 resetOnlineServerItem(serverItem);
375 updateMediaServerKeepalive(serverItem.getId(), null); 386 updateMediaServerKeepalive(serverItem.getId(), null);
376 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); 387 setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable()));
  388 +
377 publisher.zlmOnlineEventPublish(serverItem.getId()); 389 publisher.zlmOnlineEventPublish(serverItem.getId());
378 390
379 } 391 }
src/main/java/com/genersoft/iot/vmp/service/impl/StreamProxyServiceImpl.java
@@ -59,6 +59,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -59,6 +59,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
59 private IRedisCatchStorage redisCatchStorage; 59 private IRedisCatchStorage redisCatchStorage;
60 60
61 @Autowired 61 @Autowired
  62 + private IVideoManagerStorager storager;
  63 +
  64 + @Autowired
62 private UserSetup userSetup; 65 private UserSetup userSetup;
63 66
64 @Autowired 67 @Autowired
@@ -278,7 +281,27 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -278,7 +281,27 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
278 281
279 @Override 282 @Override
280 public void zlmServerOnline(String mediaServerId) { 283 public void zlmServerOnline(String mediaServerId) {
281 - zlmServerOffline(mediaServerId); 284 + // 移除开启了无人观看自动移除的流
  285 + List<StreamProxyItem> streamProxyItemList = streamProxyMapper.selecAutoRemoveItemByMediaServerId(mediaServerId);
  286 + if (streamProxyItemList.size() > 0) {
  287 + gbStreamMapper.batchDel(streamProxyItemList);
  288 + }
  289 + streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
  290 +
  291 + // 恢复流代理, 只查找这个这个流媒体
  292 + List<StreamProxyItem> streamProxyListForEnable = storager.getStreamProxyListForEnableInMediaServer(
  293 + mediaServerId, true, false);
  294 + for (StreamProxyItem streamProxyDto : streamProxyListForEnable) {
  295 + logger.info("恢复流代理," + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
  296 + JSONObject jsonObject = addStreamProxyToZlm(streamProxyDto);
  297 + if (jsonObject == null) {
  298 + // 设置为离线
  299 + logger.info("恢复流代理失败" + streamProxyDto.getApp() + "/" + streamProxyDto.getStream());
  300 + updateStatus(false, streamProxyDto.getApp(), streamProxyDto.getStream());
  301 + }else {
  302 + updateStatus(true, streamProxyDto.getApp(), streamProxyDto.getStream());
  303 + }
  304 + }
282 } 305 }
283 306
284 @Override 307 @Override
@@ -289,8 +312,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -289,8 +312,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
289 gbStreamMapper.batchDel(streamProxyItemList); 312 gbStreamMapper.batchDel(streamProxyItemList);
290 } 313 }
291 streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId); 314 streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId);
292 - // 其他的流设置未启用  
293 - streamProxyMapper.updateStatus(false, mediaServerId); 315 + // 其他的流设置离线
  316 + streamProxyMapper.updateStatusByMediaServerId(false, mediaServerId);
294 String type = "PULL"; 317 String type = "PULL";
295 318
296 // 发送redis消息 319 // 发送redis消息
@@ -314,4 +337,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { @@ -314,4 +337,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
314 public void clean() { 337 public void clean() {
315 338
316 } 339 }
  340 +
  341 + @Override
  342 + public int updateStatus(boolean status, String app, String stream) {
  343 + return streamProxyMapper.updateStatus(status, app, stream);
  344 + }
317 } 345 }
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -398,10 +398,11 @@ public interface IVideoManagerStorager { @@ -398,10 +398,11 @@ public interface IVideoManagerStorager {
398 /** 398 /**
399 * 根据媒体ID获取启用/不启用的代理列表 399 * 根据媒体ID获取启用/不启用的代理列表
400 * @param id 媒体ID 400 * @param id 媒体ID
401 - * @param b 启用/不启用 401 + * @param enable 启用/不启用
  402 + * @param status 状态
402 * @return 403 * @return
403 */ 404 */
404 - List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean b); 405 + List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean enable, boolean status);
405 406
406 /** 407 /**
407 * 根据通道ID获取其所在设备 408 * 根据通道ID获取其所在设备
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
@@ -11,9 +11,9 @@ import java.util.List; @@ -11,9 +11,9 @@ import java.util.List;
11 public interface StreamProxyMapper { 11 public interface StreamProxyMapper {
12 12
13 @Insert("INSERT INTO stream_proxy (type, app, stream,mediaServerId, url, src_url, dst_url, " + 13 @Insert("INSERT INTO stream_proxy (type, app, stream,mediaServerId, url, src_url, dst_url, " +
14 - "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, enable_remove_none_reader, createTime) VALUES" + 14 + "timeout_ms, ffmpeg_cmd_key, rtp_type, enable_hls, enable_mp4, enable, status, enable_remove_none_reader, createTime) VALUES" +
15 "('${type}','${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " + 15 "('${type}','${app}', '${stream}', '${mediaServerId}','${url}', '${src_url}', '${dst_url}', " +
16 - "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, " + 16 + "'${timeout_ms}', '${ffmpeg_cmd_key}', '${rtp_type}', ${enable_hls}, ${enable_mp4}, ${enable}, ${status}, " +
17 "${enable_remove_none_reader}, '${createTime}' )") 17 "${enable_remove_none_reader}, '${createTime}' )")
18 int add(StreamProxyItem streamProxyDto); 18 int add(StreamProxyItem streamProxyDto);
19 19
@@ -30,6 +30,7 @@ public interface StreamProxyMapper { @@ -30,6 +30,7 @@ public interface StreamProxyMapper {
30 "rtp_type=#{rtp_type}, " + 30 "rtp_type=#{rtp_type}, " +
31 "enable_hls=#{enable_hls}, " + 31 "enable_hls=#{enable_hls}, " +
32 "enable=#{enable}, " + 32 "enable=#{enable}, " +
  33 + "status=#{status}, " +
33 "enable_remove_none_reader=#{enable_remove_none_reader}, " + 34 "enable_remove_none_reader=#{enable_remove_none_reader}, " +
34 "enable_mp4=#{enable_mp4} " + 35 "enable_mp4=#{enable_mp4} " +
35 "WHERE app=#{app} AND stream=#{stream}") 36 "WHERE app=#{app} AND stream=#{stream}")
@@ -49,8 +50,8 @@ public interface StreamProxyMapper { @@ -49,8 +50,8 @@ public interface StreamProxyMapper {
49 50
50 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + 51 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
51 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " + 52 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
52 - "WHERE st.enable=${enable} and st.mediaServerId = '${id}' order by st.createTime desc")  
53 - List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable); 53 + "WHERE st.enable=${enable} and st.status=${status} and st.mediaServerId = '${id}' order by st.createTime desc")
  54 + List<StreamProxyItem> selectForEnableInMediaServer(String id, boolean enable, boolean status);
54 55
55 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + 56 @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " +
56 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " + 57 "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " +
@@ -58,9 +59,14 @@ public interface StreamProxyMapper { @@ -58,9 +59,14 @@ public interface StreamProxyMapper {
58 List<StreamProxyItem> selectInMediaServer(String id); 59 List<StreamProxyItem> selectInMediaServer(String id);
59 60
60 @Update("UPDATE stream_proxy " + 61 @Update("UPDATE stream_proxy " +
61 - "SET enable=#{status} " + 62 + "SET status=#{status} " +
62 "WHERE mediaServerId=#{mediaServerId}") 63 "WHERE mediaServerId=#{mediaServerId}")
63 - void updateStatus(boolean status, String mediaServerId); 64 + void updateStatusByMediaServerId(boolean status, String mediaServerId);
  65 +
  66 + @Update("UPDATE stream_proxy " +
  67 + "SET status=${status} " +
  68 + "WHERE app=#{app} AND stream=#{stream}")
  69 + int updateStatus(boolean status, String app, String stream);
64 70
65 @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}") 71 @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}")
66 void deleteAutoRemoveItemByMediaServerId(String mediaServerId); 72 void deleteAutoRemoveItemByMediaServerId(String mediaServerId);
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -860,8 +860,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -860,8 +860,8 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
860 } 860 }
861 861
862 @Override 862 @Override
863 - public List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean enable) {  
864 - return streamProxyMapper.selectForEnableInMediaServer(id, enable); 863 + public List<StreamProxyItem> getStreamProxyListForEnableInMediaServer(String id, boolean enable, boolean status) {
  864 + return streamProxyMapper.selectForEnableInMediaServer(id, enable, status);
865 } 865 }
866 866
867 867
web_src/src/components/StreamProxyList.vue
@@ -42,6 +42,14 @@ @@ -42,6 +42,14 @@
42 </el-table-column> 42 </el-table-column>
43 43
44 <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/> 44 <el-table-column prop="gbId" label="国标编码" width="180" align="center" show-overflow-tooltip/>
  45 + <el-table-column label="状态" width="120" align="center">
  46 + <template slot-scope="scope">
  47 + <div slot="reference" class="name-wrapper">
  48 + <el-tag size="medium" v-if="scope.row.status">在线</el-tag>
  49 + <el-tag size="medium" type="info" v-if="!scope.row.status">离线</el-tag>
  50 + </div>
  51 + </template>
  52 + </el-table-column>
45 <el-table-column label="启用" width="120" align="center"> 53 <el-table-column label="启用" width="120" align="center">
46 <template slot-scope="scope"> 54 <template slot-scope="scope">
47 <div slot="reference" class="name-wrapper"> 55 <div slot="reference" class="name-wrapper">
web_src/src/components/dialog/StreamProxyEdit.vue
@@ -46,7 +46,6 @@ @@ -46,7 +46,6 @@
46 style="width: 100%" 46 style="width: 100%"
47 placeholder="请选择拉流节点" 47 placeholder="请选择拉流节点"
48 > 48 >
49 - <el-option label="自动选择" value="auto"></el-option>  
50 <el-option 49 <el-option
51 v-for="item in mediaServerList" 50 v-for="item in mediaServerList"
52 :key="item.id" 51 :key="item.id"
@@ -172,7 +171,7 @@ export default { @@ -172,7 +171,7 @@ export default {
172 enable_mp4: false, 171 enable_mp4: false,
173 enable_remove_none_reader: false, 172 enable_remove_none_reader: false,
174 platformGbId: null, 173 platformGbId: null,
175 - mediaServerId: "auto", 174 + mediaServerId: null,
176 }, 175 },
177 mediaServerList:{}, 176 mediaServerList:{},
178 ffmpegCmdList:{}, 177 ffmpegCmdList:{},
@@ -206,7 +205,8 @@ export default { @@ -206,7 +205,8 @@ export default {
206 console.log(error); 205 console.log(error);
207 }); 206 });
208 this.mediaServer.getOnlineMediaServerList((data)=>{ 207 this.mediaServer.getOnlineMediaServerList((data)=>{
209 - this.mediaServerList = data; 208 + this.mediaServerList = data.data;
  209 + this.proxyParam.mediaServerId = this.mediaServerList[0].id
210 }) 210 })
211 }, 211 },
212 mediaServerIdChange:function (){ 212 mediaServerIdChange:function (){