648540858
2023-06-02 8d6de7242957737e571f44503f686a8aa39e9b61
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package com.genersoft.iot.vmp.gb28181.session;
 
import com.genersoft.iot.vmp.conf.SipConfig;
import com.genersoft.iot.vmp.conf.UserSetting;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
 
/**
 * ssrc使用
 */
@Component
public class SSRCFactory {
 
    /**
     * 播流最大并发个数
     */
    private static final Integer MAX_STREAM_COUNT = 10000;
 
    /**
     * 播流最大并发个数
     */
    private static final String SSRC_INFO_KEY = "VMP_SSRC_INFO_";
 
    @Autowired
    private StringRedisTemplate redisTemplate;
 
    @Autowired
    private SipConfig sipConfig;
 
    @Autowired
    private UserSetting userSetting;
 
 
    public void initMediaServerSSRC(String mediaServerId, Set<String> usedSet) {
        String ssrcPrefix = sipConfig.getDomain().substring(3, 8);
        String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
        List<String> ssrcList = new ArrayList<>();
        for (int i = 1; i < MAX_STREAM_COUNT; i++) {
            String ssrc = String.format("%s%04d", ssrcPrefix, i);
 
            if (null == usedSet || !usedSet.contains(ssrc)) {
                ssrcList.add(ssrc);
 
            }
        }
        if (redisTemplate.opsForSet().size(redisKey) != null) {
            redisTemplate.delete(redisKey);
        }
        redisTemplate.opsForSet().add(redisKey, ssrcList.toArray(new String[0]));
    }
 
 
    /**
     * 获取视频预览的SSRC值,第一位固定为0
     *
     * @return ssrc
     */
    public String getPlaySsrc(String mediaServerId) {
        return "0" + getSN(mediaServerId);
    }
 
    /**
     * 获取录像回放的SSRC值,第一位固定为1
     */
    public String getPlayBackSsrc(String mediaServerId) {
        return "1" + getSN(mediaServerId);
    }
 
    /**
     * 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽
     *
     * @param ssrc 需要重置的ssrc
     */
    public void releaseSsrc(String mediaServerId, String ssrc) {
        if (ssrc == null) {
            return;
        }
        String sn = ssrc.substring(1);
        String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
        redisTemplate.opsForSet().add(redisKey, sn);
    }
 
    /**
     * 获取后四位数SN,随机数
     */
    private String getSN(String mediaServerId) {
        String sn = null;
        String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
        Long size = redisTemplate.opsForSet().size(redisKey);
        if (size == null || size == 0) {
            throw new RuntimeException("ssrc已经用完");
        } else {
            // 在集合中移除并返回一个随机成员。
            sn = (String) redisTemplate.opsForSet().pop(redisKey);
            redisTemplate.opsForSet().remove(redisKey, sn);
        }
        return sn;
    }
 
    /**
     * 重置一个流媒体服务的所有ssrc
     *
     * @param mediaServerId 流媒体服务ID
     */
    public void reset(String mediaServerId) {
        this.initMediaServerSSRC(mediaServerId, null);
    }
 
    /**
     * 是否已经存在了某个MediaServer的SSRC信息
     *
     * @param mediaServerId 流媒体服务ID
     */
    public boolean hasMediaServerSSRC(String mediaServerId) {
        String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
        return redisTemplate.opsForSet().members(redisKey) != null;
    }
 
    /**
     * 查询ssrc是否可用
     *
     * @param mediaServerId
     * @param ssrc
     * @return
     */
    public boolean checkSsrc(String mediaServerId, String ssrc) {
        String sn = ssrc.substring(1);
        String redisKey = SSRC_INFO_KEY + userSetting.getServerId() + "_" + mediaServerId;
        return redisTemplate.opsForSet().isMember(redisKey, sn) != null;
    }
}