Commit 9dad6797 authored by 李成龙's avatar 李成龙

V1.2版本,增加数据权限

parents
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yeejoin.amos</groupId>
<artifactId>HikVideo</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> </dependency> -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-all</artifactId>
<version>1.7.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jackson-all-1.7.6.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.6.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/axis2-1.6.2.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hikvision</groupId>
<artifactId>ivms6-swdf-core</artifactId>
<version>1.1.2-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/ivms6-swdf-core-1.1.2-20141027.031632-20.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hikvision</groupId>
<artifactId>hik-cache</artifactId>
<version>1.1.5</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/hik-cache-1.1.5.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hikvision</groupId>
<artifactId>hik-scheduler</artifactId>
<version>1.1.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/hik-scheduler-1.1.1-20140530.043726-1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.hikvision</groupId>
<artifactId>hik-util</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/hik-util-1.0.0.jar</systemPath>
</dependency>
<!-- <dependency> <groupId>com.hikvision</groupId> <artifactId>platform-message-util</artifactId>
<version>4.2-SNAPSHOT</version> <scope>system</scope> <systemPath>${project.basedir}/lib/platform-message-util-4.2-SNAPSHOT.jar</systemPath>
</dependency> -->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/axis2-transport-http-1.6.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.6.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/axis2-transport-local-1.6.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.neethi</groupId>
<artifactId>neethi</artifactId>
<version>3.0.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/neethi-3.0.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-api</artifactId>
<version>1.2.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/axiom-api-1.2.13.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.axiom</groupId>
<artifactId>axiom-impl</artifactId>
<version>1.2.13</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/axiom-impl-1.2.13.jar</systemPath>
</dependency>
<!-- <dependency> <groupId>com.ibm.wsdl</groupId> <artifactId>wsdl4j</artifactId>
<version>1.6.2</version> <scope>system</scope> <systemPath>${project.basedir}/lib/wsdl4j-1.6.2.jar</systemPath>
</dependency> -->
<!-- <dependency> <groupId>com.ctc.wstx</groupId> <artifactId>wstx-asl</artifactId>
<version>3.2.9</version> <scope>system</scope> <systemPath>${project.basedir}/lib/wstx-asl-3.2.9.jar</systemPath>
</dependency> -->
<dependency>
<groupId>org.apache.woden</groupId>
<artifactId>woden-api</artifactId>
<version>1.0M9</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/woden-api-1.0M9.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.woden</groupId>
<artifactId>woden-impl-commons</artifactId>
<version>1.0M9</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/woden-impl-commons-1.0M9.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.woden</groupId>
<artifactId>woden-impl-dom</artifactId>
<version>1.0M9</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/woden-impl-dom-1.0M9.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.ws.commons.schema</groupId>
<artifactId>XmlSchema</artifactId>
<version>1.4.7</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
<!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>4.0.3</version>
</dependency><!-- apache httpclient组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>lib</directory>
<targetPath>lib/</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.5.RELEASE</version>
<configuration>
<!-- 指定启动类 -->
<mainClass>com.yeejoin.amos.AppStart</mainClass>
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.yeejoin.amos;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import com.yeejoin.amos.rtsp.HtmlRtspPlayerWebSockerServer;
import com.yeejoin.amos.rtsp.WebSocketHandshakeInterceptor;
@EnableScheduling
@EnableWebSocket
@SpringBootApplication
//@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@ImportResource(locations = {"classpath:config/applicationXml/application-*.xml"})
@MapperScan(basePackages ={"com.yeejoin.amos.mapper"})
public class AppStart
implements WebSocketConfigurer
{
public static void main(String[] args) {
new SpringApplication(AppStart.class).run(args);
}
@Bean
public HtmlRtspPlayerWebSockerServer htmlRtspPlayerWebSockerServer() {
return new HtmlRtspPlayerWebSockerServer();
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(htmlRtspPlayerWebSockerServer(), "/player").setAllowedOrigins("*").addInterceptors(new WebSocketHandshakeInterceptor());
}
}
package com.yeejoin.amos;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
/**
* <pre>
* 跨域处理
* </pre>
*
* @author SmartRay
* @version CrossDomainFilter.java v0.1
* @time 2016-9-7 9:48:10
*/
@Component(value = "crossDomainFilter")
@EnableScheduling
@Order(0)
public class CrossDomainFilter implements Filter
{
public void destroy()
{
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException
{
HttpServletResponse response = (HttpServletResponse) res;
// 允许所有域进行访问
response.setHeader("Access-Control-Allow-Origin", "*");
// 允许的方法
response.setHeader("Access-Control-Allow-Methods","GET,POST,DELETE,OPTIONS,PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, X-Access-Token, X-Api-Key, Content-Type, Accept, Cache-Control,product,token,appKey");
chain.doFilter(req, res);
}
public void init(FilterConfig arg0) throws ServletException
{
}
}
package com.yeejoin.amos.controller;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.entity.MonitorParam;
import com.yeejoin.amos.entity.PageModel;
import com.yeejoin.amos.entity.RtspAddressBean;
import com.yeejoin.amos.entity.Video;
import com.yeejoin.amos.response.CommonResponse;
import com.yeejoin.amos.server.ParamsConfig;
import com.yeejoin.amos.service.PageService;
import com.yeejoin.amos.service.VideoService;
import com.yeejoin.amos.util.CommonResponseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
@RestController
@RequestMapping(value = "/rtsp")
public class AddressController {
private final Logger log = LoggerFactory.getLogger(AddressController.class);
@Autowired
VideoService videoService;
@Autowired
private PageService pageService;
@PostMapping(value = "/address", produces = "application/json;charset=UTF-8")
public CommonResponse getRtspAddress(@RequestBody List<RtspAddressBean> list) {
try {
// URL
List<String> listUrls = new ArrayList<>();
for (RtspAddressBean bean : list) {
// rtsp://admin:zjt123456@172.16.18.21:554/h264/ch1/main/av_stream
String url = "rtsp://" + bean.getUserName() + ":" + bean.getPwd() + "@" + bean.getIp() + ":"
+ bean.getPort() + "/" + bean.getVideoFormat() + "/" + bean.getChannel() + "/main/av_stream";
listUrls.add(url);
}
return CommonResponseUtil.success(listUrls);
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取地址失败");
}
}
/**
* 分页查询摄像头列表
* @param param
* @return
*/
@PostMapping(value = "/listVideoByPage", produces = "application/json;charset=UTF-8")
public CommonResponse getVideos(@RequestBody(required = true) MonitorParam param) {
try {
PageModel<Video> findRoadPageList = videoService.findPageList(param);
return CommonResponseUtil.success(findRoadPageList);
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取失败");
}
}
/**
* 获取所有节点列表(树结构)
* @return
*/
@GetMapping(value = "/list", produces = "application/json;charset=UTF-8")
public CommonResponse getVideosList(@RequestParam("floor3d") String floor3d) {
try {
List<Video> findAll = videoService.findAll(floor3d);
return CommonResponseUtil.success(findAll);
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取失败");
}
}
/**
* 获取所有节点列表(树结构)
* @return
*/
@GetMapping(value = "/monitorVideoTree", produces = "application/json;charset=UTF-8")
public CommonResponse getVideosTree() {
try {
List<Map<String, Object>> resultList = videoService.videoTree();
return CommonResponseUtil.success(resultList);
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取失败");
}
}
/**
* 分页查询摄像头列表
* @param param
* @return
*/
@PostMapping(value = "/monitorVideoByPage", produces = "application/json;charset=UTF-8")
public CommonResponse getPageMonitorVideo(@RequestBody(required = true) MonitorParam param){
List list = pageService.doService(param);
return CommonResponseUtil.success(list);
}
}
package com.yeejoin.amos.controller;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.yeejoin.amos.entity.H5Response;
import com.yeejoin.amos.entity.Video;
import com.yeejoin.amos.response.CommonResponse;
import com.yeejoin.amos.server.ParamsConfig;
import com.yeejoin.amos.server.RemoteServer;
import com.yeejoin.amos.service.VideoService;
import com.yeejoin.amos.util.CommonResponseUtil;
@RestController
@RequestMapping(value = "/video")
public class VideoController {
private final Logger log = LoggerFactory.getLogger(VideoController.class);
@Autowired
VideoService videoService;
@Resource(name = "paramsConfig")
private ParamsConfig paramsConfig;
@Autowired
RemoteServer server;
/**
* 添加设备
* @param list
* @return
*/
@PostMapping(value = "/addDevice", produces = "application/json;charset=UTF-8")
public CommonResponse getAddDevice(@RequestBody Video bean) {
try {
H5Response addDevice = videoService.addDevice(bean);
if(addDevice.isbStatus()) {
log.info("add device success!");
return CommonResponseUtil.success(bean);
}else {
log.error("add device fail!");
return CommonResponseUtil.failure("add device fail!");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("添加设备失败");
}
}
/**
* 获取设备信息
* @return
*/
@GetMapping(value = "/getDeviceMsg", produces = "application/json;charset=UTF-8")
public CommonResponse getDeviceMsg(@RequestParam(value ="token") String token) {
try {
Video device = videoService.getDevice(token);
if(null!=device) {
return CommonResponseUtil.success(device);
}else {
return CommonResponseUtil.failure("该设备不存在");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取设备信息失败");
}
}
/**
* 删除设备信息
* @return
*/
@DeleteMapping(value = "/deleteDeviceMsg", produces = "application/json;charset=UTF-8")
public CommonResponse deleteDevice(@RequestParam(value ="token") String token) {
try {
H5Response deleteDevice = videoService.deleteDevice(token);
if(deleteDevice.isbStatus()) {
log.info("delete device success!");
return CommonResponseUtil.success(deleteDevice);
}else {
log.error("delete device fail!");
return CommonResponseUtil.failure("设备不存在");
}
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("获取设备信息失败");
}
}
/**
* 更新设备楼层和三维信息
* @param bean
* @return
*/
@PutMapping(value = "/updateDevice", produces = "application/json;charset=UTF-8")
public CommonResponse updateDevice(@RequestBody Video bean) {
try {
if(null==bean.getId()) {
return CommonResponseUtil.failure("设备token不可为空");
}
videoService.updateDevice(bean);
return CommonResponseUtil.success();
} catch (Exception e) {
log.error(e.getMessage(), e);
return CommonResponseUtil.failure("更新设备失败");
}
}
}
package com.yeejoin.amos.dao;
import com.yeejoin.amos.entity.Video;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface IVideoDao extends JpaRepository<Video, Long> {
}
package com.yeejoin.amos.entity;
import java.io.Serializable;
/**
* 摄像头配置参数
* @author DELL
*
*/
public class App implements Serializable{
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
//摄像头应用名称
private String appName;
//rtsp地址
private String input;
//应用地址
private String output;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
@Override
public String toString() {
return "App [appName=" + appName + ", input=" + input + ", output=" + output + "]";
}
}
package com.yeejoin.amos.entity;
/**
* 用于请求和返回数据使用
*
*/
public class BaseParam {
Long id;
/**
* 页码,默认值1
*/
protected Integer current = 1;
/**
* 每页记录数
*/
private Integer pageSize;
/**
* 设备名称
*/
private String name;
/**
* 是否叶子节点,默认true
*/
private Boolean isLeaf = true;
/**
* 从第几条记录开始查
* @return
*/
public Integer getStartPage(){
if(current!=null && current==0) {
return 0;
}
return (current - 1) * pageSize;
}
public Integer getCurrent() {
return current;
}
public void setCurrent(Integer current) {
this.current = current;
}
public void setPageNum(Integer current) {
this.current = current;
}
public Integer getPageSize() {
if(current!=null && current==0) {
return Integer.MAX_VALUE;
}
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getIsLeaf() {
return isLeaf;
}
public void setIsLeaf(Boolean isLeaf) {
this.isLeaf = isLeaf;
}
}
package com.yeejoin.amos.entity;
public class DeviceBean {
private String strName;
private String strUrl;
private String strSrcIpAddress;
private String strPasswd;
private String strUser;
private String strToken;
public String getStrName() {
return strName;
}
public void setStrName(String strName) {
this.strName = strName;
}
public String getStrUrl() {
return strUrl;
}
public void setStrUrl(String strUrl) {
this.strUrl = strUrl;
}
public String getStrSrcIpAddress() {
return strSrcIpAddress;
}
public void setStrSrcIpAddress(String strSrcIpAddress) {
this.strSrcIpAddress = strSrcIpAddress;
}
public String getStrPasswd() {
return strPasswd;
}
public void setStrPasswd(String strPasswd) {
this.strPasswd = strPasswd;
}
public String getStrUser() {
return strUser;
}
public void setStrUser(String strUser) {
this.strUser = strUser;
}
public String getStrToken() {
return strToken;
}
public void setStrToken(String strToken) {
this.strToken = strToken;
}
}
package com.yeejoin.amos.entity;
public class H5Response {
private boolean bStatus;
private String strCode;
public boolean isbStatus() {
return bStatus;
}
public void setbStatus(boolean bStatus) {
this.bStatus = bStatus;
}
public String getStrCode() {
return strCode;
}
public void setStrCode(String strCode) {
this.strCode = strCode;
}
}
package com.yeejoin.amos.entity;
/**
* @Author: xinglei
* @Description: TODO()
* @Date: 2019/11/27 17:31
*/
public class MonitorParam extends BaseParam {
/**
* 父ID
*/
private Long parentId;
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
}
package com.yeejoin.amos.entity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.domain.Page;
/**
* 分页返回模板对象
*
* @param <T>
*/
public class PageModel<T> {
/**
* 总记录数
*/
private Integer total;
/**
* 当前页数
*/
private Integer currPage;
/**
* 总页数
*/
private Integer totalPage;
/**
* 每页记录数
*/
private Integer pageSize;
/**
* 数据
*/
private List<T> dataList;
public PageModel(){
super();
}
public PageModel(Integer total, Integer currPage, Integer pageSize, List<T> dataList) {
super();
this.total = total;
this.currPage = currPage;
this.pageSize = pageSize;
this.dataList = dataList;
totalPage = (total - 1)/pageSize + 1;
}
public PageModel(Integer currPage, Integer pageSize, List<T> dataAll) {
super();
this.total = dataAll.size();
this.currPage = currPage;
this.pageSize = pageSize;
List<T> subList = null;
Integer start = pageSize*(currPage-1);
if(start >= dataAll.size()) {
subList = new ArrayList<>();
}else if(start+pageSize >= dataAll.size()) {
subList = dataAll.subList(start,dataAll.size());
}else {
subList = dataAll.subList(start, start+pageSize);
}
this.dataList = subList;
totalPage = (total - 1)/pageSize + 1;
}
/**
* jpa查询得到的分页转换为PageModel
* @param page
*/
public PageModel(Page<T> page){
long t = page.getTotalElements();
this.total = ((Long)t).intValue();
this.currPage = page.getNumber()+1;
this.pageSize = page.getSize();
this.dataList = page.getContent();
this.totalPage = page.getTotalPages();
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getCurrPage() {
return currPage;
}
public void setCurrPage(Integer currPage) {
this.currPage = currPage;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public List<T> getDataList() {
return dataList;
}
public void setDataList(List<T> dataList) {
this.dataList = dataList;
}
/**
* 本方法用于方便前端处理分页参数
* @return
*/
public Map<String, Object> getParameterMap(){
Map<String, Object> map = new HashMap<String, Object>();
map.put("current", currPage);
map.put("total", total);
map.put("pageSize", pageSize);
return map;
}
}
package com.yeejoin.amos.entity;
public class RtspAddressBean {
private String userName;
private String pwd;
private String ip;
private String port;
//编码格式
private String videoFormat;
//通道
private String channel;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getVideoFormat() {
return videoFormat;
}
public void setVideoFormat(String videoFormat) {
this.videoFormat = videoFormat;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
@Override
public String toString() {
return "RtspAddressBean [userName=" + userName + ", pwd=" + pwd + ", ip=" + ip + ", port=" + port
+ ", videoFormat=" + videoFormat + ", channel=" + channel + "]";
}
}
package com.yeejoin.amos.entity;
import java.util.Map;
public class RtspSource {
private boolean bStatus;
Map<String, Object>[] src;
public Map<String, Object>[] getSrc() {
return src;
}
public void setSrc(Map<String, Object>[] src) {
this.src = src;
}
public boolean getbStatus() {
return bStatus;
}
public void setbStatus(boolean bStatus) {
this.bStatus = bStatus;
}
}
package com.yeejoin.amos.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "b_monitor_video")
@org.hibernate.annotations.Table(appliesTo = "b_monitor_video", comment = "摄像头信息表")
public class Video implements Serializable {
private static final long serialVersionUID = 3499756800920010671L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = true)
private Long id;
@Column(name = "name", columnDefinition = "varchar(255) COMMENT '设备名称'")
private String name;
@Column(name = "parent_id", columnDefinition = "varchar(255) COMMENT '父ID'")
private Long parentId;
@Column(name = "is_leaf", columnDefinition = "bit COMMENT '是否叶子节点'")
private Integer isLeaf;
@Column(name = "ip", columnDefinition = "varchar(255) COMMENT '设备IP'")
private String ip;
@Column(name = "rtsp_address", columnDefinition = "varchar(255) COMMENT '视频rtsp地址'")
private String rtspAddress;
@Column(name = "url", columnDefinition = "varchar(255) COMMENT '视频访问url'")
private String url;
@Column(name = "text", columnDefinition = "varchar(255) COMMENT '备注'")
private String text;
@Column(name = "carmera_type", columnDefinition = "varchar(255) COMMENT '设备类型'")
private String carmeraType;
@Column(name = "position3d", columnDefinition = "varchar(255) COMMENT '三维坐标信息'")
private String position3d;
@Column(name = "floor3d", columnDefinition = "varchar(255) COMMENT '楼层'")
private String floor3d;
@Column(name = "is_indoor", columnDefinition = "bit COMMENT '室内室外:1 为室内,0为室外'")
private Boolean isIndoor;
@Column(name = "status", columnDefinition = "int(10) COMMENT '监控视频状态:【1:正常;0:异常】'")
private int status;
@Column(name = "token", columnDefinition = "varchar(255) COMMENT '摄像头唯一token'")
private String token;
@Column(name = "user", columnDefinition = "varchar(255) COMMENT '用户名'")
private String user;
@Column(name = "password", columnDefinition = "varchar(255) COMMENT '密码'")
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Integer getIsLeaf() {
return isLeaf;
}
public void setIsLeaf(Integer isLeaf) {
this.isLeaf = isLeaf;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getRtspAddress() {
return rtspAddress;
}
public void setRtspAddress(String rtspAddress) {
this.rtspAddress = rtspAddress;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getCarmeraType() {
return carmeraType;
}
public void setCarmeraType(String carmeraType) {
this.carmeraType = carmeraType;
}
public String getPosition3d() {
return position3d;
}
public void setPosition3d(String position3d) {
this.position3d = position3d;
}
public String getFloor3d() {
return floor3d;
}
public void setFloor3d(String floor3d) {
this.floor3d = floor3d;
}
public Boolean getIsIndoor() {
return isIndoor;
}
public void setIsIndoor(Boolean isIndoor) {
this.isIndoor = isIndoor;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.yeejoin.amos.ffmpeg;
import java.util.Collection;
import java.util.Map;
import static com.yeejoin.amos.ffmpeg.utils.PropertiesUtil.load;
import com.yeejoin.amos.ffmpeg.commandbuidler.CommandAssembly;
import com.yeejoin.amos.ffmpeg.commandbuidler.CommandBuidler;
import com.yeejoin.amos.ffmpeg.config.ProgramConfig;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.data.TaskDao;
import com.yeejoin.amos.ffmpeg.hander.TaskHandler;
/**
* FFmpeg命令操作管理器,可执行FFmpeg命令/停止/查询任务信息
*
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public interface CommandManager {
public static final ProgramConfig config=load("/loadFFmpeg.properties", ProgramConfig.class);
/**
* 注入自己实现的持久层
*
* @param taskDao
*/
public void setTaskDao(TaskDao taskDao);
/**
* 注入ffmpeg命令处理器
*
* @param taskHandler
*/
public void setTaskHandler(TaskHandler taskHandler);
/**
* 注入ffmpeg命令组装器
*
* @param commandAssembly
*/
public void setCommandAssembly(CommandAssembly commandAssembly);
/**
* 通过命令发布任务(默认命令前不加FFmpeg路径)
*
* @param id - 任务标识
* @param command - FFmpeg命令
* @return
*/
public String start(String id, String command);
/**
* 通过命令发布任务
* @param id - 任务标识
* @param commond - FFmpeg命令
* @param hasPath - 命令中是否包含FFmpeg执行文件的绝对路径
* @return
*/
public String start(String id,String commond,boolean hasPath);
/**
* 通过流式命令构建器发布任务
* @param commandBuidler
* @return
*/
public String start(String id,CommandBuidler commandBuidler);
/**
* 通过组装命令发布任务
*
* @param assembly
* -组装命令(详细请参照readme文档说明)
* @return
*/
public String start(Map<String,String> assembly);
/**
* 停止任务
*
* @param id
* @return
*/
public boolean stop(String id);
/**
* 停止全部任务
*
* @return
*/
public int stopAll();
/**
* 通过id查询任务信息
*
* @param id
*/
public CommandTasker query(String id);
/**
* 查询全部任务信息
*
*/
public Collection<CommandTasker> queryAll();
/**
* 销毁一些后台资源和保活线程
*/
public void destory();
}
package com.yeejoin.amos.ffmpeg;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import com.yeejoin.amos.ffmpeg.commandbuidler.CommandAssembly;
import com.yeejoin.amos.ffmpeg.commandbuidler.CommandAssemblyImpl;
import com.yeejoin.amos.ffmpeg.commandbuidler.CommandBuidler;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.data.TaskDao;
import com.yeejoin.amos.ffmpeg.data.TaskDaoImpl;
import com.yeejoin.amos.ffmpeg.hander.DefaultOutHandlerMethod;
import com.yeejoin.amos.ffmpeg.hander.KeepAliveHandler;
import com.yeejoin.amos.ffmpeg.hander.OutHandlerMethod;
import com.yeejoin.amos.ffmpeg.hander.TaskHandler;
import com.yeejoin.amos.ffmpeg.hander.TaskHandlerImpl;
/**
* FFmpeg命令操作管理器
*
* @author eguid
* @since jdk1.7
* @version 2017年10月13日
*/
public class CommandManagerImpl implements CommandManager {
/**
* 任务持久化器
*/
private TaskDao taskDao = null;
/**
* 任务执行处理器
*/
private TaskHandler taskHandler = null;
/**
* 命令组装器
*/
private CommandAssembly commandAssembly = null;
/**
* 任务消息处理器
*/
private OutHandlerMethod ohm = null;
/**
* 保活处理器
*/
private KeepAliveHandler keepAliveHandler=null;
/**
* 全部默认初始化,自动查找配置文件
*/
public CommandManagerImpl() {
this(null);
}
/**
* 指定任务池大小的初始化,其他使用默认
* @param size
*/
public CommandManagerImpl(Integer size) {
init(size);
}
/**
* 初始化
* @param taskDao
* @param taskHandler
* @param commandAssembly
* @param ohm
* @param size
*/
public CommandManagerImpl(TaskDao taskDao, TaskHandler taskHandler, CommandAssembly commandAssembly, OutHandlerMethod ohm,Integer size) {
super();
this.taskDao = taskDao;
this.taskHandler = taskHandler;
this.commandAssembly = commandAssembly;
this.ohm = ohm;
init(size);
}
/**
* 初始化,如果几个处理器未注入,则使用默认处理器
*
* @param size
*/
public void init(Integer size) {
if (config == null) {
System.err.println("配置文件加载失败!配置文件不存在或配置错误");
return;
}
boolean iskeepalive=false;
if (size == null) {
size = config.getSize() == null ? 10 : config.getSize();
iskeepalive=config.isKeepalive();
}
if (this.ohm == null) {
this.ohm = new DefaultOutHandlerMethod();
}
if (this.taskDao == null) {
this.taskDao = new TaskDaoImpl(size);
//初始化保活线程
if(iskeepalive) {
keepAliveHandler = new KeepAliveHandler(taskDao);
keepAliveHandler.start();
}
}
if (this.taskHandler == null) {
this.taskHandler = new TaskHandlerImpl(this.ohm);
}
if (this.commandAssembly == null) {
this.commandAssembly = new CommandAssemblyImpl();
}
}
public void setTaskDao(TaskDao taskDao) {
this.taskDao = taskDao;
}
public void setTaskHandler(TaskHandler taskHandler) {
this.taskHandler = taskHandler;
}
public void setCommandAssembly(CommandAssembly commandAssembly) {
this.commandAssembly = commandAssembly;
}
public void setOhm(OutHandlerMethod ohm) {
this.ohm = ohm;
}
/**
* 是否已经初始化
*
* @param 如果未初始化时是否初始化
* @return
*/
public boolean isInit(boolean b) {
boolean ret = this.ohm == null || this.taskDao == null || this.taskHandler == null|| this.commandAssembly == null;
if (ret && b) {
init(null);
}
return ret;
}
@Override
public String start(String id, String command) {
return start(id, command, false);
}
@Override
public String start(String id, String command, boolean hasPath) {
if (isInit(true)) {
System.err.println("执行失败,未进行初始化或初始化失败!");
return null;
}
if (id != null && command != null) {
CommandTasker tasker = taskHandler.process(id, hasPath ? command : config.getPath() + command);
if (tasker != null) {
int ret = taskDao.add(tasker);
if (ret > 0) {
return tasker.getId();
} else {
// 持久化信息失败,停止处理
taskHandler.stop(tasker.getProcess(), tasker.getThread());
if (config.isDebug())
System.err.println("持久化失败,停止任务!");
}
}
}
return null;
}
@Override
public String start(Map<String, String> assembly) {
// ffmpeg环境是否配置正确
if (checkConfig()) {
System.err.println("配置未正确加载,无法执行");
return null;
}
// 参数是否符合要求
if (assembly == null || assembly.isEmpty() || !assembly.containsKey("appName")) {
System.err.println("参数不正确,无法执行");
return null;
}
String appName = (String) assembly.get("appName");
if (appName != null && "".equals(appName.trim())) {
System.err.println("appName不能为空");
return null;
}
assembly.put("ffmpegPath", config.getPath() + "ffmpeg");
//String command = commandAssembly.assembly(assembly);
String command = commandAssembly.assemblyRtsp(assembly);
if (command != null) {
return start(appName, command, true);
}
return null;
}
@Override
public String start(String id,CommandBuidler commandBuidler) {
// ffmpeg环境是否配置正确
if (checkConfig()) {
System.err.println("配置未正确加载,无法执行");
return null;
}
String command =commandBuidler.get();
if (command != null) {
return start(id, command, true);
}
return null;
}
private boolean checkConfig() {
return config == null;
}
@Override
public boolean stop(String id) {
if (id != null && taskDao.isHave(id)) {
if (config.isDebug())
System.out.println("正在停止任务:" + id);
CommandTasker tasker = taskDao.get(id);
if (taskHandler.stop(tasker.getProcess(), tasker.getThread())) {
taskDao.remove(id);
System.out.println("停止任务成功");
return true;
}
}
System.err.println("停止任务失败!id=" + id);
return false;
}
@Override
public int stopAll() {
Collection<CommandTasker> list = taskDao.getAll();
Iterator<CommandTasker> iter = list.iterator();
CommandTasker tasker = null;
int index = 0;
while (iter.hasNext()) {
tasker = iter.next();
if (taskHandler.stop(tasker.getProcess(), tasker.getThread())) {
taskDao.remove(tasker.getId());
index++;
}
}
if (config.isDebug())
System.out.println("停止了" + index + "个任务!");
return index;
}
@Override
public CommandTasker query(String id) {
return taskDao.get(id);
}
@Override
public Collection<CommandTasker> queryAll() {
return taskDao.getAll();
}
@Override
public void destory() {
if(keepAliveHandler!=null) {
//安全停止保活线程
keepAliveHandler.interrupt();
}
}
}
//package com.yeejoin.amos.ffmpeg;
//
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.io.InputStreamReader;
//import java.util.Collection;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.CommandLineRunner;
//import org.springframework.core.io.Resource;
//import org.springframework.stereotype.Component;
//
//import com.alibaba.fastjson.JSON;
//import com.yeejoin.amos.entity.App;
//import com.yeejoin.amos.ffmpeg.data.CommandTasker;
//
///**
// * 服务启动时候自动加载摄像头推流
// * @author DELL
// *
// */
//@Component
//public class StartVideoService implements CommandLineRunner{
//
// @Value(value="classpath:cameras.json")
// private Resource resource;
//
//
// @Override
// public void run(String... args) throws Exception {
// List<App> apps = JSON.parseArray(getJSON(), App.class);
// for (App app : apps) {
// sendStream(app);
// }
// System.out.println("------开始加载摄像头推流发方法-----" + apps);
// }
//
// private String getJSON() throws IOException {
// BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()));
// StringBuffer message=new StringBuffer();
// String line = null;
// while((line = br.readLine()) != null) {
// message.append(line);
// }
// String defaultString=message.toString();
// String result=defaultString.replace("\r\n", "").replaceAll(" +", "");
// return result;
// }
//
// /**
// * 推流
// * @param appName
// * @param input
// * @param output
// * @throws InterruptedException
// */
// public static void sendStream(App app) throws InterruptedException{
// CommandManager manager = new CommandManagerImpl();
// Map<String,String> map = new HashMap<String,String>();
// map.put("appName", app.getAppName());
// map.put("input", app.getInput());
// map.put("output", app.getOutput());
// // 执行任务,id就是appName,如果执行失败返回为null
// String id = manager.start(map);
// System.out.println(id);
// // 通过id查询
// CommandTasker info = manager.query(id);
// System.out.println(info);
// // 查询全部
// Collection<CommandTasker> infoList = manager.queryAll();
// System.out.println(infoList);
// Thread.sleep(30000);
// // 停止id对应的任务
// // manager.stop(id);
// }
//}
package com.yeejoin.amos.ffmpeg.callback;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
/**
* 事件回调
*
*/
public interface EventCallBack {
/**
* 命令行执行开始事件
* @param t -事件类型
* @param tasker -任务信息
*/
boolean callback(EventCallBackType t,CommandTasker tasker);
}
package com.yeejoin.amos.ffmpeg.callback;
/**
* 事件回调类型
* @author eguid
*
*/
public enum EventCallBackType {
exec,//执行命令后通知
stop,//停止命令后通知
interrupt,//进程中断后通知
heartbeat,//主进程存活心跳
}
package com.yeejoin.amos.ffmpeg.callback.worker;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import com.yeejoin.amos.ffmpeg.CommandManager;
import com.yeejoin.amos.ffmpeg.callback.EventCallBack;
import com.yeejoin.amos.ffmpeg.callback.EventCallBackType;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.data.TaskerEventMsg;
/**
*
* 事件消息独立发送线程
*
*/
public class EventMsgNetWorker extends Thread implements EventCallBack{
protected static Queue<TaskerEventMsg> queue = null;// 一个事件消息队列,发送失败的事件消息将会进入队列队尾等待下次再次发送
// 一个网络库,用于快速发送http消息
private int timeout = 300;// 默认300毫秒
public EventMsgNetWorker(int timeout) {
super();
this.timeout = timeout;
queue = new ConcurrentLinkedQueue<>();
}
@Override
public void run() {
for (;;) {
try {
while (queue.peek() != null) {
TaskerEventMsg t = queue.poll();
// 借助网络库发送该消息
String url = CommandManager.config.getCallback();
if (reqGET(url)) {
System.err.println("发送成功");
} else {
System.err.println("发送失败");
// 发送失败的事件消息将会进入队列队尾等待下次再次发送
queue.offer(t);
}
}
} catch (Exception e) {
}
}
}
/**
* 发送get请求
*/
private boolean reqGET(String url) {
URL realUrl;
// PrintWriter out = null;
try {
realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setUseCaches(false);
connection.setConnectTimeout(timeout);
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.setDoOutput(false);
connection.setDoInput(false);
connection.connect();
return true;
} catch (IOException e) {
return false;
}
}
@Override
public boolean callback(EventCallBackType ecbt, CommandTasker tasker) {
return queue.add(new TaskerEventMsg(ecbt, tasker));
}
}
package com.yeejoin.amos.ffmpeg.commandbuidler;
import java.util.Map;
/**
* 命令组装器接口
*/
public interface CommandAssembly {
/**
* 将参数转为ffmpeg命令
* @param paramMap
* @return
*/
public String assembly(Map<String, String> paramMap);
public String assembly();
public String assemblyRtsp(Map<String, String> paramMap);
}
package com.yeejoin.amos.ffmpeg.commandbuidler;
import java.util.Map;
/**
* 默认命令组装器实现
*/
public class CommandAssemblyImpl implements CommandAssembly{
/**
*
* @param map
* -要组装的map
* @param id
* -返回参数:id
* @param id
* -返回参数:组装好的命令
* @return
*/
public String assembly(Map<String, String> paramMap) {
try {
if (paramMap.containsKey("ffmpegPath")) {
String ffmpegPath = (String) paramMap.get("ffmpegPath");
// -i:输入流地址或者文件绝对地址
StringBuilder comm = new StringBuilder(ffmpegPath + " -i ");
// 是否有必输项:输入地址,输出地址,应用名,twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码)
if (paramMap.containsKey("input") && paramMap.containsKey("output") && paramMap.containsKey("appName")
&& paramMap.containsKey("twoPart")) {
String input = (String) paramMap.get("input");
String output = (String) paramMap.get("output");
String appName = (String) paramMap.get("appName");
String twoPart = (String) paramMap.get("twoPart");
String codec = (String) paramMap.get("codec");
// 默认h264解码
codec = (codec == null ? "h264" : (String) paramMap.get("codec"));
// 输入地址
comm.append(input);
// 当twoPart为0时,只推一个元码流
if ("0".equals(twoPart)) {
comm.append(" -vcodec " + codec + " -f flv -an " + output + appName);
} else {
// -f :转换格式,默认flv
if (paramMap.containsKey("fmt")) {
String fmt = (String) paramMap.get("fmt");
comm.append(" -f " + fmt);
}
// -r :帧率,默认25;-g :帧间隔
if (paramMap.containsKey("fps")) {
String fps = (String) paramMap.get("fps");
comm.append(" -r " + fps);
comm.append(" -g " + fps);
}
// -s 分辨率 默认是原分辨率
if (paramMap.containsKey("rs")) {
String rs = (String) paramMap.get("rs");
comm.append(" -s " + rs);
}
// 输出地址+发布的应用名
comm.append(" -an " + output + appName);
// 当twoPart为2时推两个流,一个自定义流,一个元码流
if ("2".equals(twoPart)) {
// 一个视频源,可以有多个输出,第二个输出为拷贝源视频输出,不改变视频的各项参数并且命名为应用名+HD
comm.append(" -vcodec copy -f flv -an ").append(output + appName + "HD");
}
}
return comm.toString();
}
}
} catch (Exception e) {
return null;
}
return null;
}
/**
*
* @param map
* -要组装的map
* @param id
* -返回参数:id
* @param id
* -返回参数:组装好的命令
* @return
*/
@Override
public String assemblyRtsp(Map<String, String> paramMap) {
try {
if (paramMap.containsKey("ffmpegPath")) {
String ffmpegPath = (String) paramMap.get("ffmpegPath");
// -i:输入流地址或者文件绝对地址
StringBuilder comm = new StringBuilder(ffmpegPath + " -i ");
// 是否有必输项:输入地址,输出地址,应用名,twoPart:0-推一个元码流;1-推一个自定义推流;2-推两个流(一个是自定义,一个是元码)
//ffmpeg -i 'rtsp://admin:zjt123456@172.16.18.21:554/h264/ch1/main/av_strea' -q 0 -f mpegts -codec:v mpeg1video -s 1366x768 http://127.0.0.1:8081/supersecret/live2
if (paramMap.containsKey("input") && paramMap.containsKey("output") && paramMap.containsKey("appName")
) {
String input = (String) paramMap.get("input");
String output = (String) paramMap.get("output");
String appName = (String) paramMap.get("appName");
comm.append(input);
comm.append(" -q 0 -f mpegts -codec:v mpeg1video -s 1366x768 ");
comm.append(output).append("/");
comm.append(appName);
return comm.toString();
}
}
} catch (Exception e) {
return null;
}
return null;
}
@Override
public String assembly() {
// TODO Auto-generated method stub
return null;
}
}
package com.yeejoin.amos.ffmpeg.commandbuidler;
/**
* 流式命令行构建器
*
*/
public interface CommandBuidler {
/**
* 创建命令行
*
* @param root
* -命令行运行根目录或FFmpeg可执行文件安装目录
* @return
*/
CommandBuidler create(String root);
/**
* 创建默认根目录或默认FFmpeg可执行文件安装目录
*
* @return
*/
CommandBuidler create();
/**
* 累加键-值命令
*
* @param key
* @param val
* @return
*/
CommandBuidler add(String key, String val);
/**
* 累加命令
*
* @param val
* @return
*/
CommandBuidler add(String val);
/**
* 生成完整命令行
*
* @return
*/
CommandBuidler build();
/**
* 获取已经构建好的命令行
* @return
*/
String get();
}
package com.yeejoin.amos.ffmpeg.commandbuidler;
/**
* 默认流式命令构建器工厂类
*
*/
public class CommandBuidlerFactory {
public static CommandBuidler createBuidler() {
return new DefaultCommandBuidler();
};
public static CommandBuidler createBuidler(String rootpath) {
return new DefaultCommandBuidler(rootpath);
};
}
package com.yeejoin.amos.ffmpeg.commandbuidler;
import com.yeejoin.amos.ffmpeg.CommandManager;
/**
* 默认流式命令行构建器(非线程安全)
*/
public class DefaultCommandBuidler implements CommandBuidler{
StringBuilder buidler=null;
String command=null;
public DefaultCommandBuidler() {
create();
}
public DefaultCommandBuidler(String rootpath) {
create(rootpath);
}
@Override
public CommandBuidler create(String rootpath) {
buidler=new StringBuilder(rootpath);
return this;
}
@Override
public CommandBuidler create() {
return create(CommandManager.config.getPath());
}
@Override
public CommandBuidler add(String key, String val) {
return add(key).add(val);
}
@Override
public CommandBuidler add(String val) {
if(buidler!=null) {
buidler.append(val);
addBlankspace();
}
return this;
}
@Override
public CommandBuidler build() {
if(buidler!=null) {
command=buidler.toString();
}
return this;
}
private void addBlankspace() {
buidler.append(" ");
}
@Override
public String get() {
if(command==null) {
build();
}
return command;
}
}
package com.yeejoin.amos.ffmpeg.config;
/**
* 程序基础配置
*
*
*/
public class ProgramConfig {
private String path;//默认命令行执行根路径
private boolean debug;//是否开启debug模式
private Integer size;//任务池大小
private String callback;//回调通知地址
private boolean keepalive;//是否开启保活
//摄像头
private String cameras;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
public String getCallback() {
return callback;
}
public void setCallback(String callback) {
this.callback = callback;
}
public boolean isKeepalive() {
return keepalive;
}
public void setKeepalive(boolean keepalive) {
this.keepalive = keepalive;
}
public String getCameras() {
return cameras;
}
public void setCameras(String cameras) {
this.cameras = cameras;
}
}
#ffmpeg执行路径,一般为ffmpeg的安装目录,该路径只能是目录,不能为具体文件路径,否则会报错
path=
#是否启用默认的ffmpeg,如果启用默认ffmpeg,上面配置的path就没有用了
defaultpathEnable=true
#存放任务的默认Map的初始化大小
size=10
#事件回调通知接口地址
callback=http://127.0.0.1/callback
#网络超时设置(毫秒)
timeout=300
#开启保活线程
keepalive=true
#是否输出debug消息
debug=true
logging.level.org.springframework.boot.autoconfigure: ERROR
\ No newline at end of file
package com.yeejoin.amos.ffmpeg.data;
import com.yeejoin.amos.ffmpeg.hander.OutHandler;
/**
* 用于存放任务id,任务主进程,任务输出线程
*
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public class CommandTasker {
private final String id;// 任务id
private final String command;//命令行
private Process process;// 命令行运行主进程
private OutHandler thread;// 命令行消息输出子线程
public CommandTasker(String id,String command) {
this.id = id;
this.command=command;
}
public CommandTasker(String id,String command, Process process, OutHandler thread) {
this.id = id;
this.command=command;
this.process = process;
this.thread = thread;
}
public String getId() {
return id;
}
public Process getProcess() {
return process;
}
public OutHandler getThread() {
return thread;
}
public String getCommand() {
return command;
}
public void setProcess(Process process) {
this.process = process;
}
public void setThread(OutHandler thread) {
this.thread = thread;
}
@Override
public String toString() {
return "CommandTasker [id=" + id + ", command=" + command + ", process=" + process + ", thread=" + thread + "]";
}
}
package com.yeejoin.amos.ffmpeg.data;
import java.util.Collection;
/**
* 任务信息持久层接口
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public interface TaskDao {
/**
* 通过id查询任务信息
* @param id - 任务ID
* @return CommandTasker -任务实体
*/
public CommandTasker get(String id);
/**
* 查询全部任务信息
* @return Collection<CommandTasker>
*/
public Collection<CommandTasker> getAll();
/**
* 增加任务信息
* @param CommandTasker -任务信息实体
* @return 增加数量:<1-增加失败,>=1-增加成功
*/
public int add(CommandTasker CommandTasker);
/**
* 删除id对应的任务信息
* @param id
* @return 数量:<1-操作失败,>=1-操作成功
*/
public int remove(String id);
/**
* 删除全部任务信息
* @return 数量:<1-操作失败,>=1-操作成功
*/
public int removeAll();
/**
* 是否存在某个ID
* @param id - 任务ID
* @return true:存在,false:不存在
*/
public boolean isHave(String id);
}
package com.yeejoin.amos.ffmpeg.data;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 任务信息持久层实现
*
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public class TaskDaoImpl implements TaskDao {
// 存放任务信息
private ConcurrentMap<String, CommandTasker> map = null;
public TaskDaoImpl(int size) {
map = new ConcurrentHashMap<>(size);
}
@Override
public CommandTasker get(String id) {
return map.get(id);
}
@Override
public Collection<CommandTasker> getAll() {
return map.values();
}
@Override
public int add(CommandTasker CommandTasker) {
String id = CommandTasker.getId();
if (id != null && !map.containsKey(id)) {
map.put(CommandTasker.getId(), CommandTasker);
if(map.get(id)!=null)
{
return 1;
}
}
return 0;
}
@Override
public int remove(String id) {
if(map.remove(id) != null){
return 1;
};
return 0;
}
@Override
public int removeAll() {
int size = map.size();
try {
map.clear();
} catch (Exception e) {
return 0;
}
return size;
}
@Override
public boolean isHave(String id) {
return map.containsKey(id);
}
}
package com.yeejoin.amos.ffmpeg.data;
import com.yeejoin.amos.ffmpeg.callback.EventCallBackType;
/**
* 命令行事件消息
* @author eguid
*
*/
public class TaskerEventMsg {
EventCallBackType ecbt;
CommandTasker tasker;
public TaskerEventMsg(EventCallBackType ecbt, CommandTasker tasker) {
super();
this.ecbt = ecbt;
this.tasker = tasker;
}
public EventCallBackType getEcbt() {
return ecbt;
}
public void setEcbt(EventCallBackType ecbt) {
this.ecbt = ecbt;
}
public CommandTasker getTasker() {
return tasker;
}
public void setTasker(CommandTasker tasker) {
this.tasker = tasker;
}
@Override
public String toString() {
return "CommandEventMsg [ecbt=" + ecbt + ", tasker=" + tasker + "]";
}
}
package com.yeejoin.amos.ffmpeg.hander;
/**
* 默认任务消息输出处理
* @author eguid
* @since jdk1.7
* @version 2017年10月13日
*/
public class DefaultOutHandlerMethod implements OutHandlerMethod{
/**
* 任务是否异常中断,如果
*/
public boolean isBroken=false;
@Override
public void parse(String id,String msg) {
//过滤消息
if (msg.indexOf("fail") != -1) {
System.err.println(id + "任务可能发生故障:" + msg);
System.err.println("失败,设置中断状态");
isBroken=true;
}else if(msg.indexOf("miss")!= -1) {
System.err.println(id + "任务可能发生丢包:" + msg);
System.err.println("失败,设置中断状态");
isBroken=true;
}else {
isBroken=false;
System.err.println(id + "消息:" + msg);
}
}
@Override
public boolean isbroken() {
return isBroken;
}
}
package com.yeejoin.amos.ffmpeg.hander;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.data.TaskDao;
import com.yeejoin.amos.ffmpeg.utils.ExecUtil;
/**
* 任务保活处理器(一个后台保活线程,用于处理异常中断的持久任务)
* @author eguid
*
*/
public class KeepAliveHandler extends Thread{
/**待处理队列*/
private static Queue<String> queue=null;
public int err_index=0;//错误计数
public volatile int stop_index=0;//安全停止线程标记
/** 任务持久化器*/
private TaskDao taskDao = null;
public KeepAliveHandler(TaskDao taskDao) {
super();
this.taskDao=taskDao;
queue=new ConcurrentLinkedQueue<>();
}
public static void add(String id ) {
if(queue!=null) {
queue.offer(id);
}
}
public boolean stop(Process process) {
if (process != null) {
process.destroy();
return true;
}
return false;
}
@Override
public void run() {
for(;stop_index==0;) {
if(queue==null) {
continue;
}
String id=null;
CommandTasker task=null;
try {
while(queue.peek() != null) {
System.err.println("准备重启任务:"+queue);
id=queue.poll();
task=taskDao.get(id);
//重启任务
ExecUtil.restart(task);
}
}catch(IOException e) {
System.err.println(id+" 任务重启失败,详情:"+task);
//重启任务失败
err_index++;
}catch(Exception e) {
}
}
}
@Override
public void interrupt() {
stop_index=1;
}
}
package com.yeejoin.amos.ffmpeg.hander;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.yeejoin.amos.ffmpeg.CommandManager;
/**
* 任务消息输出处理器
* @author eguid
* @since jdk1.7
* @version 2017年10月13日
*/
public class OutHandler extends Thread {
/**控制状态 */
private volatile boolean desstatus = true;
/**读取输出流*/
private BufferedReader br = null;
/**任务ID*/
private String id = null;
/**消息处理方法*/
private OutHandlerMethod ohm;
/**
* 创建输出线程(默认立即开启线程)
* @param is
* @param id
* @param ohm
* @return
*/
public static OutHandler create(InputStream is, String id,OutHandlerMethod ohm) {
return create(is, id, ohm,true);
}
/**
* 创建输出线程
* @param is
* @param id
* @param ohm
* @param start-是否立即开启线程
* @return
*/
public static OutHandler create(InputStream is, String id,OutHandlerMethod ohm,boolean start) {
OutHandler out= new OutHandler(is, id, ohm);
if(start)
out.start();
return out;
}
public void setOhm(OutHandlerMethod ohm) {
this.ohm = ohm;
}
public void setDesStatus(boolean desStatus) {
this.desstatus = desStatus;
}
public void setId(String id) {
this.id = id;
}
public OutHandlerMethod getOhm() {
return ohm;
}
public OutHandler(InputStream is, String id,OutHandlerMethod ohm) {
br = new BufferedReader(new InputStreamReader(is));
this.id = id;
this.ohm=ohm;
}
/**
* 重写线程销毁方法,安全的关闭线程
*/
@Override
public void destroy() {
setDesStatus(false);
}
/**
* 执行输出线程
*/
@Override
public void run() {
String msg = null;
try {
if (CommandManager.config.isDebug()) {
System.out.println(id + "开始推流!");
}
while (desstatus && (msg = br.readLine()) != null) {
ohm.parse(id,msg);
if(ohm.isbroken()) {
System.err.println("检测到中断,提交重启任务给保活处理器");
//如果发生异常中断,立即进行保活
//把中断的任务交给保活处理器进行进一步处理
KeepAliveHandler.add(id);
}
}
} catch (IOException e) {
System.out.println("发生内部异常错误,自动关闭[" + this.getId() + "]线程");
destroy();
} finally {
if (this.isAlive()) {
destroy();
}
}
}
}
package com.yeejoin.amos.ffmpeg.hander;
/**
* 输出消息处理
* @author eguid
* @since jdk1.7
* @version 2017年10月13日
*/
public interface OutHandlerMethod {
/**
* 解析消息
* @param id-任务ID
* @param msg -消息
*/
public void parse(String id, String msg);
/**
* 任务是否异常中断
* @return
*/
public boolean isbroken();
}
package com.yeejoin.amos.ffmpeg.hander;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
/**
* 任务执行接口
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public interface TaskHandler {
/**
* 按照命令执行主进程和输出线程
*
* @param id
* @param command
* @return
*/
public CommandTasker process(String id, String command);
/**
* 停止主进程(停止主进程需要保证输出线程已经关闭,否则输出线程会出错)
*
* @param process
* @return
*/
public boolean stop(Process process);
/**
* 停止输出线程
*
* @param thread
* @return
*/
public boolean stop(Thread thread);
/**
* 正确的停止输出线程和主进程
*
* @param process
* @param thread
* @return
*/
public boolean stop(Process process, Thread thread);
}
package com.yeejoin.amos.ffmpeg.hander;
import java.io.IOException;
import com.yeejoin.amos.ffmpeg.CommandManager;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.utils.ExecUtil;
/**
* 任务处理实现
* @author eguid
* @since jdk1.7
* @version 2016年10月29日
*/
public class TaskHandlerImpl implements TaskHandler {
private OutHandlerMethod ohm=null;
public TaskHandlerImpl(OutHandlerMethod ohm) {
this.ohm = ohm;
}
public void setOhm(OutHandlerMethod ohm) {
this.ohm = ohm;
}
@Override
public CommandTasker process(String id, String command) {
CommandTasker tasker = null;
try {
tasker =ExecUtil.createTasker(id,command,ohm);
if(CommandManager.config.isDebug())
System.out.println(id+" 执行命令行:"+command);
return tasker;
} catch (IOException e) {
//运行失败,停止任务
ExecUtil.stop(tasker);
if(CommandManager.config.isDebug())
System.err.println(id+" 执行命令失败!进程和输出线程已停止");
// 出现异常说明开启失败,返回null
return null;
}
}
@Override
public boolean stop(Process process) {
return ExecUtil.stop(process);
}
@Override
public boolean stop(Thread outHandler) {
return ExecUtil.stop(outHandler);
}
@Override
public boolean stop(Process process, Thread thread) {
boolean ret=false;
ret=stop(thread);
ret=stop(process);
return ret;
}
}
This diff is collapsed.
package com.yeejoin.amos.ffmpeg.utils;
import java.io.File;
import java.util.UUID;
import org.springframework.util.ClassUtils;
/**
* 公共常用方法工具
*
* @author eguid
*
*/
public class CommonUtil {
/**
* 当前项目根路径
*/
public static final String rootPath = getProjectRootPath();
public static final String TRUE = "true";
public static final String NULL_STRING = "";
public static final String H_LINE = "-";
public static String getUUID() {
return UUID.randomUUID().toString().trim().replaceAll(H_LINE, NULL_STRING);
}
/**
* 是否为空
*
* @param str
* @return boolean true:为空,false:不为空
*/
public static boolean isNull(String str) {
return str == null || NULL_STRING.equals(str.trim());
}
/**
* 字符串是否是"true"
*
* @param str
* @return
*/
public static boolean isTrue(String str) {
return TRUE.equals(str) ? true : false;
}
/**
* 获取项目根目录(静态)
*
* @return
*/
public static String getRootPath() {
return rootPath;
}
/**
* 获取项目根目录(动态)
*
* @return
*/
public static String getProjectRootPath() {
String path = null;
try {
path = ClassUtils.getDefaultClassLoader().getResource("").getPath();
} catch (Exception e) {
File directory = new File(NULL_STRING);
path = directory.getAbsolutePath() + File.separator;
}
return path;
}
/**
* 获取类路径
*
* @param cla
* @return
*/
public static String getClassPath(Class<?> cla) {
return cla.getResource("").getPath();
}
}
package com.yeejoin.amos.ffmpeg.utils;
import java.io.IOException;
import com.yeejoin.amos.ffmpeg.data.CommandTasker;
import com.yeejoin.amos.ffmpeg.hander.OutHandler;
import com.yeejoin.amos.ffmpeg.hander.OutHandlerMethod;
/**
* 命令行操作工具类
* @author eguid
*
*/
public class ExecUtil {
/**
* 执行命令行并获取进程
* @param cmd
* @return
* @throws IOException
*/
public static Process exec(String cmd) throws IOException {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(cmd);// 执行命令获取主进程
return process;
}
/**
* 销毁进程
* @param process
* @return
*/
public static boolean stop(Process process) {
if (process != null) {
process.destroy();
return true;
}
return false;
}
/**
* 销毁输出线程
* @param outHandler
* @return
*/
public static boolean stop(Thread outHandler) {
if (outHandler != null && outHandler.isAlive()) {
outHandler.stop();
outHandler.destroy();
return true;
}
return false;
}
/**
* 销毁
* @param process
* @param outHandler
*/
public static void stop(CommandTasker tasker) {
if(tasker!=null) {
stop(tasker.getThread());
stop(tasker.getProcess());
}
}
/**
* 创建命令行任务
* @param id
* @param command
* @return
* @throws IOException
*/
public static CommandTasker createTasker(String id,String command,OutHandlerMethod ohm) throws IOException {
// 执行本地命令获取任务主进程
Process process=exec(command);
// 创建输出线程
OutHandler outHandler=OutHandler.create(process.getErrorStream(), id,ohm);
CommandTasker tasker = new CommandTasker(id,command, process, outHandler);
return tasker;
}
/**
* 中断故障缘故重启
* @param tasker
* @return
* @throws IOException
*/
public static CommandTasker restart(CommandTasker tasker) throws IOException {
if(tasker!=null) {
String id=tasker.getId(),command=tasker.getCommand();
OutHandlerMethod ohm=null;
if(tasker.getThread()!=null) {
ohm=tasker.getThread().getOhm();
}
//安全销毁命令行进程和输出子线程
stop(tasker);
// 执行本地命令获取任务主进程
Process process=exec(command);
tasker.setProcess(process);
// 创建输出线程
OutHandler outHandler=OutHandler.create(process.getErrorStream(), id,ohm);
tasker.setThread(outHandler);
}
return tasker;
}
}
package com.yeejoin.amos.ffmpeg.utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
/**
* properties配置文件读取
* @author eguid
*
*/
public class PropertiesUtil {
/**
* 加载properties配置文件并读取配置项
* @param path
* @param cl
* @return
*/
@SuppressWarnings("unchecked")
public static <T>T load(String path, Class<T> cl) {
InputStream is = null;
try {
is = getInputStream(path);
} catch (FileNotFoundException e) {
//尝试从web目录读取
String newpath=CommonUtil.getProjectRootPath()+path;
System.err.println("尝试从web目录读取配置文件:"+newpath);
try {
is = getInputStream(newpath);
System.err.println("web目录读取到配置文件:"+newpath);
} catch (FileNotFoundException e1) {
System.err.println("没找到配置文件,读取默认配置文件");
//尝试从jar包中读取默认配置文件
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
try {
is = classloader.getResourceAsStream("com/yeejoin/amos/ffmpeg/config/defaultFFmpegConfig.properties");
System.err.println("读取默认配置文件:defaultFFmpegConfig.properties");
} catch (Exception e2) {
System.err.println("没找到默认配置文件:defaultFFmpegConfig.properties");
return null;
}
}
}
if (is != null) {
Properties pro = new Properties();
try {
System.err.println("加载配置文件...");
pro.load(is);
System.err.println("加载配置文件完毕");
return (T)load(pro, cl);
} catch (IOException e) {
System.err.println("加载配置文件失败");
return null;
}
}
return null;
}
/**
* 读取配置项并转换为对应对象
* @param pro
* @param cl
* @return
*/
public static Object load(Properties pro, Class<?> cl) {
try {
Map<String, Object> map = getMap(pro);
System.err.println("读取的配置项:" + map);
Object obj = ReflectUtil.mapToObj(map, cl);
System.err.println("转换后的对象:" + obj);
return obj;
} catch (InstantiationException e) {
System.err.println("加载配置文件失败");
return null;
} catch (IllegalAccessException e) {
System.err.println("加载配置文件失败");
return null;
} catch (IllegalArgumentException e) {
System.err.println("加载配置文件失败");
return null;
} catch (InvocationTargetException e) {
System.err.println("加载配置文件失败");
return null;
}
}
/**
* 获取对应文件路径下的文件流
* @param path
* @return
* @throws FileNotFoundException
*/
public static InputStream getInputStream(String path) throws FileNotFoundException {
return new FileInputStream(path);
}
/**
* 根据路径获取properties的Map格式内容
* @param path
* @return
*/
public static Map<String, Object> getMap(String path){
Properties pro=new Properties();
try {
pro.load(getInputStream(path));
return getMap(pro);
} catch (IOException e) {
return null;
}
}
/**
* 根据路径获取properties的Map格式内容
* @param path
* @param isRootPath -是否在项目根目录中
* @return
*/
public static Map<String, Object> getMap(String path,boolean isRootPath){
return getMap(isRootPath?CommonUtil.getProjectRootPath()+path:path);
}
/**
* Properties配置项转为Map<String, Object>
* @param pro
* @return
*/
public static Map<String, Object> getMap(Properties pro) {
if (pro == null || pro.isEmpty() || pro.size() < 1) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
for (Entry<Object, Object> en : pro.entrySet()) {
String key = (String) en.getKey();
Object value = en.getValue();
map.put(key, value);
}
return map;
}
}
package com.yeejoin.amos.ffmpeg.utils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
/**
* 反射操作工具
*
* @author eguid
*
*/
public class ReflectUtil {
public static final String SET = "set";
public static final String GET = "get";
public static Object mapToObj(Map<String, Object> map, Class<?> oc)
throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method[] ms = oc.getDeclaredMethods();
if (ms == null || ms.length < 1) {
return null;
}
Object obj = getObject(oc);
for (Method m : ms) {
String methodName = m.getName();
String fieldName = getMethodField(methodName, SET);
Object value = map.get(fieldName);
if (value != null) {
setMethodValue(m, obj, typeConvert(value, m));
}
}
return obj;
}
public static Object typeConvert(Object obj, Method m) {
return typeConvert(obj, m.getParameterTypes()[0].getName());
}
public static Object typeConvert(Object obj, Field f) {
return typeConvert(obj, f.getType().getName());
}
/**
* 基础数据转换
* @param obj
* @param typeName
* @return
*/
public static Object typeConvert(Object obj, String typeName) {
// 基础数据都可以转为String
String str = String.valueOf(obj);
if ("int".equals(typeName) || "java.lang.Integer".equals(typeName)) {
return Integer.valueOf(str.trim());
} else if ("long".equals(typeName) || "java.lang.Long".equals(typeName)) {
return Long.valueOf(str.trim());
} else if ("byte".equals(typeName) || "java.lang.Byte".equals(typeName)) {
return Byte.valueOf(str.trim());
} else if ("short".equals(typeName) || "java.lang.Short".equals(typeName)) {
return Short.valueOf(str.trim());
} else if ("float".equals(typeName) || "java.lang.Float".equals(typeName)) {
return Float.valueOf(str.trim());
} else if ("double".equals(typeName) || "java.lang.Double".equals(typeName)) {
return Double.valueOf(str.trim());
} else if ("boolean".equals(typeName) || "java.lang.Boolean".equals(typeName)) {
return CommonUtil.TRUE.equals(str)?true:false;
} else if ("char".equals(typeName) || "java.lang.Character".equals(typeName)) {
return Character.valueOf(str.trim().charAt(0));
} else if ("java.lang.String".equals(typeName)) {
return str;
}
return null;
}
public static Class<?> getFieldType(Class<?> cl, String fieldName) throws NoSuchFieldException, SecurityException {
Field f = cl.getDeclaredField(fieldName);
return f.getType();
}
public static Field findField(Class<?> cl, String fieldName) throws NoSuchFieldException, SecurityException {
return cl.getDeclaredField(fieldName);
}
/**
* 执行方法
*
* @param m
* - 方法
* @param obj
* - 对象
* @param value
* - 参数
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public static Object setMethodValue(Method m, Object obj, Object... value)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
m.getParameterTypes();
return m.invoke(obj, value);
}
public static Object getFieldValue(Class<?> obj, String FieldName) throws NoSuchFieldException, SecurityException {
return obj.getDeclaredField(FieldName);
}
/**
* 通过class实例化
*
* @param oc
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
public static Object getObject(Class<?> oc) throws InstantiationException, IllegalAccessException {
return oc.newInstance();
}
/**
* 获取方法字段
*
* @param methodName
* @param prefix
* @param lowercase
* @return
*/
public static String getMethodField(String methodName, String prefix) {
String m = null;
if (prefix != null) {
if (methodName.indexOf(prefix) >= 0) {
m = methodName.substring(prefix.length());
return stringFirstLower(m);
}
}
return m;
}
/**
* 首字母大写
*
* @param str
* @return
*/
public static String stringFirstUpper(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
/**
* 首字母小写
*
* @param str
* @return
*/
public static String stringFirstLower(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'A' && ch[0] <= 'Z') {
ch[0] = (char) (ch[0] + 32);
}
return new String(ch);
}
}
package com.yeejoin.amos.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.yeejoin.amos.entity.Video;
@Repository
public interface VideoMapper {
public Integer getCount(@Param("name") String name, @Param("parentId") Long parentId);
public List<Video> findPageList( @Param("offset")Integer offset,@Param("pageSize") Integer pageSize,@Param("name") String name, @Param("parentId") Long parentId);
/**
* 根据楼层查询摄像头
* @param floor3d
* @return
*/
public List<Video> findAll(@Param("floor3d") String floor3d);
List<Video> selectByParentId();
void insertVideo(Video video);
void deleteVideo(@Param("token") String token);
Video selectByToken(@Param("token") String token);
void updateVideo(Video video);
}
package com.yeejoin.amos.response;
import java.io.Serializable;
public class CommonResponse implements Serializable
{
private static final long serialVersionUID = -8737351878134480646L;
private String result;
private Object dataList;
private String message;
public CommonResponse() {
}
public CommonResponse(final String result) {
this.result = result;
}
public CommonResponse(final Object dataList) {
this.dataList = dataList;
this.result = "";
}
public CommonResponse(final String result, final Object dataList) {
this.dataList = dataList;
this.result = result;
}
public CommonResponse(final String result, final String message) {
this.result = result;
this.message = message;
}
public CommonResponse(final String result, final Object dataList, final String message) {
this.dataList = dataList;
this.result = result;
this.message = message;
}
public Boolean isSuccess() {
return "SUCCESS".equals(this.getResult());
}
public String getResult() {
return this.result;
}
public void setResult(final String result) {
this.result = result;
}
public String getMessage() {
return this.message;
}
public void setMessage(final String message) {
this.message = message;
}
public Object getDataList() {
return this.dataList;
}
public void setDataList(final Object dataList) {
this.dataList = dataList;
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;
import java.util.HashMap;
import java.util.List;
@Component
public class HandleRtpWebSocker implements IHandleWebSocket {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Rtp Sesson start:" + session.getId());
System.out.println(session.getAcceptedProtocol());
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
SessionInfo sessionInfo = SessionInfo.get(session.getId());
if(sessionInfo == null) {
String str_msg = message.getPayload();
System.out.println("Recv from RTP session:[" + session.getId() + "]\r\n" + str_msg);
List<String> lines = Utils.msg2lines(str_msg);
HashMap<String,String> hsmpVal = Utils.list2key(lines, ":", 1);
String channel = hsmpVal.get("channel".toLowerCase());
String seq = hsmpVal.get("seq".toLowerCase());
try {
if(!StringUtils.isEmpty(channel))
{
String rtspChannel = channel.trim().substring(channel.indexOf(" ")).trim();
sessionInfo = SessionInfo.getByChannel(rtspChannel);
if(sessionInfo == null) {
session.sendMessage(new TextMessage("UNKNOWN\r\n\r\n"));
return;
} else {
SessionInfo.add(session.getId(),sessionInfo);
sessionInfo.getLocalRtspService().attachRtpChannel(session);
String s = WebSocketConfig.PROXY_PROTOCOL + "/" + WebSocketConfig.PROXY_VERSION + " 200 OK" + "\r\n"
+ "seq: " + seq + "\r\n"
+ "\r\n";
session.sendMessage(new TextMessage(s));
System.out.println("[Send to RTP Channel]\r\n" + s);
return;
}
}
session.sendMessage(new TextMessage("ERROR\r\n\r\n"));
} catch (Exception e) {
}
return;
} else {
try {
//sessionInfo.getTcpTask().send(null);
} catch (Exception e) {
e.printStackTrace();
sessionInfo.close();
}
}
}
@Override
public void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
SessionInfo sessionInfo = SessionInfo.get(session.getId());
if(sessionInfo != null) {
SessionInfo.remove(session.getId());
System.out.println("RTP Sesson closed:" + session.getId());
}
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
@Component
public class HandleRtspWebSocker implements IHandleWebSocket {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Rtsp Sesson start:" + session.getId());
}
@Override
public void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
ByteBuffer bb = message.getPayload();
byte[] data = bb.array();
System.out.println("Recv from RTP session:[" + session.getId() + "]\r\n" + new String(data));
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
try {
String str_msg = message.getPayload();
System.out.println("Recv from RTSP session:[" + session.getId() + "]\r\n" + str_msg);
SessionInfo sessionInfo = SessionInfo.get(session.getId());
if (sessionInfo == null) {
List<String> lines = Utils.msg2lines(str_msg);
HashMap<String, String> hsmpVal = Utils.list2key(lines, ":", 1);
String host = hsmpVal.get("host".toLowerCase());
String sport = hsmpVal.get("port".toLowerCase());
String url = hsmpVal.get("url".toLowerCase());
String seq = hsmpVal.get("seq".toLowerCase());
if (StringUtils.isEmpty(host) || StringUtils.isEmpty(sport)) {
session.sendMessage(new TextMessage("UNKNOWN\r\n\r\n"));
return;
}
int port = Integer.parseInt(sport);
sessionInfo = new SessionInfo();
sessionInfo.setHost(host);
sessionInfo.setPort(port);
sessionInfo.setUrl(url);
SessionInfo.add(session.getId(), sessionInfo);
sessionInfo.setLocalRtspService(new LocalRtspService((sessionInfo)));
sessionInfo.setRemoteRtspService(new RemoteRtspService(sessionInfo));
sessionInfo.getLocalRtspService().attachRtspChannel(session);
sessionInfo.getRemoteRtspService().start();
sessionInfo.getLocalRtspService().start();
String channel = sessionInfo.getChannel();
String channelStr = "localhost-" + channel + " " + channel;
String s = WebSocketConfig.PROXY_PROTOCOL + "/" + WebSocketConfig.PROXY_VERSION + " 200 OK" + "\r\n"
+ "channel: " + channelStr + "\r\n"
+ "seq: " + seq + "\r\n"
+ "\r\n";
session.sendMessage(new TextMessage(s));
System.out.println("[Send to RTSP Channel]\r\n" + s);
return;
} else {
sessionInfo.getLocalRtspService().recvMsg(str_msg);
}
} catch(Exception e) {
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
SessionInfo sessionInfo = SessionInfo.get(session.getId());
if(sessionInfo != null) {
SessionInfo.remove(session.getId());
sessionInfo.close();
System.out.println("RTSP Sesson closed:" + session.getId());
}
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.util.HashMap;
import java.util.List;
@Component
public class HandleWebSocker {
@Autowired
HandleRtpWebSocker handleRtpWebSocker;
@Autowired
HandleRtspWebSocker handleRtspWebSocker;
IHandleWebSocket getHandleWebSocket(WebSocketSession session) {
String secWebSocketProtocol = session.getHandshakeHeaders().getFirst("Sec-WebSocket-Protocol");
if(StringUtils.isEmpty(secWebSocketProtocol)) secWebSocketProtocol = session.getHandshakeHeaders().getFirst("sec-websocket-protocol");
if("control".equalsIgnoreCase(secWebSocketProtocol)) return handleRtspWebSocker;
if("data".equalsIgnoreCase(secWebSocketProtocol)) return handleRtpWebSocker;
return null;
}
void afterConnectionEstablished(WebSocketSession session) throws Exception {
IHandleWebSocket handleWebSocket = getHandleWebSocket(session);
if(handleWebSocket != null) {
handleWebSocket.afterConnectionEstablished(session);
}
}
void handleTextMessage(WebSocketSession session, TextMessage message) {
IHandleWebSocket handleWebSocket = getHandleWebSocket(session);
if(handleWebSocket != null) {
handleWebSocket.handleTextMessage(session,message);
}
}
void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
IHandleWebSocket handleWebSocket = getHandleWebSocket(session);
if(handleWebSocket != null) {
handleWebSocket.handleBinaryMessage(session,message);
}
}
void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
IHandleWebSocket handleWebSocket = getHandleWebSocket(session);
if(handleWebSocket != null) {
handleWebSocket.afterConnectionClosed(session,status);
}
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;
import java.util.HashMap;
import java.util.List;
@Component
public class HtmlRtspPlayerWebSockerServer extends AbstractWebSocketHandler {
@Autowired
HandleWebSocker handleWebSocker;
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
handleWebSocker.afterConnectionEstablished(session);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
handleWebSocker.handleTextMessage(session,message);
}
@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
handleWebSocker.handleBinaryMessage(session,message);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
handleWebSocker.afterConnectionClosed(session,status);
super.afterConnectionClosed(session, status);
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
public interface IHandleWebSocket {
void afterConnectionEstablished(WebSocketSession session) throws Exception;
void handleTextMessage(WebSocketSession session, TextMessage message);
void handleBinaryMessage(WebSocketSession session, BinaryMessage message);
void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception;
}
package com.yeejoin.amos.rtsp;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class LocalRtspService {
private static final String NULL_STRING = "";
private static final byte[] NULL_BYTE = {};
private BlockingQueue<String> queueRtspEvent = new LinkedBlockingDeque<String>();
private BlockingQueue<byte[]> queueRtpEvent = new LinkedBlockingDeque<byte[]>();
private SessionInfo sessionInfo = null;
private RtspSendThread rtspSendThread = null;
private RtpSendThread rtpSendThread = null;
private WebSocketSession rtspSession = null;
private WebSocketSession rtpSession = null;
private HashMap<String,String> hsmpCseq2Seq = new HashMap<String,String>();
public LocalRtspService(SessionInfo sessionInfo) {
this.sessionInfo = sessionInfo;
}
public void start() {
}
public void attachRtspChannel(WebSocketSession rtspSession) {
this.rtspSession = rtspSession;
if(rtspSendThread == null && rtspSession!= null) {
rtspSendThread = new RtspSendThread();
rtspSendThread.start();
}
}
public void attachRtpChannel(WebSocketSession rtpSession) {
this.rtpSession = rtpSession;
if(rtpSendThread == null && rtpSession != null) {
rtpSendThread = new RtpSendThread();
rtpSendThread.start();
}
}
public void close() {
try {
queueRtspEvent.put(NULL_STRING);
queueRtpEvent.put(NULL_BYTE);
} catch(Exception e) {
} }
private class RtspSendThread extends Thread {
public void run() {
try {
String msg;
while((msg = queueRtspEvent.take()) != null) {
if(msg == NULL_STRING)
break;
String head = "";
List<String> lines = Utils.msg2lines(msg);
HashMap<String,String> hsmpVal = Utils.list2key(lines, ":", 1);
String cseq = hsmpVal.get("cseq".toLowerCase());
if(!StringUtils.isEmpty(cseq)) {
String seq = null;
synchronized (hsmpCseq2Seq) {
seq = hsmpCseq2Seq.get(cseq);
hsmpCseq2Seq.remove(cseq);
}
if (seq != null) {
int contentLength = msg.getBytes().length;
head = WebSocketConfig.PROXY_PROTOCOL + "/" + WebSocketConfig.PROXY_VERSION + " 200 OK" + "\r\n"
+ "seq: " + seq + "\r\n"
+ "contentLength: " + contentLength + "\r\n"
+ "\r\n";
}
rtspSession.sendMessage(new TextMessage(head + msg));
System.out.println("[Send to RTSP Channel]--" + rtspSession.getId() + "==============================\r\n" + head + msg);
}
}
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("RtspSendThread is down!");
}
}
public class RtpSendThread extends Thread {
public void run() {
try {
byte[] data;
while((data = queueRtpEvent.take()) != null) {
if(data == NULL_BYTE)
break;
rtpSession.sendMessage(new BinaryMessage(data));
}
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("RtpSendThread is down!");
}
}
private String send_msg = "";
public void recvMsg(String msg) {
send_msg += msg;
int div;
while((div = send_msg.indexOf("\r\n\r\n")) > 0) {
div += 4;
String header = send_msg.substring(0,div).trim();
String body = send_msg.substring(div);
if(!header.startsWith(WebSocketConfig.PROXY_PROTOCOL + "/" + WebSocketConfig.PROXY_VERSION)) {
send_msg = body;
break;
}
List<String> lines = Utils.msg2lines(header);
HashMap<String,String> hsmpVal = Utils.list2key(lines, ":", 1);
String seq = hsmpVal.get("seq".toLowerCase());
String contentLength = hsmpVal.get("contentLength".toLowerCase());
if(!StringUtils.isEmpty(contentLength)) {
int expectLen = Integer.parseInt(contentLength);
byte[] bodyBytes = body.getBytes();
if(expectLen < bodyBytes.length)
return;
String rtspMsg = new String(bodyBytes,0,expectLen);
if(expectLen == bodyBytes.length) {
send_msg = "";
} else {
send_msg = new String(bodyBytes,expectLen,bodyBytes.length - expectLen);
}
lines = Utils.msg2lines(rtspMsg);
hsmpVal = Utils.list2key(lines, ":", 1);
String cseq = hsmpVal.get("cseq".toLowerCase());
if(!StringUtils.isEmpty(seq) && !StringUtils.isEmpty(cseq)) {
synchronized (hsmpCseq2Seq) {
hsmpCseq2Seq.put(cseq, seq);
}
}
sessionInfo.getRemoteRtspService().sendMsg(rtspMsg);
}
}
}
public void sendMsg(String msg) {
if(!msg.startsWith("RTSP")) {
System.out.println("=========================================[ERROR]" + msg.length() + "================================");
}
try {
queueRtspEvent.put(msg);
} catch(Exception e) {
}
}
public void sendData(byte[] data) {
try {
queueRtpEvent.put(data);
} catch(Exception e) {
}
}
public void sendData(byte[] data, int offset, int len) {
if(len == 0) return;
byte[] newData = new byte[len];
System.arraycopy(data,offset,newData,0,len);
sendData(newData);
}
}
This diff is collapsed.
package com.yeejoin.amos.rtsp;
import java.util.HashMap;
public class SessionInfo {
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getRedirectUrl() {
return redirectUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public LocalRtspService getLocalRtspService() {
return localRtspService;
}
public void setLocalRtspService(LocalRtspService localRtspService) {
this.localRtspService = localRtspService;
}
public RemoteRtspService getRemoteRtspService() {
return remoteRtspService;
}
public void setRemoteRtspService(RemoteRtspService remoteRtspService) {
this.remoteRtspService = remoteRtspService;
}
public void close() {
if(localRtspService != null) localRtspService.close();
if(remoteRtspService != null) remoteRtspService.close();
hsmpChannel2SessionInfo.remove(channel);
}
public String getChannel() {
return channel;
}
public SessionInfo() {
channel = Integer.toString(channelSeq ++);
synchronized (hsmpChannel2SessionInfo) {
hsmpChannel2SessionInfo.put(channel, this);
}
}
private LocalRtspService localRtspService = null;
private RemoteRtspService remoteRtspService = null;
private String redirectUrl = null;
private String url = null;
private String host = null;
private int port = 0;
private String channel = null;
private final static HashMap<String,SessionInfo> hsmpSessionInfo = new HashMap<String,SessionInfo>();
private final static HashMap<String,SessionInfo> hsmpChannel2SessionInfo = new HashMap<String,SessionInfo>();
private static int channelSeq = 0;
public static SessionInfo getByChannel(String channel) {
synchronized (hsmpChannel2SessionInfo) {
return hsmpChannel2SessionInfo.get(channel);
}
}
public static void add(String sessionId,SessionInfo sessionInfo) {
hsmpSessionInfo.put(sessionId,sessionInfo);
}
public static void remove(String sessionId) {
hsmpSessionInfo.remove(sessionId);
}
public static SessionInfo get(String sessionId) {
return hsmpSessionInfo.get(sessionId);
}
}
package com.yeejoin.amos.rtsp;
import org.springframework.util.StringUtils;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Utils {
public static List<String> msg2lines(String s) {
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(s.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")));
String line;
List<String> listLine = new ArrayList<String>();
try {
while ((line = br.readLine()) != null) {
listLine.add(line);
}
br.close();
} catch(Exception e) {
e.printStackTrace();
}
return listLine;
}
public static HashMap<String,String> list2key(List<String> lines, String div) {
return list2key(lines,div, 0);
}
public static HashMap<String,String> list2key(List<String> lines, String div, int parseLineIdx) {
HashMap<String,String> hsmpVal = new HashMap<String,String>();
for(int i=parseLineIdx;i<lines.size();i++) {
String line = lines.get(i).trim();
if(line.length() == 0)
continue;
int divIdx = line.indexOf(div);
if(divIdx <= 0)
continue;
String k = line.toLowerCase().substring(0,divIdx).trim();
String v = line.substring(divIdx + div.length()).trim();
hsmpVal.put(k,v);
}
return hsmpVal;
}
public static HashMap<String,String> parseUrl(String url) {
HashMap<String,String> hsmpVal = new HashMap<String,String>();
String protocol = url.split("://")[0];
if(!StringUtils.isEmpty(protocol)) {
String hostfull = url.split("://")[1].split("/")[0];
hostfull = (hostfull.indexOf('@') > 0) ? hostfull.split("@")[1] : hostfull;
String host = (hostfull.indexOf(':') >= 0) ? hostfull.split(":")[0] : hostfull;
int port = (hostfull.indexOf(':') >= 0) ? Integer.parseInt(hostfull.split(":")[1]) : 554;
String path = url.split("://")[1].split("^([^/]+)")[1];
hsmpVal.put("url",url);
hsmpVal.put("protocol",protocol);
hsmpVal.put("host",host);
hsmpVal.put("port",Integer.toString(port));
hsmpVal.put("path",path);
return hsmpVal;
} else {
return null;
}
}
}
package com.yeejoin.amos.rtsp;
public class WebSocketConfig {
public final static String PROXY_PROTOCOL = "WSP";
public final static String PROXY_VERSION = "1.1";
public final static String CMD_INIT = "INIT";
public final static String CMD_JOIN = "JOIN";
public final static String CMD_WRAP = "WRAP";
}
package com.yeejoin.amos.rtsp;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpSession;
import java.util.Map;
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
ServletServerHttpResponse servletResponse = (ServletServerHttpResponse) response;
String protocol = request.getHeaders().getFirst("Sec-WebSocket-Protocol");
if(!StringUtils.isEmpty(protocol))
response.getHeaders().set("Sec-WebSocket-Protocol",protocol);
HttpSession session = servletRequest.getServletRequest().getSession(false);
if (session != null) {
//session.setAttribute(Constants.Content);
//session.setAttribute(Constants.Encod);
//String userName = (String) session.getAttribute(Constants.SESSION_USERNAME);
//attributes.put(Constants.WEBSOCKET_USERNAME,userName);
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
package com.yeejoin.amos.server;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration //配置类注解,被自动扫描发现
@PropertySource("classpath:video/params.properties") //指明配置源文件位置
@ConfigurationProperties("param") //指明前缀
public class ParamsConfig {
/** 后台h5s服务 url */
private String remoteurl;
public String getRemoteurl() {
return remoteurl;
}
public void setRemoteurl(String remoteurl) {
this.remoteurl = remoteurl;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment