Merge remote-tracking branch 'sk/dev-0.1.0' into dev-0.1.0

# Conflicts:
#	gb28181-mocking-service/src/main/java/cn/skcks/docking/gb28181/mocking/service/device/DeviceProxyService.java
This commit is contained in:
shikong 2024-02-22 09:33:46 +08:00
commit 2704f224b8
5 changed files with 60 additions and 58 deletions

View File

@ -6,7 +6,7 @@ import org.springframework.context.annotation.Configuration;
@Data @Data
@Configuration @Configuration
@ConfigurationProperties(prefix = "media.rtmp") @ConfigurationProperties(prefix = "media.rtsp")
public class ZlmRtmpConfig { public class ZlmRtspConfig {
int port = 1935; int port = 554;
} }

View File

@ -26,7 +26,7 @@ import cn.skcks.docking.gb28181.media.proxy.ZlmMediaService;
import cn.skcks.docking.gb28181.mocking.config.sip.DeviceProxyConfig; import cn.skcks.docking.gb28181.mocking.config.sip.DeviceProxyConfig;
import cn.skcks.docking.gb28181.mocking.config.sip.FfmpegConfig; import cn.skcks.docking.gb28181.mocking.config.sip.FfmpegConfig;
import cn.skcks.docking.gb28181.mocking.config.sip.ZlmHookConfig; import cn.skcks.docking.gb28181.mocking.config.sip.ZlmHookConfig;
import cn.skcks.docking.gb28181.mocking.config.sip.ZlmRtmpConfig; import cn.skcks.docking.gb28181.mocking.config.sip.ZlmRtspConfig;
import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.notify.dto.MediaStatusRequestDTO; import cn.skcks.docking.gb28181.mocking.core.sip.message.processor.message.request.notify.dto.MediaStatusRequestDTO;
import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe; import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe;
import cn.skcks.docking.gb28181.mocking.core.sip.request.SipRequestBuilder; import cn.skcks.docking.gb28181.mocking.core.sip.request.SipRequestBuilder;
@ -91,7 +91,7 @@ public class DeviceProxyService {
private final ZlmMediaService zlmMediaService; private final ZlmMediaService zlmMediaService;
private final ZlmMediaConfig zlmMediaConfig; private final ZlmMediaConfig zlmMediaConfig;
private final ZlmStreamChangeHookService zlmStreamChangeHookService; private final ZlmStreamChangeHookService zlmStreamChangeHookService;
private final ZlmRtmpConfig zlmRtmpConfig; private final ZlmRtspConfig zlmRtspConfig;
private final VideoCacheManager videoCacheManager; private final VideoCacheManager videoCacheManager;
private final String DEFAULT_ZLM_APP = "live"; private final String DEFAULT_ZLM_APP = "live";
@ -111,7 +111,7 @@ public class DeviceProxyService {
GB28181Description gb28181Description = new GB28181DescriptionParser(new String(request.getRawContent())).parse(); GB28181Description gb28181Description = new GB28181DescriptionParser(new String(request.getRawContent())).parse();
MediaDescription mediaDescription = (MediaDescription)gb28181Description.getMediaDescriptions(true).get(0); MediaDescription mediaDescription = (MediaDescription)gb28181Description.getMediaDescriptions(true).get(0);
boolean tcp = StringUtils.containsIgnoreCase(mediaDescription.getMedia().getProtocol(), "TCP"); boolean tcp = StringUtils.containsIgnoreCase(mediaDescription.getMedia().getProtocol(), "TCP");
zlmStreamChangeHookService.getRegistHandler(DEFAULT_ZLM_APP).put(callId,()->{ // zlmStreamChangeHookService.getRegistHandler(DEFAULT_ZLM_APP).put(callId,()->{
Retryer<StartSendRtpResp> retryer = RetryerBuilder.<StartSendRtpResp>newBuilder() Retryer<StartSendRtpResp> retryer = RetryerBuilder.<StartSendRtpResp>newBuilder()
.retryIfResult(resp -> resp.getLocalPort() == null || resp.getLocalPort() <= 0) .retryIfResult(resp -> resp.getLocalPort() == null || resp.getLocalPort() <= 0)
.retryIfException() .retryIfException()
@ -136,13 +136,9 @@ public class DeviceProxyService {
return startSendRtpResp; return startSendRtpResp;
}); });
} catch (Exception e) { } catch (Exception e) {
log.error("调用 zlm rtp 推流失败", e);
schedule.cancel(true); schedule.cancel(true);
// 响应 sdp ok
sendOkResponse.run();
Optional.ofNullable(zlmStreamChangeHookService.getUnregistHandler(DEFAULT_ZLM_APP).remove(callId)) Optional.ofNullable(zlmStreamChangeHookService.getUnregistHandler(DEFAULT_ZLM_APP).remove(callId))
.ifPresent(ZlmStreamChangeHookService.ZlmStreamChangeHookHandler::handler); .ifPresent(ZlmStreamChangeHookService.ZlmStreamChangeHookHandler::handler);
sendBye(request,device,key);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -150,20 +146,16 @@ public class DeviceProxyService {
schedule.cancel(false); schedule.cancel(false);
// 响应 sdp ok // 响应 sdp ok
sendOkResponse.run(); sendOkResponse.run();
});
zlmStreamChangeHookService.getUnregistHandler(DEFAULT_ZLM_APP).put(callId,()->{
scheduledExecutorService.schedule(()->{
StopSendRtp stopSendRtp = new StopSendRtp();
stopSendRtp.setApp(DEFAULT_ZLM_APP);
stopSendRtp.setStream(callId);
stopSendRtp.setSsrc(ssrc);
sendBye(request,device,key);
}, 5, TimeUnit.SECONDS);
});
// zlmStreamNoneReaderHookService.getHandler(DEFAULT_ZLM_APP).put(callId,()->{
// sendBye(request,device,key);
// }); // });
zlmStreamChangeHookService.getUnregistHandler(DEFAULT_ZLM_APP).put(callId,()->{
StopSendRtp stopSendRtp = new StopSendRtp();
stopSendRtp.setApp(DEFAULT_ZLM_APP);
stopSendRtp.setStream(callId);
stopSendRtp.setSsrc(ssrc);
});
zlmStreamNoneReaderHookService.getHandler(DEFAULT_ZLM_APP).put(callId,()->{
sendBye(request,device,key);
});
} }
private Flow.Subscriber<SIPRequest> ffmpegTask(SIPRequest request,ConcurrentHashMap<String, Executor> tasks, String callId, String key, MockingDevice device){ private Flow.Subscriber<SIPRequest> ffmpegTask(SIPRequest request,ConcurrentHashMap<String, Executor> tasks, String callId, String key, MockingDevice device){
@ -182,7 +174,7 @@ public class DeviceProxyService {
ScheduledFuture<?> schedule = trying(request); ScheduledFuture<?> schedule = trying(request);
Flow.Subscriber<SIPRequest> task = ffmpegTask(request, callbackTask, callId, key, device); Flow.Subscriber<SIPRequest> task = ffmpegTask(request, callbackTask, callId, key, device);
try { try {
String zlmRtpUrl = getZlmRtmpUrl(DEFAULT_ZLM_APP, callId); String zlmRtpUrl = getZlmRtspUrl(DEFAULT_ZLM_APP, callId);
FfmpegExecuteResultHandler executeResultHandler = mediaStatus(schedule,request, device, key); FfmpegExecuteResultHandler executeResultHandler = mediaStatus(schedule,request, device, key);
Executor executor = pushRtpTask(fromUrl, zlmRtpUrl, time + 60, executeResultHandler); Executor executor = pushRtpTask(fromUrl, zlmRtpUrl, time + 60, executeResultHandler);
requestZlmPushStream(schedule, sendOkResponse, request, callId, fromUrl, toAddr, toPort, device, key, time, ssrc); requestZlmPushStream(schedule, sendOkResponse, request, callId, fromUrl, toAddr, toPort, device, key, time, ssrc);
@ -202,14 +194,9 @@ public class DeviceProxyService {
ScheduledFuture<?> schedule = trying(request); ScheduledFuture<?> schedule = trying(request);
Flow.Subscriber<SIPRequest> task = ffmpegTask(request, downloadTask, callId, key, device); Flow.Subscriber<SIPRequest> task = ffmpegTask(request, downloadTask, callId, key, device);
try { try {
String zlmRtpUrl = getZlmRtmpUrl(DEFAULT_ZLM_APP, callId); String zlmRtpUrl = getZlmRtspUrl(DEFAULT_ZLM_APP, callId);
// String rtpUrl = "rtp://" + toAddr + ":" + toPort;
FfmpegExecuteResultHandler executeResultHandler = mediaStatus(schedule, request, device, key); FfmpegExecuteResultHandler executeResultHandler = mediaStatus(schedule, request, device, key);
Executor executor = pushDownload2RtpTask(fromUrl, zlmRtpUrl, time + 60, executeResultHandler); Executor executor = pushDownload2RtpTask(fromUrl, zlmRtpUrl, time + 60, executeResultHandler);
// // 停止发送 trying
// schedule.cancel(true);
// // 响应 sdp ok
// sendOkResponse.run();
requestZlmPushStream(schedule, sendOkResponse, request, callId, fromUrl, toAddr, toPort, device, key, time, ssrc); requestZlmPushStream(schedule, sendOkResponse, request, callId, fromUrl, toAddr, toPort, device, key, time, ssrc);
scheduledExecutorService.schedule(task::onComplete, time + 60, TimeUnit.SECONDS); scheduledExecutorService.schedule(task::onComplete, time + 60, TimeUnit.SECONDS);
downloadTask.put(device.getDeviceCode(), executor); downloadTask.put(device.getDeviceCode(), executor);
@ -222,8 +209,8 @@ public class DeviceProxyService {
}; };
} }
private String getZlmRtmpUrl(String app, String streamId){ private String getZlmRtspUrl(String app, String streamId){
return "rtmp://" + zlmMediaConfig.getIp() + ":" + zlmRtmpConfig.getPort() + "/" + app +"/" + streamId; return "rtsp://" + zlmMediaConfig.getIp() + ":" + zlmRtspConfig.getPort() + "/" + app +"/" + streamId;
} }
private ScheduledFuture<?> trying(SIPRequest request){ private ScheduledFuture<?> trying(SIPRequest request){
@ -368,7 +355,7 @@ public class DeviceProxyService {
.withStopStrategy(StopStrategies.stopAfterAttempt(3)) .withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build(); .build();
String toUrl = "rtmp://" + zlmMediaConfig.getIp() + ":" + zlmRtmpConfig.getPort() + "/" + ZLM_FFMPEG_PROXY_APP +"/" + callId; String toUrl = "rtsp://" + zlmMediaConfig.getIp() + ":" + zlmRtspConfig.getPort() + "/" + ZLM_FFMPEG_PROXY_APP +"/" + callId;
String key = GenericSubscribe.Helper.getKey(Request.BYE, callId); String key = GenericSubscribe.Helper.getKey(Request.BYE, callId);
try { try {
ZlmResponse<AddFFmpegSourceResp> sourceResp = retryer.call(() -> zlmMediaService.addFfmpegSource(AddFFmpegSource.builder() ZlmResponse<AddFFmpegSourceResp> sourceResp = retryer.call(() -> zlmMediaService.addFfmpegSource(AddFFmpegSource.builder()
@ -428,7 +415,10 @@ public class DeviceProxyService {
@SneakyThrows @SneakyThrows
public void pullLiveStream2Rtp(SIPRequest request,Runnable sendOkResponse,String callId, MockingDevice device, String rtpAddr, int rtpPort, String ssrc){ public void pullLiveStream2Rtp(SIPRequest request,Runnable sendOkResponse,String callId, MockingDevice device, String rtpAddr, int rtpPort, String ssrc){
String liveCache = CacheUtil.getKey("INVITE", "LIVE", device.getGbDeviceId()); String liveCacheKey = CacheUtil.getKey("INVITE", "LIVE", device.getGbDeviceId());
String liveCache = RedisUtil.StringOps.get(liveCacheKey);
RedisUtil.KeyOps.delete(liveCache);
// 关闭已存在的实时流 bye 订阅如果存在 // 关闭已存在的实时流 bye 订阅如果存在
subscribe.getByeSubscribe().delPublisher(liveCache); subscribe.getByeSubscribe().delPublisher(liveCache);

View File

@ -60,8 +60,8 @@ gb28181:
media: media:
local: local:
hook: http://10.10.10.200:18182/zlm/hook hook: http://10.10.10.200:18182/zlm/hook
rtmp: rtsp:
port: 1935 port: 554
ip: 10.10.10.200 ip: 10.10.10.200
url: 'http://10.10.10.200:5080' url: 'http://10.10.10.200:5080'
# url: 'http://10.10.10.200:12580/anything/' # url: 'http://10.10.10.200:12580/anything/'
@ -81,7 +81,7 @@ ffmpeg-support:
ffprobe: /usr/bin/ffmpeg/ffprobe ffprobe: /usr/bin/ffmpeg/ffprobe
rtp: rtp:
input: -re -i input: -re -i
output: -vcodec h264 -acodec aac -f flv output: -vcodec h264 -acodec aac -f rtsp
debug: debug:
download: false download: false
input: false input: false

View File

@ -11,7 +11,7 @@ spring:
# host: 192.168.1.241 # host: 192.168.1.241
host: 10.10.10.200 host: 10.10.10.200
# [必须修改] 端口号 # [必须修改] 端口号
port: 6379 port: 16379
# [可选] 数据库 DB # [可选] 数据库 DB
database: 15 database: 15
# [可选] 访问密码,若你的redis服务器没有设置密码就不需要用密码去连接 # [可选] 访问密码,若你的redis服务器没有设置密码就不需要用密码去连接
@ -48,7 +48,8 @@ gb28181:
# [可选] # [可选]
domain: 4405010000 domain: 4405010000
# [可选] # [可选]
id: 44050100002000000002 #id: 44050100002000000002
id: 44050100002000000009
# [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验 # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验
password: 123456 password: 123456
expire: 3600 expire: 3600
@ -58,17 +59,17 @@ gb28181:
ip: 10.10.10.20 ip: 10.10.10.20
# ip: 192.168.10.32 # ip: 192.168.10.32
# ip: 192.168.3.12 # ip: 192.168.3.12
port: 5063 # port: 5060
# port: 5061 port: 5061
password: 123456 password: 123456
domain: 4405010000 domain: 4405010000
# id: 44050100002000000002 id: 44050100002000000002
id: 44050100002000000003 # id: 44050100002000000003
media: media:
local: local:
hook: http://10.10.10.20:18182/zlm/hook hook: http://10.10.10.20:18182/zlm/hook
delay: 100ms delay: 2000ms
fixed: 0s fixed: 0s
ip: 10.10.10.200 ip: 10.10.10.200
url: 'http://10.10.10.200:5081' url: 'http://10.10.10.200:5081'
@ -76,20 +77,22 @@ media:
id: amrWMKmbKqoBjRQ9 id: amrWMKmbKqoBjRQ9
# secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc # secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333 secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333
rtmp: rtsp:
port: 1936 port: 554
proxy: proxy:
device: device:
# 代理的视频接口地址, 用于获取历史视频 # 代理的视频接口地址, 用于获取历史视频
# 参数 device_id, begin_time, end_time # 参数 device_id, begin_time, end_time
url: http://10.10.10.20:18186 # url: http://10.10.10.20:
url: http://10.10.10.200:18183
use-download-to-playback: true use-download-to-playback: true
proxy-video-in-time-range: true proxy-video-in-time-range: true
proxy-time-range: 5m proxy-time-range: 5m
pre-download-for-record-info: pre-download-for-record-info:
time-range: 5m time-range: 5m
cache-path: ./record # cache-path: ./record
enable: true enable: true
cache-path: G:/Temp/record
ffmpeg-support: ffmpeg-support:
task: task:
# 最大同时推流任务数, <= 0 时不做限制 # 最大同时推流任务数, <= 0 时不做限制
@ -97,14 +100,23 @@ ffmpeg-support:
ffmpeg: D:\Soft\Captura\ffmpeg\ffmpeg.exe ffmpeg: D:\Soft\Captura\ffmpeg\ffmpeg.exe
ffprobe: D:\Soft\Captura\ffmpeg\ffprobe.exe ffprobe: D:\Soft\Captura\ffmpeg\ffprobe.exe
rtp: rtp:
input: -thread_queue_size 128 -re -i http://10.10.10.200:5081/live/test.live.flv #input: -thread_queue_size 128 -re -i http://10.10.10.200:5081/live/test.live.flv
# input: -re -i #input: -thread_queue_size 128 -re -i rtsp://admin:XXXXXX@10.10.11.171/Streaming/Channels/1/
output: -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f flv #rtp_mpegts #input: -hwaccel cuda -re -i rtsp://10.10.11.200/camera/171
# output: -vcodec h264 -acodec aac -vf scale=640:-1 -f rtp_mpegts # -rtsp_transport tcp input: -re -i
download: -i E:\Repository\other\happytime-gb28181-device-x64\666.mp4 -filter:v "setpts=4.0*PTS" # output: -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f rtsp #flv #rtp_mpegts
output: -c:v copy -an -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f rtsp #flv #
# output: -c:v h264 -an -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f rtsp
download: -thread_queue_size 128 -re -i
download-speed: 0
# output: -vcodec h264 -acodec aac -vf scale=640:-1 -f rtp_mpegts # -rtsp_transport tcp
# download: -i E:\Repository\other\happytime-gb28181-device-x64\666.mp4 -filter:v "setpts=4.0*PTS"
# download: -i E:\Repository\other\happytime-gb28181-device-x64\666.mp4 -filter:v "setpts=4.0*PTS
debug: debug:
download: true # download: true
input: true # input: true
download: false
input: false
output: false output: false
# [可选] 日志配置, 一般不需要改 # [可选] 日志配置, 一般不需要改

View File

@ -70,8 +70,8 @@ media:
id: amrWMKmbKqoBjRQ9 id: amrWMKmbKqoBjRQ9
# secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc # secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333 secret: 4155cca6-2f9f-11ee-85e6-8de4ce2e7333
rtmp: rtsp:
port: 1937 port: 554
proxy: proxy:
device: device:
# 代理的视频接口地址, 用于获取历史视频 # 代理的视频接口地址, 用于获取历史视频
@ -105,7 +105,7 @@ ffmpeg-support:
#output: -filter:v "setpts=4.0*PTS" -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f flv #output: -filter:v "setpts=4.0*PTS" -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f flv
# 下载 正常速率 # 下载 正常速率
#output: -r 30 -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f flv #output: -r 30 -tune zerolatency -vcodec libx264 -acodec aac -preset ultrafast -vf scale=640:-1 -f flv
output: -c:v copy -an -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f flv output: -c:v copy -an -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f rtsp
#output: -r 30 -vcodec libx264 -acodec aac -filter:v "setpts=1*PTS" -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f flv #output: -r 30 -vcodec libx264 -acodec aac -filter:v "setpts=1*PTS" -preset ultrafast -flvflags no_duration_filesize -bf 0 -max_interleave_delta 0 -f flv
#download: -i E:\Repository\other\happytime-gb28181-device-x64\666.mp4 -filter:v "setpts=4.0*PTS" #download: -i E:\Repository\other\happytime-gb28181-device-x64\666.mp4 -filter:v "setpts=4.0*PTS"
download: -i download: -i