Commit f33c3a36302749d8552b281de3dbe37f672bba86
1 parent
66cadafd
添加重启后拉流代理自动恢复
Showing
12 changed files
with
90 additions
and
16 deletions
sql/mysql.sql
| ... | ... | @@ -444,6 +444,7 @@ CREATE TABLE `stream_proxy` ( |
| 444 | 444 | `enable_hls` bit(1) DEFAULT NULL, |
| 445 | 445 | `enable_mp4` bit(1) DEFAULT NULL, |
| 446 | 446 | `enable` bit(1) NOT NULL, |
| 447 | + `status` bit(1) NOT NULL, | |
| 447 | 448 | `enable_remove_none_reader` bit(1) NOT NULL, |
| 448 | 449 | `createTime` varchar(50) NOT NULL, |
| 449 | 450 | PRIMARY KEY (`app`,`stream`) | ... | ... |
sql/update.sql
0 → 100644
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
| ... | ... | @@ -332,6 +332,11 @@ public class ZLMHttpHookListener { |
| 332 | 332 | }else { |
| 333 | 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 | 340 | if ("rtp".equals(app) && !regist ) { |
| 336 | 341 | StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); |
| 337 | 342 | if (streamInfo!=null){ |
| ... | ... | @@ -355,6 +360,7 @@ public class ZLMHttpHookListener { |
| 355 | 360 | || item.getOriginType() == OriginType.RTC_PUSH.ordinal() ) { |
| 356 | 361 | streamPushItem = zlmMediaListManager.addPush(item); |
| 357 | 362 | } |
| 363 | + | |
| 358 | 364 | List<GbStream> gbStreams = new ArrayList<>(); |
| 359 | 365 | if (streamPushItem == null || streamPushItem.getGbId() == null) { |
| 360 | 366 | GbStream gbStream = storager.getGbStream(app, streamId); | ... | ... |
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/StreamProxyItem.java
src/main/java/com/genersoft/iot/vmp/service/IStreamProxyService.java
| ... | ... | @@ -56,6 +56,16 @@ public interface IStreamProxyService { |
| 56 | 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 | 70 | * @param app |
| 61 | 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 | 14 | import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory; |
| 15 | 15 | import com.genersoft.iot.vmp.media.zlm.ZLMServerConfig; |
| 16 | 16 | import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem; |
| 17 | +import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem; | |
| 17 | 18 | import com.genersoft.iot.vmp.service.IMediaServerService; |
| 19 | +import com.genersoft.iot.vmp.service.IStreamProxyService; | |
| 18 | 20 | import com.genersoft.iot.vmp.service.bean.SSRCInfo; |
| 21 | +import com.genersoft.iot.vmp.storager.IVideoManagerStorager; | |
| 19 | 22 | import com.genersoft.iot.vmp.storager.dao.MediaServerMapper; |
| 20 | 23 | import com.genersoft.iot.vmp.utils.redis.JedisUtil; |
| 21 | 24 | import com.genersoft.iot.vmp.utils.redis.RedisUtil; |
| ... | ... | @@ -71,6 +74,12 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR |
| 71 | 74 | private RedisUtil redisUtil; |
| 72 | 75 | |
| 73 | 76 | @Autowired |
| 77 | + private IVideoManagerStorager storager; | |
| 78 | + | |
| 79 | + @Autowired | |
| 80 | + private IStreamProxyService streamProxyService; | |
| 81 | + | |
| 82 | + @Autowired | |
| 74 | 83 | private EventPublisher publisher; |
| 75 | 84 | |
| 76 | 85 | @Autowired |
| ... | ... | @@ -231,6 +240,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR |
| 231 | 240 | public List<MediaServerItem> getAllOnline() { |
| 232 | 241 | String key = VideoManagerConstants.MEDIA_SERVERS_ONLINE_PREFIX + userSetup.getServerId(); |
| 233 | 242 | Set<String> mediaServerIdSet = redisUtil.zRevRange(key, 0, -1); |
| 243 | + | |
| 234 | 244 | List<MediaServerItem> result = new ArrayList<>(); |
| 235 | 245 | if (mediaServerIdSet != null && mediaServerIdSet.size() > 0) { |
| 236 | 246 | for (String mediaServerId : mediaServerIdSet) { |
| ... | ... | @@ -238,6 +248,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR |
| 238 | 248 | result.add((MediaServerItem) redisUtil.get(serverKey)); |
| 239 | 249 | } |
| 240 | 250 | } |
| 251 | + Collections.reverse(result); | |
| 241 | 252 | return result; |
| 242 | 253 | } |
| 243 | 254 | |
| ... | ... | @@ -374,6 +385,7 @@ public class MediaServerServiceImpl implements IMediaServerService, CommandLineR |
| 374 | 385 | resetOnlineServerItem(serverItem); |
| 375 | 386 | updateMediaServerKeepalive(serverItem.getId(), null); |
| 376 | 387 | setZLMConfig(serverItem, "0".equals(zlmServerConfig.getHookEnable())); |
| 388 | + | |
| 377 | 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 | 59 | private IRedisCatchStorage redisCatchStorage; |
| 60 | 60 | |
| 61 | 61 | @Autowired |
| 62 | + private IVideoManagerStorager storager; | |
| 63 | + | |
| 64 | + @Autowired | |
| 62 | 65 | private UserSetup userSetup; |
| 63 | 66 | |
| 64 | 67 | @Autowired |
| ... | ... | @@ -278,7 +281,27 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 278 | 281 | |
| 279 | 282 | @Override |
| 280 | 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 | 307 | @Override |
| ... | ... | @@ -289,8 +312,8 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 289 | 312 | gbStreamMapper.batchDel(streamProxyItemList); |
| 290 | 313 | } |
| 291 | 314 | streamProxyMapper.deleteAutoRemoveItemByMediaServerId(mediaServerId); |
| 292 | - // 其他的流设置未启用 | |
| 293 | - streamProxyMapper.updateStatus(false, mediaServerId); | |
| 315 | + // 其他的流设置离线 | |
| 316 | + streamProxyMapper.updateStatusByMediaServerId(false, mediaServerId); | |
| 294 | 317 | String type = "PULL"; |
| 295 | 318 | |
| 296 | 319 | // 发送redis消息 |
| ... | ... | @@ -314,4 +337,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService { |
| 314 | 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 | 398 | /** |
| 399 | 399 | * 根据媒体ID获取启用/不启用的代理列表 |
| 400 | 400 | * @param id 媒体ID |
| 401 | - * @param b 启用/不启用 | |
| 401 | + * @param enable 启用/不启用 | |
| 402 | + * @param status 状态 | |
| 402 | 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 | 408 | * 根据通道ID获取其所在设备 | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/StreamProxyMapper.java
| ... | ... | @@ -11,9 +11,9 @@ import java.util.List; |
| 11 | 11 | public interface StreamProxyMapper { |
| 12 | 12 | |
| 13 | 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 | 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 | 17 | "${enable_remove_none_reader}, '${createTime}' )") |
| 18 | 18 | int add(StreamProxyItem streamProxyDto); |
| 19 | 19 | |
| ... | ... | @@ -30,6 +30,7 @@ public interface StreamProxyMapper { |
| 30 | 30 | "rtp_type=#{rtp_type}, " + |
| 31 | 31 | "enable_hls=#{enable_hls}, " + |
| 32 | 32 | "enable=#{enable}, " + |
| 33 | + "status=#{status}, " + | |
| 33 | 34 | "enable_remove_none_reader=#{enable_remove_none_reader}, " + |
| 34 | 35 | "enable_mp4=#{enable_mp4} " + |
| 35 | 36 | "WHERE app=#{app} AND stream=#{stream}") |
| ... | ... | @@ -49,8 +50,8 @@ public interface StreamProxyMapper { |
| 49 | 50 | |
| 50 | 51 | @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + |
| 51 | 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 | 56 | @Select("SELECT st.*, pgs.gbId, pgs.name, pgs.longitude, pgs.latitude FROM stream_proxy st " + |
| 56 | 57 | "LEFT JOIN gb_stream pgs on st.app = pgs.app AND st.stream = pgs.stream " + |
| ... | ... | @@ -58,9 +59,14 @@ public interface StreamProxyMapper { |
| 58 | 59 | List<StreamProxyItem> selectInMediaServer(String id); |
| 59 | 60 | |
| 60 | 61 | @Update("UPDATE stream_proxy " + |
| 61 | - "SET enable=#{status} " + | |
| 62 | + "SET status=#{status} " + | |
| 62 | 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 | 71 | @Delete("DELETE FROM stream_proxy WHERE enable_remove_none_reader=true AND mediaServerId=#{mediaServerId}") |
| 66 | 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 | 860 | } |
| 861 | 861 | |
| 862 | 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 | 42 | </el-table-column> |
| 43 | 43 | |
| 44 | 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 | 53 | <el-table-column label="启用" width="120" align="center"> |
| 46 | 54 | <template slot-scope="scope"> |
| 47 | 55 | <div slot="reference" class="name-wrapper"> | ... | ... |
web_src/src/components/dialog/StreamProxyEdit.vue
| ... | ... | @@ -46,7 +46,6 @@ |
| 46 | 46 | style="width: 100%" |
| 47 | 47 | placeholder="请选择拉流节点" |
| 48 | 48 | > |
| 49 | - <el-option label="自动选择" value="auto"></el-option> | |
| 50 | 49 | <el-option |
| 51 | 50 | v-for="item in mediaServerList" |
| 52 | 51 | :key="item.id" |
| ... | ... | @@ -172,7 +171,7 @@ export default { |
| 172 | 171 | enable_mp4: false, |
| 173 | 172 | enable_remove_none_reader: false, |
| 174 | 173 | platformGbId: null, |
| 175 | - mediaServerId: "auto", | |
| 174 | + mediaServerId: null, | |
| 176 | 175 | }, |
| 177 | 176 | mediaServerList:{}, |
| 178 | 177 | ffmpegCmdList:{}, |
| ... | ... | @@ -206,7 +205,8 @@ export default { |
| 206 | 205 | console.log(error); |
| 207 | 206 | }); |
| 208 | 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 | 212 | mediaServerIdChange:function (){ | ... | ... |