Compare commits

...

10 Commits

Author SHA1 Message Date
10724561be 完善 pom 配置 2024-03-26 23:24:40 +08:00
99887f715d 项目完善 2024-03-26 21:44:35 +08:00
05c00db058 zlm 录像api 2024-02-10 20:56:48 +08:00
14d9a80759 zlm 录像api 2024-02-10 19:07:51 +08:00
c993a15711 zlm service 添加 ffmpeg 拉流代理 2024-01-16 15:43:25 +08:00
0e8d4f0cc1 addFFmpegSource 和 delFFmpegSource 接口 2024-01-16 15:16:11 +08:00
1852e7b3d5 修正 2024-01-11 15:50:45 +08:00
443ed7fc2c 更新 README.md 2024-01-11 10:44:34 +08:00
99ce7afc73 Merge branch 'dev-0.1.0_rebuild-sip-handler' into dev-0.1.0 2024-01-11 09:40:30 +08:00
974e34641b DeviceControlRequestDTO 2024-01-09 22:24:48 +08:00
29 changed files with 690 additions and 17 deletions

View File

@ -26,8 +26,61 @@ docker run --name gb28181 --rm \
skcks.cn/gb28181-docking-platform:0.0.1-SNAPSHOT
```
### 清理私仓
切换到私仓目录
例: cd H:/Repository/skcks.cn/gb28181-docking-platform-mvn-repo
```shell
rm -rf ./*/*/*/*/0.1.0-SNAPSHOT
rm -rf ./*/*/*/*/*/0.1.0-SNAPSHOT
```
### 打包到本地私仓
```shell
mvn deploy -s settings.xml -DaltDeploymentRepository=local-repo::default::file:H:/Repository/skcks.cn/gb28181-docking-platform-mvn-repo
```
git push 推送即可
### 公共仓库
https://central.sonatype.com
https://central.sonatype.org/publish/requirements/gpg/#signing-a-file
gpg签名
https://central.sonatype.org/publish/requirements/gpg/
https://www.gpg4win.org/thanks-for-download.html
gpg服务器
- keyserver.ubuntu.com
- keys.openpgp.org
- pgp.mit.edu
settings.xml
```xml
<settings>
<servers>
<server>
<id>ossrh</id>
<username><!-- your token username --></username>
<password><!-- your token password --></password>
</server>
</servers>
<profiles>
<profile>
<id>ossrh</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.keyname>GPG KEY NAME</gpg.keyname>
<gpg.passphrase>GPG KEY PASSWORD</gpg.passphrase>
</properties>
</profile>
</profiles>
</settings>
```
#### 解决idea 控制台乱码
- 设置 > 构建/运行/部署 > 构建工具 > Maven > 运行程序 > VM options
- 添加 -Dfile.encoding=GBK

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -47,7 +47,7 @@ public class RecordInfoRequestDTO {
private String address;
@Builder.Default
private Integer Secrecy = 0;
private Integer secrecy = 0;
@Builder.Default
private String type = "all";
@ -63,5 +63,5 @@ public class RecordInfoRequestDTO {
*
* 1: 进行模糊查询,此时设备所在域应同时进行中心检索和前端检索并将结果统一返回
*/
private Integer IndistinctQuery;
private Integer indistinctQuery;
}

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

117
pom.xml
View File

@ -8,12 +8,35 @@
<version>3.1.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
<packaging>pom</packaging>
<name>gb28181-docking-platform</name>
<description>GB28181 Docking Platform</description>
<developers>
<developer>
<name>shikong</name>
<email>919411476@qq.com</email>
</developer>
</developers>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<scm>
<connection>scm:git:git://github.com/shikong-sk/gb28181-docking-platform.git</connection>
<developerConnection>scm:git:ssh://github.com/shikong-sk/gb28181-docking-platform.git</developerConnection>
<url>https://github.com/shikong-sk/gb28181-docking-platform/tree/master</url>
</scm>
<url>https://github.com/shikong-sk/gb28181-docking-platform.git</url>
<modules>
<module>starter</module>
<module>annotation</module>
@ -25,6 +48,7 @@
<module>gb28181-sip</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
@ -55,10 +79,10 @@
<springdoc.version>2.2.0</springdoc.version>
<!--Docker打包配置-->
<!-- <docker.repository.url>10.10.10.200:5000</docker.repository.url>-->
<!-- <docker.registry.name>skcks.cn</docker.registry.name>-->
<!-- <docker.registry.username>XXX</docker.registry.username>-->
<!-- <docker.registry.password>XXX</docker.registry.password>-->
<!-- <docker.repository.url>10.10.10.200:5000</docker.repository.url>-->
<!-- <docker.registry.name>skcks.cn</docker.registry.name>-->
<!-- <docker.registry.username>XXX</docker.registry.username>-->
<!-- <docker.registry.password>XXX</docker.registry.password>-->
<docker.maven.plugin.version>1.4.13</docker.maven.plugin.version>
<jain-sip.version>1.3.0-91</jain-sip.version>
@ -84,6 +108,89 @@
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>ossrh</id>
<properties>
<skip.docker>true</skip.docker>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.4.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>ossrh</publishingServerId>
<centralBaseUrl>https://central.sonatype.com</centralBaseUrl>
<tokenAuth>true</tokenAuth>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<keyname>2FA8C646FBB668DAF3E6B08CBD85FF18B373C341</keyname>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</profile>
</profiles>
<dependencyManagement>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<groupId>cn.skcks.docking.gb28181</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>cn.skcks.docking</groupId>
<artifactId>gb28181</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>0.1.0</version>
</parent>
<artifactId>zlmediakit-service</artifactId>

View File

@ -0,0 +1,41 @@
package cn.skcks.docking.gb28181.media.dto.proxy;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class AddFFmpegSource {
/**
* FFmpeg 拉流地址,支持任意协议或格式(只要 FFmpeg 支持即可)
*/
private String srcUrl;
/**
* FFmpeg rtmp 推流地址一般都是推给自己
* <p>例如 rtmp://127.0.0.1/live/stream_form_ffmpeg</p>
*/
private String dstUrl;
/**
* FFmpeg 推流成功超时时间
*/
private long timeoutMs;
/**
* 是否开启 hls 录制
*/
private Boolean enableHls;
/**
* 是否开启 mp4 录制
*/
private Boolean enableMp4;
/**
* 配置文件中 FFmpeg 命令参数模板 key(非内容)置空则采用默认模板:ffmpeg.cmd
*/
private String ffmpegCmdKey;
}

View File

@ -0,0 +1,11 @@
package cn.skcks.docking.gb28181.media.dto.proxy;
import lombok.Data;
@Data
public class AddFFmpegSourceResp {
/**
* 流的唯一标识
*/
private String key;
}

View File

@ -0,0 +1,8 @@
package cn.skcks.docking.gb28181.media.dto.proxy;
import lombok.Data;
@Data
public class DelFFmpegSourceResp {
private Boolean flag;
}

View File

@ -0,0 +1,41 @@
package cn.skcks.docking.gb28181.media.dto.record;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@Data
public class DeleteRecordDirectory {
/**
* 添加的流的虚拟主机例如__defaultVhost__
*/
@Builder.Default
private String vhost = "__defaultVhost__";
/**
* 添加的流的应用名例如live
*/
private String app;
/**
* 添加的流的id名
*/
private String stream;
/**
* 流的录像日期格式为 2020-02-01,如果不是完整的日期那么是搜索录像文件夹列表否则搜索对应日期下的 mp4 文件列表
*/
private String period;
/**
* 自定义搜索路径 startRecord 方法中的 customized_path 一样默认为配置文件的路径
*/
private String customizedPath;
}

View File

@ -0,0 +1,19 @@
package cn.skcks.docking.gb28181.media.dto.record;
import cn.skcks.docking.gb28181.media.dto.status.ResponseStatus;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@Data
public class DeleteRecordDirectoryResp {
private ResponseStatus code;
private String path;
}

View File

@ -0,0 +1,41 @@
package cn.skcks.docking.gb28181.media.dto.record;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@Data
public class GetMp4RecordFile {
/**
* 添加的流的虚拟主机例如__defaultVhost__
*/
@Builder.Default
private String vhost = "__defaultVhost__";
/**
* 添加的流的应用名例如live
*/
private String app;
/**
* 添加的流的id名
*/
private String stream;
/**
* 流的录像日期格式为 2020-02-01,如果不是完整的日期那么是搜索录像文件夹列表否则搜索对应日期下的 mp4 文件列表
*/
private String period;
/**
* 自定义搜索路径 startRecord 方法中的 customized_path 一样默认为配置文件的路径
*/
private String customizedPath;
}

View File

@ -0,0 +1,9 @@
package cn.skcks.docking.gb28181.media.dto.record;
import cn.skcks.docking.gb28181.media.dto.response.ZlmResponse;
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class GetMp4RecordFileResp extends ZlmResponse<GetMp4RecordFileRespData> {
}

View File

@ -0,0 +1,15 @@
package cn.skcks.docking.gb28181.media.dto.record;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class GetMp4RecordFileRespData {
private List<String> paths;
private String rootPath;
}

View File

@ -0,0 +1,36 @@
package cn.skcks.docking.gb28181.media.dto.record;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class IsRecording {
/**
* 添加的流的虚拟主机例如__defaultVhost__
*/
@Builder.Default
private String vhost = "__defaultVhost__";
/**
* 0 hls1 mp4
*/
@Builder.Default
private Integer type = 1;
/**
* 添加的流的应用名例如live
*/
private String app;
/**
* 添加的流的id名
*/
private String stream;
}

View File

@ -0,0 +1,19 @@
package cn.skcks.docking.gb28181.media.dto.record;
import cn.skcks.docking.gb28181.media.dto.status.ResponseStatus;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class IsRecordingResp {
private ResponseStatus code;
private Boolean status;
}

View File

@ -0,0 +1,46 @@
package cn.skcks.docking.gb28181.media.dto.record;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class StartRecord {
/**
* 添加的流的虚拟主机例如__defaultVhost__
*/
@Builder.Default
private String vhost = "__defaultVhost__";
/**
* 0 hls1 mp4
*/
@Builder.Default
private Integer type = 1;
/**
* 添加的流的应用名例如live
*/
private String app;
/**
* 添加的流的id名
*/
private String stream;
/**
* 录像保存目录
*/
private String customizedPath;
/**
* mp4 录像切片时间大小,单位秒 0 则采用配置项
*/
private int maxSecond = 0;
}

View File

@ -0,0 +1,19 @@
package cn.skcks.docking.gb28181.media.dto.record;
import cn.skcks.docking.gb28181.media.dto.status.ResponseStatus;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class StartRecordResp {
private ResponseStatus code;
private Boolean result;
}

View File

@ -0,0 +1,36 @@
package cn.skcks.docking.gb28181.media.dto.record;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class StopRecord {
/**
* 添加的流的虚拟主机例如__defaultVhost__
*/
@Builder.Default
private String vhost = "__defaultVhost__";
/**
* 0 hls1 mp4
*/
@Builder.Default
private Integer type = 1;
/**
* 添加的流的应用名例如live
*/
private String app;
/**
* 添加的流的id名
*/
private String stream;
}

View File

@ -0,0 +1,19 @@
package cn.skcks.docking.gb28181.media.dto.record;
import cn.skcks.docking.gb28181.media.dto.status.ResponseStatus;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class StopRecordResp {
private ResponseStatus code;
private Boolean result;
}

View File

@ -4,6 +4,7 @@ import cn.skcks.docking.gb28181.media.dto.config.ServerConfig;
import cn.skcks.docking.gb28181.media.dto.media.GetMediaList;
import cn.skcks.docking.gb28181.media.dto.media.MediaResp;
import cn.skcks.docking.gb28181.media.dto.proxy.*;
import cn.skcks.docking.gb28181.media.dto.record.*;
import cn.skcks.docking.gb28181.media.dto.response.ZlmResponse;
import cn.skcks.docking.gb28181.media.dto.rtp.*;
import cn.skcks.docking.gb28181.media.dto.snap.Snap;
@ -17,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Map;
@FeignClient(name="zlmMediaServerProxy", url = "${media.url}", configuration = IgnoreSSLFeignClientConfig.class)
public interface ZlmMediaHttpClient {
@ -76,4 +78,25 @@ public interface ZlmMediaHttpClient {
@GetMapping("/index/api/getRtpInfo")
GetRtpInfoResp getRtpInfo(@RequestParam String secret,@RequestParam("stream_id") String streamId);
@PostMapping("/index/api/addFFmpegSource")
ZlmResponse<AddFFmpegSourceResp> addFFmpegSource(@RequestParam String secret,@RequestBody AddFFmpegSource params);
@GetMapping("/index/api/delFFmpegSource")
ZlmResponse<DelFFmpegSourceResp> delFFmpegSource(@RequestParam String secret, @RequestParam String key);
@PostMapping("/index/api/startRecord")
StartRecordResp startRecord(@RequestParam String secret, @RequestBody StartRecord params);
@PostMapping("/index/api/stopRecord")
StopRecordResp stopRecord(@RequestParam String secret, @RequestBody StopRecord params);
@PostMapping("/index/api/isRecording")
IsRecordingResp isRecording(@RequestParam String secret, @RequestBody IsRecording params);
@PostMapping("/index/api/getMp4RecordFile")
GetMp4RecordFileResp getMp4RecordFile(@RequestParam String secret, @RequestBody GetMp4RecordFile params);
@PostMapping("/index/api/deleteRecordDirectory")
DeleteRecordDirectoryResp deleteRecordDirectory(@RequestParam String secret, @RequestBody DeleteRecordDirectory params);
}

View File

@ -4,14 +4,19 @@ import cn.skcks.docking.gb28181.media.dto.config.ServerConfig;
import cn.skcks.docking.gb28181.media.dto.media.GetMediaList;
import cn.skcks.docking.gb28181.media.dto.media.MediaResp;
import cn.skcks.docking.gb28181.media.dto.proxy.*;
import cn.skcks.docking.gb28181.media.dto.record.*;
import cn.skcks.docking.gb28181.media.dto.response.ZlmResponse;
import cn.skcks.docking.gb28181.media.dto.rtp.*;
import cn.skcks.docking.gb28181.media.dto.snap.Snap;
import cn.skcks.docking.gb28181.media.dto.version.VersionResp;
import lombok.Builder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Map;
@Builder
@SuppressWarnings("unused")
@ -159,5 +164,55 @@ public class ZlmMediaService {
public GetRtpInfoResp getRtpInfo(String streamId){
return exchange.getRtpInfo(secret, streamId);
}
/**
* 功能通过 fork FFmpeg 进程的方式拉流代理支持任意协议
*/
public ZlmResponse<AddFFmpegSourceResp> addFfmpegSource(AddFFmpegSource params){
return exchange.addFFmpegSource(secret, params);
}
/**
* 功能关闭 ffmpeg 拉流代理
*/
public ZlmResponse<DelFFmpegSourceResp> delFfmpegSource(String key){
return exchange.delFFmpegSource(secret, key);
}
/**
* 开始录制 hls MP4
*/
public StartRecordResp startRecord(@RequestBody StartRecord params){
return exchange.startRecord(secret, params);
}
/**
* 停止录制流
*/
public StopRecordResp stopRecord(@RequestBody StopRecord params){
return exchange.stopRecord(secret, params);
}
/**
* 获取流录制状态
*/
public IsRecordingResp isRecording(@RequestBody IsRecording params){
return exchange.isRecording(secret, params);
}
/**
* 搜索文件系统获取流对应的录像文件列表或日期文件夹列表
*/
public GetMp4RecordFileResp getMp4RecordFile(@RequestBody GetMp4RecordFile params){
return exchange.getMp4RecordFile(secret, params);
}
public DeleteRecordDirectoryResp deleteRecordDirectory(@RequestBody DeleteRecordDirectory params){
return exchange.deleteRecordDirectory(secret, params);
}
}

View File

@ -3,7 +3,7 @@ project:
media:
ip: 10.10.10.200
url: 'http://10.10.10.200:5080'
url: 'http://10.10.10.200:5081'
# url: 'http://10.10.10.200:12580/anything/'
id: amrWMKmbKqoBjRQ9
secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333

View File

@ -1,6 +1,7 @@
package cn.skcks.docking.gb28181.test;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.skcks.docking.gb28181.common.json.JsonResponse;
import cn.skcks.docking.gb28181.common.json.JsonUtils;
@ -10,6 +11,7 @@ import cn.skcks.docking.gb28181.media.dto.config.ServerConfig;
import cn.skcks.docking.gb28181.media.dto.media.GetMediaList;
import cn.skcks.docking.gb28181.media.dto.media.MediaResp;
import cn.skcks.docking.gb28181.media.dto.proxy.*;
import cn.skcks.docking.gb28181.media.dto.record.*;
import cn.skcks.docking.gb28181.media.dto.response.ZlmResponse;
import cn.skcks.docking.gb28181.media.dto.response.ZlmResponseConvertor;
import cn.skcks.docking.gb28181.media.dto.rtp.*;
@ -31,6 +33,10 @@ import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@SpringBootTest
@ -41,6 +47,7 @@ public class MediaServiceTest {
private ZlmMediaService zlmMediaService;
@Autowired
private ZlmMediaConfig config;
private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
@Test
void test(){
@ -212,4 +219,72 @@ public class MediaServiceTest {
GetRtpInfoResp rtpInfo = zlmMediaService.getRtpInfo("test");
log.info("{}", rtpInfo);
}
@SneakyThrows
@Test
void recordTest(){
CountDownLatch countDownLatch = new CountDownLatch(1);
String customizedPath = "/tmp/record";
DeleteRecordDirectoryResp deleteRecordDirectoryResp = zlmMediaService.deleteRecordDirectory(DeleteRecordDirectory.builder()
.app("live")
.stream("test")
.period(DateUtil.formatDate(DateUtil.date()))
.customizedPath(customizedPath).build());
log.info("{}", deleteRecordDirectoryResp);
// ZlmResponse<AddStreamProxyResp> addedStreamProxy = zlmMediaService.addStreamProxy(AddStreamProxy.builder()
// .app("live")
// .stream("test")
// .vhost("__defaultVhost__")
// .url("rtsp://10.10.10.200:554/camera/121")
// .build());
// log.info("addedStreamProxy {}", addedStreamProxy);
ZlmResponse<AddFFmpegSourceResp> addFFmpegSourceRespZlmResponse = zlmMediaService.addFfmpegSource(AddFFmpegSource.builder()
.dstUrl("rtmp://10.10.10.200:1936/live/test")
.srcUrl("http://10.10.10.200:18183/video")
.timeoutMs(30 * 1000L)
.enableHls(false)
.enableMp4(false)
.build());
log.info("addFfmpegSource {}", addFFmpegSourceRespZlmResponse);
ZlmResponse<List<MediaResp>> mediaList = zlmMediaService.getMediaList(GetMediaList.builder()
.schema("rtsp")
.app("live")
.stream("test")
.build());
log.info("mediaList {}", mediaList);
StartRecordResp startRecordResp = zlmMediaService.startRecord(StartRecord.builder()
.app("live")
.stream("test")
.vhost("__defaultVhost__")
.customizedPath(customizedPath)
.build());
log.info("startRecordResp {}", startRecordResp);
scheduledExecutorService.schedule(() -> {
ZlmResponse<DelFFmpegSourceResp> delFFmpegSourceRespZlmResponse = zlmMediaService.delFfmpegSource(addFFmpegSourceRespZlmResponse.getData().getKey());
log.info("delFFmpegSourceRespZlmResponse {}", delFFmpegSourceRespZlmResponse);
StopRecordResp stopRecordResp = zlmMediaService.stopRecord(StopRecord.builder()
.app("live")
.stream("test")
.vhost("__defaultVhost__")
.build());
log.info("stopRecordResp {}", stopRecordResp);
GetMp4RecordFileResp mp4RecordFile = zlmMediaService.getMp4RecordFile(GetMp4RecordFile.builder()
.app("live")
.stream("test")
.period(DateUtil.formatDate(DateUtil.date()))
.customizedPath(customizedPath).build());
log.info("mp4RecordFile {}", mp4RecordFile);
countDownLatch.countDown();
}, 15, TimeUnit.SECONDS);
countDownLatch.await();
}
}