From edb033ccd7df53e2444f38c9657946ce15856153 Mon Sep 17 00:00:00 2001 From: panlinlin <648540858@qq.com> Date: 星期五, 26 三月 2021 18:32:36 +0800 Subject: [PATCH] 添加获取直播流的api --- src/main/java/com/genersoft/iot/vmp/common/RealVideo.java | 206 +++++++++++ src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 6 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 4 web_src/src/components/PushVideoList.vue | 256 ++++++++++++++ src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java | 20 src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java | 2 src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java | 45 ++ src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 9 src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java | 31 + src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java | 13 web_src/src/router/index.js | 5 src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java | 87 ++++ web_src/src/components/UiHeader.vue | 1 src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java | 369 ++++++++++++++++++++ 14 files changed, 1,039 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/RealVideo.java b/src/main/java/com/genersoft/iot/vmp/common/RealVideo.java new file mode 100644 index 0000000..b5ed851 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/common/RealVideo.java @@ -0,0 +1,206 @@ +package com.genersoft.iot.vmp.common; + +import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + + +public class RealVideo implements Comparable<RealVideo>{ + + /** + * 搴旂敤鍚� + */ + private String app; + + /** + * 娴乮d + */ + private String stream; + + /** + * 瑙傜湅鎬讳汉鏁帮紝鍖呮嫭hls/rtsp/rtmp/http-flv/ws-flv + */ + private String totalReaderCount; + + /** + * 鍗忚 鍖呮嫭hls/rtsp/rtmp/http-flv/ws-flv + */ + private List<MediaSchema> schemas; + + /** + * 浜х敓婧愮被鍨嬶紝 + * unknown = 0, + * rtmp_push=1, + * rtsp_push=2, + * rtp_push=3, + * pull=4, + * ffmpeg_pull=5, + * mp4_vod=6, + * device_chn=7 + */ + private int originType; + + /** + * 瀹㈡埛绔拰鏈嶅姟鍣ㄧ綉缁滀俊鎭紝鍙兘涓簄ull绫诲瀷 + */ + private MediaItem.OriginSock originSock; + + /** + * 浜х敓婧愮被鍨嬬殑瀛楃涓叉弿杩� + */ + private String originTypeStr; + + /** + * 浜х敓婧愮殑url + */ + private String originUrl; + + /** + * GMT unix绯荤粺鏃堕棿鎴筹紝鍗曚綅绉� + */ + private Long createStamp; + + /** + * 瀛樻椿鏃堕棿锛屽崟浣嶇 + */ + private Long aliveSecond; + + /** + * 闊宠棰戣建閬� + */ + private List<MediaItem.MediaTrack> tracks; + + /** + * 闊宠棰戣建閬� + */ + private String vhost; + + public String getVhost() { + return vhost; + } + + public void setVhost(String vhost) { + this.vhost = vhost; + } + + @Override + public int compareTo(@NotNull RealVideo realVideo) { + return new Long(this.createStamp - realVideo.getCreateStamp().intValue()).intValue(); + } + + public static class MediaSchema { + private String schema; + private Long bytesSpeed; + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public Long getBytesSpeed() { + return bytesSpeed; + } + + public void setBytesSpeed(Long bytesSpeed) { + this.bytesSpeed = bytesSpeed; + } + } + + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public String getTotalReaderCount() { + return totalReaderCount; + } + + public void setTotalReaderCount(String totalReaderCount) { + this.totalReaderCount = totalReaderCount; + } + + public List<MediaSchema> getSchemas() { + return schemas; + } + + public void setSchemas(List<MediaSchema> schemas) { + this.schemas = schemas; + } + + public int getOriginType() { + return originType; + } + + public void setOriginType(int originType) { + this.originType = originType; + } + + public MediaItem.OriginSock getOriginSock() { + return originSock; + } + + public void setOriginSock(MediaItem.OriginSock originSock) { + this.originSock = originSock; + } + + + public String getOriginTypeStr() { + return originTypeStr; + } + + public void setOriginTypeStr(String originTypeStr) { + this.originTypeStr = originTypeStr; + } + + public String getOriginUrl() { + return originUrl; + } + + public void setOriginUrl(String originUrl) { + this.originUrl = originUrl; + } + + public Long getCreateStamp() { + return createStamp; + } + + public void setCreateStamp(Long createStamp) { + this.createStamp = createStamp; + } + + public Long getAliveSecond() { + return aliveSecond; + } + + public void setAliveSecond(Long aliveSecond) { + this.aliveSecond = aliveSecond; + } + + public List<MediaItem.MediaTrack> getTracks() { + return tracks; + } + + public void setTracks(List<MediaItem.MediaTrack> tracks) { + this.tracks = tracks; + } + + +} + diff --git a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java index 8e9e871..8af9956 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java +++ b/src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java @@ -10,6 +10,8 @@ public static final String MEDIA_SERVER_PREFIX = "VMP_media_server"; + public static final String MEDIA_STREAM_PREFIX = "VMP_media_stream"; + public static final String DEVICE_PREFIX = "VMP_device_"; public static final String CACHEKEY_PREFIX = "VMP_channel_"; diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java index 51f61ef..51c6e1b 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java @@ -51,8 +51,8 @@ @Autowired private IRedisCatchStorage redisCatchStorage; - // @Autowired - // private ZLMRESTfulUtils zlmresTfulUtils; + @Autowired + private ZLMMediaListManager zlmMediaListManager; @Autowired private ZLMHttpHookSubscribe subscribe; @@ -237,6 +237,7 @@ // 娴佹秷澶辩Щ闄edis play String app = json.getString("app"); String streamId = json.getString("stream"); + String schema = json.getString("schema"); boolean regist = json.getBoolean("regist"); StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(streamId); if ("rtp".equals(app) && !regist ) { @@ -247,6 +248,10 @@ streamInfo = redisCatchStorage.queryPlaybackByStreamId(streamId); redisCatchStorage.stopPlayback(streamInfo); } + }else { + if (!"rtp".equals(app) && "rtsp".equals(schema)){ + zlmMediaListManager.updateMediaList(); + } } JSONObject ret = new JSONObject(); ret.put("code", 0); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java new file mode 100644 index 0000000..b17151a --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaListManager.java @@ -0,0 +1,87 @@ +package com.genersoft.iot.vmp.media.zlm; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.genersoft.iot.vmp.common.RealVideo; +import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import com.genersoft.iot.vmp.gb28181.session.SsrcUtil; +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import com.genersoft.iot.vmp.storager.impl.RedisCatchStorageImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +public class ZLMMediaListManager { + + private Logger logger = LoggerFactory.getLogger("ZLMMediaListManager"); + + @Autowired + private ZLMRESTfulUtils zlmresTfulUtils; + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + + public void updateMediaList() { + JSONObject mediaList = zlmresTfulUtils.getMediaList(); + String dataStr = mediaList.getString("data"); + + Integer code = mediaList.getInteger("code"); + Map<String, RealVideo> result = new HashMap<>(); + if (code == 0 ) { + if (dataStr != null) { + List<MediaItem> mediaItems = JSON.parseObject(dataStr, new TypeReference<List<MediaItem>>() {}); + for (MediaItem item : mediaItems) { + if ("rtp".equals(item.getApp())) { + continue; + } + String key = item.getApp() + "_" + item.getStream(); + RealVideo realVideo = result.get(key); + if (realVideo == null) { + realVideo = new RealVideo(); + realVideo.setApp(item.getApp()); + realVideo.setStream(item.getStream()); + realVideo.setAliveSecond(item.getAliveSecond()); + realVideo.setCreateStamp(item.getCreateStamp()); + realVideo.setOriginSock(item.getOriginSock()); + realVideo.setTotalReaderCount(item.getTotalReaderCount()); + realVideo.setOriginType(item.getOriginType()); + realVideo.setOriginTypeStr(item.getOriginTypeStr()); + realVideo.setOriginUrl(item.getOriginUrl()); + realVideo.setCreateStamp(item.getCreateStamp()); + realVideo.setAliveSecond(item.getAliveSecond()); + + ArrayList<RealVideo.MediaSchema> mediaSchemas = new ArrayList<>(); + realVideo.setSchemas(mediaSchemas); + realVideo.setTracks(item.getTracks()); + realVideo.setVhost(item.getVhost()); + result.put(key, realVideo); + } + + RealVideo.MediaSchema mediaSchema = new RealVideo.MediaSchema(); + mediaSchema.setSchema(item.getSchema()); + mediaSchema.setBytesSpeed(item.getBytesSpeed()); + realVideo.getSchemas().add(mediaSchema); + } + + } + }else { + logger.warn("鏇存柊瑙嗛娴佸け璐ワ紝閿欒code锛� " + code); + } + + List<RealVideo> realVideos = new ArrayList<>(result.values()); + Collections.sort(realVideos); + redisCatchStorage.updateMediaList(realVideos); + } + + + +} diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java index 42670a7..ad17fee 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java @@ -73,6 +73,10 @@ return sendPost("getMediaList",param); } + public JSONObject getMediaList(){ + return sendPost("getMediaList",null); + } + public JSONObject getMediaInfo(String app, String schema, String stream){ Map<String, Object> param = new HashMap<>(); param.put("app",app); diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java index 490bfd8..e65fae0 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java @@ -60,6 +60,9 @@ @Autowired private ZLMRESTfulUtils zlmresTfulUtils; + @Autowired + private ZLMMediaListManager zlmMediaListManager; + @Override public void run(String... strings) throws Exception { // 鑾峰彇zlm淇℃伅 @@ -70,6 +73,8 @@ if (autoConfig) saveZLMConfig(); mediaServerConfig = getMediaServerConfig(); redisCatchStorage.updateMediaInfo(mediaServerConfig); + // 鏇存柊娴佸垪琛� + zlmMediaListManager.updateMediaList(); } } @@ -130,4 +135,5 @@ logger.info("璁剧疆zlm澶辫触: " + responseJSON.getString("msg")); } } + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java new file mode 100644 index 0000000..51a89b2 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/dto/MediaItem.java @@ -0,0 +1,369 @@ +package com.genersoft.iot.vmp.media.zlm.dto; + +import com.alibaba.fastjson.JSONObject; + +import java.util.List; + +public class MediaItem { + + /** + * 搴旂敤鍚� + */ + private String app; + + /** + * 娴乮d + */ + private String stream; + + /** + * 瑙傜湅鎬讳汉鏁帮紝鍖呮嫭hls/rtsp/rtmp/http-flv/ws-flv + */ + private String totalReaderCount; + + /** + * 鍗忚 鍖呮嫭hls/rtsp/rtmp/http-flv/ws-flv + */ + private String schema; + + + /** + * 浜х敓婧愮被鍨嬶紝 + * unknown = 0, + * rtmp_push=1, + * rtsp_push=2, + * rtp_push=3, + * pull=4, + * ffmpeg_pull=5, + * mp4_vod=6, + * device_chn=7 + */ + private int originType; + + /** + * 瀹㈡埛绔拰鏈嶅姟鍣ㄧ綉缁滀俊鎭紝鍙兘涓簄ull绫诲瀷 + */ + private OriginSock originSock; + + /** + * 浜х敓婧愮被鍨嬬殑瀛楃涓叉弿杩� + */ + private String originTypeStr; + + /** + * 浜х敓婧愮殑url + */ + private String originUrl; + + /** + * GMT unix绯荤粺鏃堕棿鎴筹紝鍗曚綅绉� + */ + private Long createStamp; + + /** + * 瀛樻椿鏃堕棿锛屽崟浣嶇 + */ + private Long aliveSecond; + + /** + * 鏁版嵁浜х敓閫熷害锛屽崟浣峛yte/s + */ + private Long bytesSpeed; + + /** + * 闊宠棰戣建閬� + */ + private List<MediaTrack> tracks; + + /** + * 闊宠棰戣建閬� + */ + private String vhost; + + + public static class MediaTrack { + /** + * 闊抽閫氶亾鏁� + */ + private int channels; + + /** + * H264 = 0, H265 = 1, AAC = 2, G711A = 3, G711U = 4 + */ + private int codecId; + + /** + * 缂栫爜绫诲瀷鍚嶇О CodecAAC CodecH264 + */ + private String codecIdName; + + /** + * Video = 0, Audio = 1 + */ + private int codecType; + + /** + * 杞ㄩ亾鏄惁鍑嗗灏辩华 + */ + private boolean ready; + + /** + * 闊抽閲囨牱浣嶆暟 + */ + private int sampleBit; + + /** + * 闊抽閲囨牱鐜� + */ + private int sampleRate; + + /** + * 瑙嗛fps + */ + private int fps; + + /** + * 瑙嗛楂� + */ + private int height; + + /** + * 瑙嗛瀹� + */ + private int width; + + public int getChannels() { + return channels; + } + + public void setChannels(int channels) { + this.channels = channels; + } + + public int getCodecId() { + return codecId; + } + + public void setCodecId(int codecId) { + this.codecId = codecId; + } + + public String getCodecIdName() { + return codecIdName; + } + + public void setCodecIdName(String codecIdName) { + this.codecIdName = codecIdName; + } + + public int getCodecType() { + return codecType; + } + + public void setCodecType(int codecType) { + this.codecType = codecType; + } + + public boolean isReady() { + return ready; + } + + public void setReady(boolean ready) { + this.ready = ready; + } + + public int getSampleBit() { + return sampleBit; + } + + public void setSampleBit(int sampleBit) { + this.sampleBit = sampleBit; + } + + public int getSampleRate() { + return sampleRate; + } + + public void setSampleRate(int sampleRate) { + this.sampleRate = sampleRate; + } + + public int getFps() { + return fps; + } + + public void setFps(int fps) { + this.fps = fps; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + } + + public static class OriginSock{ + private String identifier; + private String local_ip; + private int local_port; + private String peer_ip; + private int peer_port; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getLocal_ip() { + return local_ip; + } + + public void setLocal_ip(String local_ip) { + this.local_ip = local_ip; + } + + public int getLocal_port() { + return local_port; + } + + public void setLocal_port(int local_port) { + this.local_port = local_port; + } + + public String getPeer_ip() { + return peer_ip; + } + + public void setPeer_ip(String peer_ip) { + this.peer_ip = peer_ip; + } + + public int getPeer_port() { + return peer_port; + } + + public void setPeer_port(int peer_port) { + this.peer_port = peer_port; + } + } + + public String getApp() { + return app; + } + + public void setApp(String app) { + this.app = app; + } + + public String getStream() { + return stream; + } + + public void setStream(String stream) { + this.stream = stream; + } + + public String getTotalReaderCount() { + return totalReaderCount; + } + + public void setTotalReaderCount(String totalReaderCount) { + this.totalReaderCount = totalReaderCount; + } + + + public int getOriginType() { + return originType; + } + + public void setOriginType(int originType) { + this.originType = originType; + } + + + public String getOriginTypeStr() { + return originTypeStr; + } + + public void setOriginTypeStr(String originTypeStr) { + this.originTypeStr = originTypeStr; + } + + public String getOriginUrl() { + return originUrl; + } + + public void setOriginUrl(String originUrl) { + this.originUrl = originUrl; + } + + public Long getCreateStamp() { + return createStamp; + } + + public void setCreateStamp(Long createStamp) { + this.createStamp = createStamp; + } + + public Long getAliveSecond() { + return aliveSecond; + } + + public void setAliveSecond(Long aliveSecond) { + this.aliveSecond = aliveSecond; + } + + public List<MediaTrack> getTracks() { + return tracks; + } + + public void setTracks(List<MediaTrack> tracks) { + this.tracks = tracks; + } + + public String getSchema() { + return schema; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public void setOriginSock(OriginSock originSock) { + this.originSock = originSock; + } + + public Long getBytesSpeed() { + return bytesSpeed; + } + + public void setBytesSpeed(Long bytesSpeed) { + this.bytesSpeed = bytesSpeed; + } + + public String getVhost() { + return vhost; + } + + public void setVhost(String vhost) { + this.vhost = vhost; + } + + public OriginSock getOriginSock() { + return originSock; + } +} diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java index 9061184..c9f5fff 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/IRedisCatchStorage.java @@ -1,11 +1,13 @@ package com.genersoft.iot.vmp.storager; +import com.genersoft.iot.vmp.common.RealVideo; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.conf.MediaServerConfig; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; +import java.util.List; import java.util.Map; public interface IRedisCatchStorage { @@ -102,4 +104,15 @@ */ boolean isChannelSendingRTP(String channelId); + /** + * 鏇存柊濯掍綋娴佸垪琛� + * @param mediaList + */ + void updateMediaList(List<RealVideo> mediaList); + + /** + * 鑾峰彇褰撳墠濯掍綋娴佸垪琛� + * @return List<RealVideo> + */ + List<Object> getMediaList(int start, int end); } diff --git a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java index 3feb347..c5e31d6 100644 --- a/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/impl/RedisCatchStorageImpl.java @@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.storager.impl; +import com.genersoft.iot.vmp.common.RealVideo; import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.common.VideoManagerConstants; import com.genersoft.iot.vmp.conf.MediaServerConfig; @@ -10,9 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Component public class RedisCatchStorageImpl implements IRedisCatchStorage { @@ -251,4 +250,30 @@ } } + + /** + * 鏇存柊濯掍綋娴佸垪琛� + * @param mediaList + */ + @Override + public void updateMediaList(List<RealVideo> mediaList) { + String key = VideoManagerConstants.MEDIA_STREAM_PREFIX; + redis.del(key); + for (int i = 0; i < mediaList.size(); i++) { + RealVideo realVideo = mediaList.get(i); + redis.zAdd(key, realVideo, realVideo.getCreateStamp()); + } + } + + + /** + * 鑾峰彇褰撳墠濯掍綋娴佸垪琛� + * @return List<RealVideo> + */ + @Override + public List<Object> getMediaList(int start, int end) { + String key = VideoManagerConstants.MEDIA_STREAM_PREFIX; + Set<Object> realVideos = redis.ZRange(key, start, end); + return new ArrayList(realVideos); + } } diff --git a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java index f83d5f3..5db3c7f 100644 --- a/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java +++ b/src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java @@ -396,7 +396,7 @@ * @param value * @param score */ - public void zAdd(String key, String value, double score) { + public void zAdd(Object key, Object value, double score) { redisTemplate.opsForZSet().add(key, value, score); } @@ -406,7 +406,7 @@ * @param key * @param value */ - public void zRemove(String key, String value) { + public void zRemove(Object key, Object value) { redisTemplate.opsForZSet().remove(key, value); } @@ -417,7 +417,7 @@ * @param value * @param score */ - public Double zIncrScore(String key, String value, double score) { + public Double zIncrScore(Object key, Object value, double score) { return redisTemplate.opsForZSet().incrementScore(key, value, score); } @@ -428,7 +428,7 @@ * @param value * @return */ - public Double zScore(String key, String value) { + public Double zScore(Object key, Object value) { return redisTemplate.opsForZSet().score(key, value); } @@ -439,7 +439,7 @@ * @param value * @return */ - public Long zRank(String key, String value) { + public Long zRank(Object key, Object value) { return redisTemplate.opsForZSet().rank(key, value); } @@ -449,7 +449,7 @@ * @param key * @return */ - public Long zSize(String key) { + public Long zSize(Object key) { return redisTemplate.opsForZSet().zCard(key); } @@ -463,7 +463,7 @@ * @param end * @return */ - public Set<String> ZRange(String key, int start, int end) { + public Set<Object> ZRange(Object key, int start, int end) { return redisTemplate.opsForZSet().range(key, start, end); } /** @@ -474,7 +474,7 @@ * @param end * @return */ - public Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(String key, int start, int end) { + public Set<ZSetOperations.TypedTuple<String>> zRangeWithScore(Object key, int start, int end) { return redisTemplate.opsForZSet().rangeWithScores(key, start, end); } /** @@ -487,7 +487,7 @@ * @param end * @return */ - public Set<String> zRevRange(String key, int start, int end) { + public Set<String> zRevRange(Object key, int start, int end) { return redisTemplate.opsForZSet().reverseRange(key, start, end); } /** @@ -498,7 +498,7 @@ * @param max * @return */ - public Set<String> zSortRange(String key, int min, int max) { + public Set<String> zSortRange(Object key, int min, int max) { return redisTemplate.opsForZSet().rangeByScore(key, min, max); } diff --git a/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java b/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java new file mode 100644 index 0000000..84910c5 --- /dev/null +++ b/src/main/java/com/genersoft/iot/vmp/web/ApiMediaController.java @@ -0,0 +1,45 @@ +package com.genersoft.iot.vmp.web; + +import com.alibaba.fastjson.JSONObject; +import com.genersoft.iot.vmp.common.RealVideo; +import com.genersoft.iot.vmp.conf.SipConfig; +import com.genersoft.iot.vmp.storager.IRedisCatchStorage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; + +/** + * 鍏煎LiveGBS鐨凙PI锛氱郴缁熸帴鍙� + */ +@Controller +@CrossOrigin +@RequestMapping(value = "/api/v1/media") +public class ApiMediaController { + + private final static Logger logger = LoggerFactory.getLogger(ApiMediaController.class); + + @Autowired + private IRedisCatchStorage redisCatchStorage; + + + @RequestMapping(value = "/list") + @ResponseBody + public JSONObject list( @RequestParam(required = false)Integer start, + @RequestParam(required = false)Integer limit, + @RequestParam(required = false)String q, + @RequestParam(required = false)Boolean online ){ + + List<Object> mediaList = redisCatchStorage.getMediaList(start - 1, start - 1 + limit); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", 0); + jsonObject.put("data", mediaList); + return jsonObject; + } +} diff --git a/web_src/src/components/PushVideoList.vue b/web_src/src/components/PushVideoList.vue new file mode 100644 index 0000000..60a5c9e --- /dev/null +++ b/web_src/src/components/PushVideoList.vue @@ -0,0 +1,256 @@ +<template> + <div id="app"> + <el-container> + <el-header> + <uiHeader></uiHeader> + </el-header> + <el-main> + <div style="background-color: #FFFFFF; margin-bottom: 1rem; position: relative; padding: 0.5rem; text-align: left;"> + <span style="font-size: 1rem; font-weight: bold;">鎺ㄦ祦鍒楄〃</span> + <div style="position: absolute; right: 1rem; top: 0.3rem;"> + <el-button icon="el-icon-refresh-right" circle size="mini" :loading="getDeviceListLoading" @click="getDeviceList()"></el-button> + </div> + </div> + <!-- <devicePlayer ref="devicePlayer"></devicePlayer> --> + <el-table :data="deviceList" border style="width: 100%" :height="winHeight"> + <el-table-column prop="schema" label="鍗忚" width="180" align="center"> + </el-table-column> + <el-table-column prop="streamUrl" label="娴佸湴鍧�" width="240" align="center"> + </el-table-column> + <el-table-column prop="online" label="鍦ㄧ嚎浜烘暟" width="240" align="center"> + </el-table-column> + <el-table-column prop="startTime" label="寮�濮嬫椂闂�" align="center"> + </el-table-column> + + + <el-table-column label="鎿嶄綔" width="360" align="center" fixed="right"> + <template slot-scope="scope"> + <el-button size="mini" :ref="scope.row.deviceId + 'refbtn' " icon="el-icon-refresh" @click="refDevice(scope.row)">鍒锋柊</el-button> + <el-button-group> + <el-button size="mini" icon="el-icon-video-play" @click="sendDevicePush(scope.row)">鎾斁</el-button> + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="!!scope.row.streamId" @click="stopDevicePush(scope.row)">鍋滄</el-button> + </el-button-group> + </template> + </el-table-column> + </el-table> + <el-pagination + style="float: right" + @size-change="handleSizeChange" + @current-change="currentChange" + :current-page="currentPage" + :page-size="count" + :page-sizes="[15, 25, 35, 50]" + layout="total, sizes, prev, pager, next" + :total="total"> + </el-pagination> + + </el-main> + </el-container> + </div> +</template> + +<script> + import uiHeader from './UiHeader.vue' + export default { + name: 'app', + components: { + uiHeader + }, + data() { + return { + deviceList: [], //璁惧鍒楄〃 + currentDevice: {}, //褰撳墠鎿嶄綔璁惧瀵硅薄 + + videoComponentList: [], + updateLooper: 0, //鏁版嵁鍒锋柊杞鏍囧織 + currentDeviceChannelsLenth:0, + winHeight: window.innerHeight - 200, + currentPage:1, + count:15, + total:0, + getDeviceListLoading: false + }; + }, + computed: { + getcurrentDeviceChannels: function() { + let data = this.currentDevice['channelMap']; + let channels = null; + if (data) { + channels = Object.keys(data).map(key => { + return data[key]; + }); + this.currentDeviceChannelsLenth = channels.length; + } + + console.log("鏁版嵁锛�" + JSON.stringify(channels)); + return channels; + } + }, + mounted() { + this.initData(); + this.updateLooper = setInterval(this.initData, 10000); + }, + destroyed() { + this.$destroy('videojs'); + clearTimeout(this.updateLooper); + }, + methods: { + initData: function() { + this.getDeviceList(); + }, + currentChange: function(val){ + this.currentPage = val; + this.getDeviceList(); + }, + handleSizeChange: function(val){ + this.count = val; + this.getDeviceList(); + }, + getDeviceList: function() { + let that = this; + this.getDeviceListLoading = true; + this.$axios.get(`/api/devices`,{ + params: { + page: that.currentPage, + count: that.count + } + } ) + .then(function (res) { + console.log(res); + console.log(res.data.list); + that.total = res.data.total; + that.deviceList = res.data.list; + that.getDeviceListLoading = false; + }) + .catch(function (error) { + console.log(error); + that.getDeviceListLoading = false; + }); + + }, + showChannelList: function(row) { + console.log(JSON.stringify(row)) + this.$router.push(`/channelList/${row.deviceId}/0/15/1`); + }, + showDevicePosition: function(row) { + console.log(JSON.stringify(row)) + this.$router.push(`/devicePosition/${row.deviceId}/0/15/1`); + }, + + //gb28181骞冲彴瀵规帴 + //鍒锋柊璁惧淇℃伅 + refDevice: function(itemData) { + ///api/devices/{deviceId}/sync + console.log("鍒锋柊瀵瑰簲璁惧:" + itemData.deviceId); + var that = this; + that.$refs[itemData.deviceId + 'refbtn' ].loading = true; + this.$axios({ + method: 'post', + url: '/api/devices/' + itemData.deviceId + '/sync' + }).then(function(res) { + console.log("鍒锋柊璁惧缁撴灉锛�"+JSON.stringify(res)); + if (!res.data.deviceId) { + that.$message({ + showClose: true, + message: res.data, + type: 'error' + }); + }else{ + that.$message({ + showClose: true, + message: '璇锋眰鎴愬姛', + type: 'success' + }); + } + that.initData() + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; + }).catch(function(e) { + console.error(e) + that.$refs[itemData.deviceId + 'refbtn' ].loading = false; + });; + }, + //閫氱煡璁惧涓婁紶濯掍綋娴� + sendDevicePush: function(itemData) { + // let deviceId = this.currentDevice.deviceId; + // let channelId = itemData.channelId; + // console.log("閫氱煡璁惧鎺ㄦ祦1锛�" + deviceId + " : " + channelId); + // let that = this; + // this.$axios({ + // method: 'get', + // url: '/api/play/' + deviceId + '/' + channelId + // }).then(function(res) { + // let ssrc = res.data.ssrc; + // that.$refs.devicePlayer.play(ssrc,deviceId,channelId); + // }).catch(function(e) { + // }); + }, + transportChange: function (row) { + console.log(row); + console.log(`淇敼浼犺緭鏂瑰紡涓� ${row.streamMode}锛�${row.deviceId} `); + let that = this; + this.$axios({ + method: 'get', + url: '/api/devices/' + row.deviceId + '/transport/' + row.streamMode + }).then(function(res) { + + }).catch(function(e) { + }); + } + + } + }; +</script> + +<style> + .videoList { + display: flex; + flex-wrap: wrap; + align-content: flex-start; + } + + .video-item { + position: relative; + width: 15rem; + height: 10rem; + margin-right: 1rem; + background-color: #000000; + } + + .video-item-img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 100%; + height: 100%; + } + + .video-item-img:after { + content: ""; + display: inline-block; + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 3rem; + height: 3rem; + background-image: url("../assets/loading.png"); + background-size: cover; + background-color: #000000; + } + + .video-item-title { + position: absolute; + bottom: 0; + color: #000000; + background-color: #ffffff; + line-height: 1.5rem; + padding: 0.3rem; + width: 14.4rem; + } +</style> diff --git a/web_src/src/components/UiHeader.vue b/web_src/src/components/UiHeader.vue index 1d3f76a..fa1c442 100644 --- a/web_src/src/components/UiHeader.vue +++ b/web_src/src/components/UiHeader.vue @@ -3,6 +3,7 @@ <el-menu router :default-active="this.$route.path" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" mode="horizontal"> <el-menu-item index="/">鎺у埗鍙�</el-menu-item> <el-menu-item index="/deviceList">璁惧鍒楄〃</el-menu-item> + <el-menu-item index="/pushVideoList">鎺ㄦ祦鍒楄〃</el-menu-item> <el-menu-item index="/parentPlatformList/15/1">鍥芥爣绾ц仈</el-menu-item> <el-switch v-model="alarmNotify" active-text="鎶ヨ淇℃伅鎺ㄩ��" style="display: block float: right" @change="sseControl"></el-switch> <el-menu-item style="float: right;" @click="loginout">閫�鍑�</el-menu-item> diff --git a/web_src/src/router/index.js b/web_src/src/router/index.js index 43d2110..fc55dd5 100644 --- a/web_src/src/router/index.js +++ b/web_src/src/router/index.js @@ -4,6 +4,7 @@ import control from '../components/control.vue' import deviceList from '../components/DeviceList.vue' import channelList from '../components/channelList.vue' +import pushVideoList from '../components/PushVideoList.vue' import devicePosition from '../components/devicePosition.vue' import login from '../components/Login.vue' import parentPlatformList from '../components/ParentPlatformList.vue' @@ -28,6 +29,10 @@ component: deviceList, }, { + path: '/pushVideoList', + component: pushVideoList, + }, + { path: '/login', name: '鐧诲綍', component: login, -- Gitblit v1.8.0