songww
5 years ago
16 changed files with 406 additions and 73 deletions
@ -0,0 +1,91 @@ |
|||
package com.genersoft.iot.vmp.gb28181.utils; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Random; |
|||
|
|||
import com.genersoft.iot.vmp.conf.SipConfig; |
|||
import com.genersoft.iot.vmp.utils.SpringBeanFactory; |
|||
|
|||
/** |
|||
* @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数 |
|||
* @author: songww |
|||
* @date: 2020年5月10日 上午11:57:57 |
|||
*/ |
|||
public class SsrcUtil { |
|||
|
|||
private static String ssrcPrefix; |
|||
|
|||
private static List<String> isUsed; |
|||
|
|||
private static List<String> notUsed; |
|||
|
|||
private static void init() { |
|||
SipConfig sipConfig = (SipConfig) SpringBeanFactory.getBean("sipConfig"); |
|||
ssrcPrefix = sipConfig.getSipDomain().substring(4, 9); |
|||
isUsed = new ArrayList<String>(); |
|||
notUsed = new ArrayList<String>(); |
|||
for (int i = 1; i < 10000; i++) { |
|||
if (i < 10) { |
|||
notUsed.add("000" + i); |
|||
} else if (i < 100) { |
|||
notUsed.add("00" + i); |
|||
} else if (i < 1000) { |
|||
notUsed.add("0" + i); |
|||
} else { |
|||
notUsed.add(String.valueOf(i)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取视频预览的SSRC值,第一位固定为0 |
|||
* |
|||
*/ |
|||
public static String getPlaySsrc() { |
|||
return "0" + getSsrcPrefix() + getSN(); |
|||
} |
|||
|
|||
/** |
|||
* 获取录像回放的SSRC值,第一位固定为1 |
|||
* |
|||
*/ |
|||
public static String getPlayBackSsrc() { |
|||
return "1" + getSsrcPrefix() + getSN(); |
|||
} |
|||
|
|||
/** |
|||
* 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽 |
|||
* |
|||
*/ |
|||
public static void releaseSsrc(String ssrc) { |
|||
String sn = ssrc.substring(6); |
|||
isUsed.remove(sn); |
|||
notUsed.add(sn); |
|||
} |
|||
|
|||
/** |
|||
* 获取后四位数SN,随机数 |
|||
* |
|||
*/ |
|||
private static String getSN() { |
|||
String sn = null; |
|||
if (notUsed.size() == 0) { |
|||
throw new RuntimeException("ssrc已经用完"); |
|||
} else if (notUsed.size() == 1) { |
|||
sn = notUsed.get(0); |
|||
} else { |
|||
sn = notUsed.get(new Random().nextInt(notUsed.size() - 1)); |
|||
} |
|||
notUsed.remove(0); |
|||
isUsed.add(sn); |
|||
return sn; |
|||
} |
|||
|
|||
private static String getSsrcPrefix() { |
|||
if (ssrcPrefix == null) { |
|||
init(); |
|||
} |
|||
return ssrcPrefix; |
|||
} |
|||
} |
@ -0,0 +1,47 @@ |
|||
package com.genersoft.iot.vmp.utils; |
|||
|
|||
import org.springframework.beans.BeansException; |
|||
import org.springframework.context.ApplicationContext; |
|||
import org.springframework.context.ApplicationContextAware; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* @Description:spring bean获取工厂,获取spring中的已初始化的bean |
|||
* @author: songww |
|||
* @date: 2019年6月25日 下午4:51:52 |
|||
* |
|||
*/ |
|||
@Component |
|||
public class SpringBeanFactory implements ApplicationContextAware { |
|||
|
|||
// Spring应用上下文环境
|
|||
private static ApplicationContext applicationContext; |
|||
|
|||
/** |
|||
* 实现ApplicationContextAware接口的回调方法,设置上下文环境 |
|||
*/ |
|||
@Override |
|||
public void setApplicationContext(ApplicationContext applicationContext) |
|||
throws BeansException { |
|||
SpringBeanFactory.applicationContext = applicationContext; |
|||
} |
|||
|
|||
public static ApplicationContext getApplicationContext() { |
|||
return applicationContext; |
|||
} |
|||
|
|||
/** |
|||
* 获取对象 这里重写了bean方法,起主要作用 |
|||
*/ |
|||
public static Object getBean(String beanId) throws BeansException { |
|||
return applicationContext.getBean(beanId); |
|||
} |
|||
|
|||
/** |
|||
* 获取当前环境 |
|||
*/ |
|||
public static String getActiveProfile() { |
|||
return applicationContext.getEnvironment().getActiveProfiles()[0]; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,47 @@ |
|||
package com.genersoft.iot.vmp.vmanager.playback; |
|||
|
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.ResponseEntity; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.PathVariable; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import com.genersoft.iot.vmp.gb28181.bean.Device; |
|||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander; |
|||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager; |
|||
|
|||
@RestController |
|||
@RequestMapping("/api") |
|||
public class PlaybackController { |
|||
|
|||
private final static Logger logger = LoggerFactory.getLogger(PlaybackController.class); |
|||
|
|||
@Autowired |
|||
private SIPCommander cmder; |
|||
|
|||
@Autowired |
|||
private IVideoManagerStorager storager; |
|||
|
|||
@GetMapping("/playback/{deviceId}/{channelId}") |
|||
public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId, String startTime, String endTime){ |
|||
|
|||
Device device = storager.queryVideoDevice(deviceId); |
|||
String ssrc = cmder.playStreamCmd(device, channelId); |
|||
|
|||
if (logger.isDebugEnabled()) { |
|||
logger.debug(String.format("设备预览 API调用,deviceId:%s ,channelId:%s",deviceId, channelId)); |
|||
logger.debug("设备预览 API调用,ssrc:"+ssrc+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(ssrc))); |
|||
} |
|||
|
|||
if(ssrc!=null) { |
|||
return new ResponseEntity<String>(ssrc,HttpStatus.OK); |
|||
} else { |
|||
logger.warn("设备预览API调用失败!"); |
|||
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR); |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue