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