648540858
2024-05-29 764d04b497356ba6bcbb75fd42b51eca750f7223
src/main/java/com/genersoft/iot/vmp/service/impl/InviteStreamServiceImpl.java
old mode 100644 new mode 100755
@@ -1,17 +1,23 @@
package com.genersoft.iot.vmp.service.impl;
import com.alibaba.fastjson2.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
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.VideoManagerConstants;
import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -20,6 +26,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
@Service
@DS("master")
public class InviteStreamServiceImpl implements IInviteStreamService {
    private final Logger logger = LoggerFactory.getLogger(InviteStreamServiceImpl.class);
@@ -28,6 +35,35 @@
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private IVideoManagerStorage storage;
    /**
     * 流到来的处理
     */
    @Async("taskExecutor")
    @org.springframework.context.event.EventListener
    public void onApplicationEvent(MediaArrivalEvent event) {
//        if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) {
//
//        }
    }
    /**
     * 流离开的处理
     */
    @Async("taskExecutor")
    @EventListener
    public void onApplicationEvent(MediaDepartureEvent event) {
        if ("rtsp".equals(event.getSchema()) && "rtp".equals(event.getApp())) {
            InviteInfo inviteInfo = getInviteInfoByStream(null, event.getStream());
            if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) {
                removeInviteInfo(inviteInfo);
                storage.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
            }
        }
    }
    @Override
    public void updateInviteInfo(InviteInfo inviteInfo) {
@@ -77,10 +113,11 @@
        }
        String key = VideoManagerConstants.INVITE_PREFIX +
                "_" + inviteInfoForUpdate.getType() +
                "_" + inviteInfoForUpdate.getDeviceId() +
                "_" + inviteInfoForUpdate.getChannelId() +
                "_" + inviteInfoForUpdate.getStream();
                ":" + inviteInfoForUpdate.getType() +
                ":" + inviteInfoForUpdate.getDeviceId() +
                ":" + inviteInfoForUpdate.getChannelId() +
                ":" + inviteInfoForUpdate.getStream()+
                ":" + inviteInfoForUpdate.getSsrcInfo().getSsrc();
        redisTemplate.opsForValue().set(key, inviteInfoForUpdate);
    }
@@ -93,10 +130,11 @@
        }
        removeInviteInfo(inviteInfoInDb);
        String key = VideoManagerConstants.INVITE_PREFIX +
                "_" + inviteInfo.getType() +
                "_" + inviteInfo.getDeviceId() +
                "_" + inviteInfo.getChannelId() +
                "_" + stream;
                ":" + inviteInfo.getType() +
                ":" + inviteInfo.getDeviceId() +
                ":" + inviteInfo.getChannelId() +
                ":" + stream +
                ":" + inviteInfo.getSsrcInfo().getSsrc();
        inviteInfoInDb.setStream(stream);
        if (inviteInfoInDb.getSsrcInfo() != null) {
            inviteInfoInDb.getSsrcInfo().setStream(stream);
@@ -108,13 +146,17 @@
    @Override
    public InviteInfo getInviteInfo(InviteSessionType type, String deviceId, String channelId, String stream) {
        String key = VideoManagerConstants.INVITE_PREFIX +
                "_" + (type != null ? type : "*") +
                "_" + (deviceId != null ? deviceId : "*") +
                "_" + (channelId != null ? channelId : "*") +
                "_" + (stream != null ? stream : "*");
                ":" + (type != null ? type : "*") +
                ":" + (deviceId != null ? deviceId : "*") +
                ":" + (channelId != null ? channelId : "*") +
                ":" + (stream != null ? stream : "*")
                + ":*";
        List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
        if (scanResult.size() != 1) {
        if (scanResult.isEmpty()) {
            return null;
        }
        if (scanResult.size() != 1) {
            logger.warn("[获取InviteInfo] 发现 key: {}存在多条", key);
        }
        return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
@@ -133,10 +175,11 @@
    @Override
    public void removeInviteInfo(InviteSessionType type, String deviceId, String channelId, String stream) {
        String scanKey = VideoManagerConstants.INVITE_PREFIX +
                "_" + (type != null ? type : "*") +
                "_" + (deviceId != null ? deviceId : "*") +
                "_" + (channelId != null ? channelId : "*") +
                "_" + (stream != null ? stream : "*");
                ":" + (type != null ? type : "*") +
                ":" + (deviceId != null ? deviceId : "*") +
                ":" + (channelId != null ? channelId : "*") +
                ":" + (stream != null ? stream : "*") +
                ":*";
        List<Object> scanResult = RedisUtil.scan(redisTemplate, scanKey);
        if (scanResult.size() > 0) {
            for (Object keyObj : scanResult) {
@@ -174,10 +217,10 @@
    }
    private String buildKey(InviteSessionType type, String deviceId, String channelId, String stream) {
        String key = type + "_" +  deviceId + "_" + channelId;
        String key = type + ":" +  deviceId + ":" + channelId;
        // 如果ssrc未null那么可以实现一个通道只能一次操作,ssrc不为null则可以支持一个通道多次invite
        if (stream != null) {
            key += ("_" + stream);
            key += (":" + stream);
        }
        return key;
    }
@@ -191,7 +234,7 @@
    @Override
    public int getStreamInfoCount(String mediaServerId) {
        int count = 0;
        String key = VideoManagerConstants.INVITE_PREFIX + "_*_*_*_*";
        String key = VideoManagerConstants.INVITE_PREFIX + ":*:*:*:*:*";
        List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
        if (scanResult.size() == 0) {
            return 0;
@@ -222,11 +265,42 @@
    private String buildSubStreamKey(InviteSessionType type, String deviceId, String channelId, String stream) {
        String key = type + "_" + "_" +  deviceId + "_" + channelId;
        String key = type + ":" + ":" +  deviceId + ":" + channelId;
        // 如果ssrc为null那么可以实现一个通道只能一次操作,ssrc不为null则可以支持一个通道多次invite
        if (stream != null) {
            key += ("_" + stream);
            key += (":" + stream);
        }
        return key;
    }
    @Override
    public InviteInfo getInviteInfoBySSRC(String ssrc) {
        String key = VideoManagerConstants.INVITE_PREFIX + ":*:*:*:*:" + ssrc;
        List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
        if (scanResult.size() != 1) {
            return null;
        }
        return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
    }
    @Override
    public InviteInfo updateInviteInfoForSSRC(InviteInfo inviteInfo, String ssrc) {
        InviteInfo inviteInfoInDb = getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
        if (inviteInfoInDb == null) {
            return null;
        }
        removeInviteInfo(inviteInfoInDb);
        String key = VideoManagerConstants.INVITE_PREFIX +
                ":" + inviteInfo.getType() +
                ":" + inviteInfo.getDeviceId() +
                ":" + inviteInfo.getChannelId() +
                ":" + inviteInfo.getStream() +
                ":" + ssrc;
        if (inviteInfoInDb.getSsrcInfo() != null) {
            inviteInfoInDb.getSsrcInfo().setSsrc(ssrc);
        }
        redisTemplate.opsForValue().set(key, inviteInfoInDb);
        return inviteInfoInDb;
    }
}