diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvp1.yml b/src/main/resources/application-wvp1.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp1.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvp1.yml b/src/main/resources/application-wvp1.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp1.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvpbr.yml b/src/main/resources/application-wvpbr.yml new file mode 100644 index 0000000..dd456fb --- /dev/null +++ b/src/main/resources/application-wvpbr.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: localhost + # [必须修改] 端口号 + port: 30001 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:30000/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203! + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 30007 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 172.27.46.84 + # [可选] 28181服务监听的端口 + port: 30008 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 172.27.46.84 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 172.27.46.84 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30030,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 30025,30029 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvp1.yml b/src/main/resources/application-wvp1.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp1.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvpbr.yml b/src/main/resources/application-wvpbr.yml new file mode 100644 index 0000000..dd456fb --- /dev/null +++ b/src/main/resources/application-wvpbr.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: localhost + # [必须修改] 端口号 + port: 30001 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:30000/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203! + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 30007 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 172.27.46.84 + # [可选] 28181服务监听的端口 + port: 30008 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 172.27.46.84 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 172.27.46.84 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30030,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 30025,30029 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6d3f4ba..3230090 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ application: name: wvp profiles: - active: shentong \ No newline at end of file + active: test \ No newline at end of file diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvp1.yml b/src/main/resources/application-wvp1.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp1.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvpbr.yml b/src/main/resources/application-wvpbr.yml new file mode 100644 index 0000000..dd456fb --- /dev/null +++ b/src/main/resources/application-wvpbr.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: localhost + # [必须修改] 端口号 + port: 30001 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:30000/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203! + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 30007 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 172.27.46.84 + # [可选] 28181服务监听的端口 + port: 30008 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 172.27.46.84 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 172.27.46.84 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30030,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 30025,30029 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6d3f4ba..3230090 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ application: name: wvp profiles: - active: shentong \ No newline at end of file + active: test \ No newline at end of file diff --git a/src/main/resources/bak/application-test.yml b/src/main/resources/bak/application-test.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/bak/application-test.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/doc/conf/config.ini b/doc/conf/config.ini new file mode 100644 index 0000000..b5e0b6d --- /dev/null +++ b/doc/conf/config.ini @@ -0,0 +1,193 @@ +; auto-generated by mINI class { + +[api] +apiDebug=1 +defaultSnap=./www/logo.png +downloadRoot=./www +secret=0EcyrurlYHctuBbgue6zMUrI5aF6J8XO +snapRoot=./www/snap/ + +[cluster] +origin_url= +retry_count=3 +timeout_sec=15 + +[ffmpeg] +bin=/usr/bin/ffmpeg +cmd=%s -re -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s +log=./ffmpeg/ffmpeg.log +restart_sec=0 +snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s + +[general] +broadcast_player_count_changed=0 +check_nvidia_dev=1 +enableVhost=0 +enable_ffmpeg_log=0 +flowThreshold=1024 +maxStreamWaitMS=15000 +mediaServerId=your_server_id +mergeWriteMS=0 +resetWhenRePlay=1 +streamNoneReaderDelayMS=20000 +unready_frame_cache=100 +wait_add_track_ms=3000 +wait_track_ready_ms=10000 + +[hls] +broadcastRecordTs=0 +deleteDelaySec=10 +fastRegister=0 +fileBufSize=65536 +segDelay=0 +segDur=2 +segKeep=0 +segNum=3 +segRetain=5 + +[hook] +alive_interval=10.0 +enable=0 +on_flow_report= +on_http_access= +on_play= +on_publish= +on_record_mp4= +on_record_ts= +on_rtp_server_timeout= +on_rtsp_auth= +on_rtsp_realm= +on_send_rtp_stopped= +on_server_exited= +on_server_keepalive= +on_server_started= +on_shell_login= +on_stream_changed= +on_stream_none_reader= +on_stream_not_found= +retry=1 +retry_delay=3.0 +stream_changed_schemas=rtsp/rtmp/fmp4/ts/hls/hls.fmp4 +timeoutSec=10 + +[http] +allow_cross_domains=1 +allow_ip_range=::1,127.0.0.1,172.16.0.0-172.31.255.255,192.168.0.0-192.168.255.255,10.0.0.0-10.255.255.255 +charSet=utf-8 +dirMenu=1 +forbidCacheSuffix= +forwarded_ip_header= +keepAliveSecond=30 +maxReqSize=40960 +notFound=404 Not Found

您访问的资源不存在!


ZLMediaKit(git hash:2f2e8c2/2024-06-24T09:28:43+08:00,branch:master,build time:2024-07-05T16:42:51)
+port=8080 +rootPath=./www +sendBufSize=65536 +sslport=8443 +virtualPath= + +[multicast] +addrMax=239.255.255.255 +addrMin=239.0.0.0 +udpTTL=64 + +[protocol] +add_mute_audio=1 +auto_close=0 +continue_push_ms=15000 +enable_audio=1 +enable_fmp4=1 +enable_hls=1 +enable_hls_fmp4=0 +enable_mp4=0 +enable_rtmp=1 +enable_rtsp=1 +enable_ts=1 +fmp4_demand=0 +hls_demand=0 +hls_save_path=./www +modify_stamp=2 +mp4_as_player=0 +mp4_max_second=3600 +mp4_save_path=./www +paced_sender_ms=0 +rtmp_demand=0 +rtsp_demand=0 +ts_demand=0 + +[record] +appName=record +enableFmp4=0 +fastStart=0 +fileBufSize=65536 +fileRepeat=0 +sampleMS=500 + +[rtc] +externIP= +maxNackMS=5000 +max_bitrate=0 +min_bitrate=0 +nackIntervalRatio=1.0 +nackMaxCount=15 +nackMaxMS=3000 +nackMaxSize=2048 +nackRtpSize=8 +port=8000 +preferredCodecA=PCMA,PCMU,opus,mpeg4-generic +preferredCodecV=H264,H265,AV1,VP9,VP8 +rembBitRate=0 +rtpCacheCheckInterval=100 +start_bitrate=0 +tcpPort=8000 +timeoutSec=15 + +[rtmp] +directProxy=1 +enhanced=0 +handshakeSecond=15 +keepAliveSecond=15 +port=1935 +sslport=0 + +[rtp] +audioMtuSize=600 +h264_stap_a=1 +lowLatency=0 +rtpMaxSize=10 +videoMtuSize=1400 + +[rtp_proxy] +dumpDir= +gop_cache=1 +h264_pt=98 +h265_pt=99 +opus_pt=100 +port=10000 +port_range=30000-35000 +ps_pt=96 +rtp_g711_dur_ms=100 +timeoutSec=15 +udp_recv_socket_buffer=4194304 + +[rtsp] +authBasic=0 +directProxy=1 +handshakeSecond=15 +keepAliveSecond=15 +lowLatency=0 +port=8554 +rtpTransportType=-1 +sslport=0 + +[shell] +maxReqSize=1024 +port=0 + +[srt] +latencyMul=4 +pktBufSize=8192 +port=9000 +timeoutSec=5 + +; } --- diff --git a/doc/conf/readme b/doc/conf/readme new file mode 100644 index 0000000..97eaa88 --- /dev/null +++ b/doc/conf/readme @@ -0,0 +1,12 @@ +sudo firewall-cmd --permanent --zone=public --add-port=10000/tcp +sudo firewall-cmd --permanent --zone=public --add-port=10000/udp +sudo firewall-cmd --permanent --zone=public --add-port=1935/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8554/tcp +sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp + + +sudo firewall-cmd --permanent --zone=public --add-port=8000/udp +sudo firewall-cmd --permanent --zone=public --add-port=9000/udp +sudo firewall-cmd --permanent --zone=public --add-port=30000-30050/udp +# 重新载入防火墙规则 +sudo firewall-cmd --reload \ No newline at end of file diff --git a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java index 9241305..e83287b 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java +++ b/src/main/java/com/genersoft/iot/vmp/common/InviteSessionType.java @@ -1,9 +1,24 @@ package com.genersoft.iot.vmp.common; public enum InviteSessionType { + /** + * 实时点播 + */ PLAY, + /** + * 历史回放 + */ PLAYBACK, + /** + * 文件下载 + */ DOWNLOAD, + /** + * 语音广播通知、语音广播应答命令 + */ BROADCAST, + /** + * 语音对讲 + */ TALK } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java index 6c0c050..1421b5a 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorObserver.java @@ -32,6 +32,7 @@ private static Map requestProcessorMap = new ConcurrentHashMap<>(); private static Map responseProcessorMap = new ConcurrentHashMap<>(); + private static Map sessionMap = new ConcurrentHashMap<>(); private static ITimeoutProcessor timeoutProcessor; @Autowired @@ -39,7 +40,9 @@ @Autowired private EventPublisher eventPublisher; - + public void addSession(String ip, ServerTransaction serverTransaction) { + sessionMap.put(ip, serverTransaction); + } /** * 添加 request订阅 * @param method 方法名 @@ -132,8 +135,6 @@ responseEvent.getDialog().delete(); } } - - } /** @@ -178,7 +179,7 @@ // serverTransaction.get // } - + System.out.println("事务断开------------"); // Transaction transaction = null; // System.out.println("processTransactionTerminated"); // if (transactionTerminatedEvent.isServerTransaction()) { @@ -201,5 +202,11 @@ CallIdHeader callId = dialogTerminatedEvent.getDialog().getCallId(); } + public static Map getSessionMap() { + return sessionMap; + } + public static void setSessionMap(Map sessionMap) { + SIPProcessorObserver.sessionMap = sessionMap; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java index ce1074b..9d3c22b 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java @@ -87,6 +87,7 @@ } if (message instanceof Request) { tcpSipProvider.sendRequest((Request)message); + }else if (message instanceof Response) { tcpSipProvider.sendResponse((Response)message); } @@ -98,7 +99,8 @@ return; } if (message instanceof Request) { - sipProvider.sendRequest((Request)message); + Request request = (Request)message; + sipProvider.sendRequest(request); }else if (message instanceof Response) { sipProvider.sendResponse((Response)message); } diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java index f984256..536f221 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java @@ -84,6 +84,7 @@ Request request = null; //请求行 SipURI requestLine = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress()); + //via ArrayList viaHeaders = new ArrayList(); HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory(); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index 5ed3b4e..28a43bc 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -351,6 +351,7 @@ Request request = headerProvider.createInviteRequest(device, channel.getChannelId(), content.toString(), SipUtils.getNewViaTag(), SipUtils.getNewFromTag(), null, ssrcInfo.getSsrc(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, (e -> { streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream()); mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java index f3f7431..89912a9 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/SIPRequestProcessorParent.java @@ -91,7 +91,8 @@ if (msg != null) { response.setReasonPhrase(msg); } - + String dia = response.getDialogId(false); + logger.info("DialogId:{}----------------",dia); if (responseAckExtraParam != null) { if (responseAckExtraParam.sipURI != null && sipRequest.getMethod().equals(Request.INVITE)) { logger.debug("responseSdpAck SipURI: {}:{}", responseAckExtraParam.sipURI.getHost(), responseAckExtraParam.sipURI.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java index 1f0ba53..f6da5e5 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/RegisterRequestProcessor.java @@ -93,6 +93,7 @@ // 注销成功 registerFlag = false; } +// evt.getServerTransaction() FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME); AddressImpl address = (AddressImpl) fromHeader.getAddress(); SipUri uri = (SipUri) address.getURI(); @@ -216,6 +217,8 @@ device.setRegisterTime(DateUtil.getNow()); SipTransactionInfo sipTransactionInfo = new SipTransactionInfo((SIPResponse)response); deviceService.online(device, sipTransactionInfo); + //开流通道 +// evt.getServerTransaction().sendResponse(); } else { logger.info("[注销成功] deviceId: {}->{}" ,deviceId, requestAddress); deviceService.offline(deviceId, "主动注销"); diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java index 85f2da7..53e04d3 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java @@ -6,6 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device; import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; import com.genersoft.iot.vmp.gb28181.bean.RemoteAddressInfo; +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver; import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.IMessageHandler; import com.genersoft.iot.vmp.gb28181.transmit.event.request.impl.message.notify.NotifyMessageHandler; @@ -23,6 +24,7 @@ import javax.sip.InvalidArgumentException; import javax.sip.RequestEvent; +import javax.sip.ServerTransaction; import javax.sip.SipException; import javax.sip.message.Response; import java.text.ParseException; @@ -36,7 +38,7 @@ private final Logger logger = LoggerFactory.getLogger(KeepaliveNotifyMessageHandler.class); private final static String cmdType = "Keepalive"; - + private SIPProcessorObserver sipProcessorObserver; @Autowired private NotifyMessageHandler notifyMessageHandler; @@ -60,6 +62,7 @@ // 未注册的设备不做处理 return; } + System.out.println(evt.getDialog()); SIPRequest request = (SIPRequest) evt.getRequest(); logger.info("[收到心跳] device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); if (userSetting.getGbDeviceOnline() == 0 && !device.isOnLine()) { @@ -76,7 +79,6 @@ logger.info("[收到心跳] 心跳发送过于频繁,已忽略 device: {}, callId: {}", device.getDeviceId(), request.getCallIdHeader().getCallId()); return; } - RemoteAddressInfo remoteAddressInfo = SipUtils.getRemoteAddressFromRequest(request, userSetting.getSipUseSourceIpAsRemoteAddress()); if (!device.getIp().equalsIgnoreCase(remoteAddressInfo.getIp()) || device.getPort() != remoteAddressInfo.getPort() || !request.getRemoteAddress().getHostAddress().equals(device.getLocalIp())) { logger.info("[收到心跳] 设备{}地址变化, 远程地址为: {}:{}", device.getDeviceId(), remoteAddressInfo.getIp(), remoteAddressInfo.getPort()); diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java index 39c67c2..124fee7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java @@ -312,6 +312,7 @@ } } String streamId = String.format("%s_%s", device.getDeviceId(), channelId); + //收流IP SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam()); if (ssrcInfo == null) { callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3cf100c..3146464 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: 123456 + password: casic203 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.37 + ip: 192.168.83.42 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -86,7 +86,7 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: 192.168.83.37 + hook-ip: 192.168.83.42 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 # http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret @@ -166,4 +166,5 @@ # - http://127.0.0.1:8080 # [可选] 日志配置, 一般不需要改 logging: + level.com.genersoft: debug config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90e9ae..d07c6be 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -32,7 +32,7 @@ driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root - password: casic203 + password: 123456 hikari: connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 initialSize: 50 # 连接池初始化连接数 @@ -60,7 +60,7 @@ # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 - ip: 192.168.83.42 + ip: 192.168.83.37 # [可选] 28181服务监听的端口 port: 5060 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) @@ -76,9 +76,9 @@ alarm: true #zlm 默认服务器配置 media: - id: your_server_id + id: your_server_id1 # [必须修改] zlm服务器的内网IP - ip: 192.168.83.42 + ip: 192.168.83.37 # [必须修改] zlm服务器的http.port http-port: 8080 # [可选] 返回流地址时的ip,置空使用 media.ip @@ -86,13 +86,13 @@ # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip sdp-ip: # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip - hook-ip: + hook-ip: 192.168.83.37 # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 http-ssl-port: 1443 # [可选] zlm服务器的hook.admin_params=secret auto-config: true # [可选] zlm服务器的hook.admin_params=secret - secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + secret: qZM6aOlerAs90pXdQAUTU1HSfYeqRvsV # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 rtp: # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 diff --git a/src/main/resources/application-test42.yml b/src/main/resources/application-test42.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/application-test42.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git a/src/main/resources/application-wvp.yml b/src/main/resources/application-wvp.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvp1.yml b/src/main/resources/application-wvp1.yml new file mode 100644 index 0000000..85cc0d6 --- /dev/null +++ b/src/main/resources/application-wvp1.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 111.198.10.15 + # [必须修改] 端口号 + port: 11412 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: ew5T4K3#203lwh + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 22118 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.1.221 + # [可选] 28181服务监听的端口 + port: 22117 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 111.198.10.15 + # [必须修改] zlm服务器的http.port + http-port: 22112 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.1.221 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 22130,22160 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 22120,22125 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application-wvpbr.yml b/src/main/resources/application-wvpbr.yml new file mode 100644 index 0000000..dd456fb --- /dev/null +++ b/src/main/resources/application-wvpbr.yml @@ -0,0 +1,170 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: localhost + # [必须修改] 端口号 + port: 30001 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:30000/wvp_video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: Casic203! + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 30007 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 172.27.46.84 + # [可选] 28181服务监听的端口 + port: 30008 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id + # [必须修改] zlm服务器的内网IP + ip: 172.27.46.84 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 172.27.46.84 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 +# http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30030,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 30025,30029 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 180000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 600000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + level.com.genersoft: debug + config: classpath:logback-spring.xml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6d3f4ba..3230090 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,4 +2,4 @@ application: name: wvp profiles: - active: shentong \ No newline at end of file + active: test \ No newline at end of file diff --git a/src/main/resources/bak/application-test.yml b/src/main/resources/bak/application-test.yml new file mode 100644 index 0000000..4b4841c --- /dev/null +++ b/src/main/resources/bak/application-test.yml @@ -0,0 +1,169 @@ +spring: + # 设置接口超时时间 + mvc: + async: + request-timeout: 20000 + thymeleaf: + cache: false + # [可选]上传文件大小限制 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 100MB + # REDIS数据库配置 + redis: + # [必须修改] Redis服务器IP, REDIS安装在本机的,使用127.0.0.1 + host: 127.0.0.1 + # [必须修改] 端口号 + port: 6379 + # [可选] 数据库 DB + database: 7 + # [可选] 访问密码,若你的redis服务器没有设置密码,就不需要用密码去连接 + password: + # [可选] 超时时间 + timeout: 10000 + # mysql数据源 + datasource: + dynamic: + primary: master + datasource: + master: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/sys-video?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true + username: root + password: casic203 + hikari: + connection-timeout: 20000 # 是客户端等待连接池连接的最大毫秒数 + initialSize: 50 # 连接池初始化连接数 + maximum-pool-size: 200 # 连接池最大连接数 + minimum-idle: 10 # 连接池最小空闲连接数 + idle-timeout: 300000 # 允许连接在连接池中空闲的最长时间(以毫秒为单位) + max-lifetime: 1200000 # 是池中连接关闭后的最长生命周期(以毫秒为单位) +#[可选] WVP监听的HTTP端口, 网页和接口调用都是这个端口 +server: + port: 18080 + # [可选] HTTPS配置, 默认不开启 + ssl: + # [可选] 是否开启HTTPS访问 + enabled: false + # [可选] 证书文件路径,放置在resource/目录下即可,修改xxx为文件名 + key-store: classpath:test.monitor.89iot.cn.jks + # [可选] 证书密码 + key-store-password: gpf64qmw + # [可选] 证书类型, 默认为jks,根据实际修改 + key-store-type: JKS + +# 作为28181服务器的配置 +sip: + # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, + # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 + # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 + # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 + ip: 192.168.83.42 + # [可选] 28181服务监听的端口 + port: 5060 + # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) + # 后两位为行业编码,定义参照附录D.3 + # 3701020049标识山东济南历下区 信息行业接入 + # [可选] + domain: 1101080000 + # [可选] + id: 11010800002000000002 + # [可选] 默认设备认证密码,后续扩展使用设备单独密码, 移除密码将不进行校验1234qwer + password: + # 是否存储alarm信息 + alarm: true +#zlm 默认服务器配置 +media: + id: your_server_id1 + # [必须修改] zlm服务器的内网IP + ip: 192.168.83.42 + # [必须修改] zlm服务器的http.port + http-port: 8080 + # [可选] 返回流地址时的ip,置空使用 media.ip + stream-ip: + # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip + sdp-ip: + # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip + hook-ip: 192.168.83.42 + # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 + http-ssl-port: 1443 + # [可选] zlm服务器的hook.admin_params=secret + auto-config: true + # [可选] zlm服务器的hook.admin_params=secret + secret: vcOhVPzPUgfcvDLLWTFjgBgVNrCkvi7P + # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 + rtp: + # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 + enable: true + # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 + port-range: 30000,30050 # 端口范围 + # [可选] 国标级联在此范围内选择端口发送媒体流, + send-port-range: 56502,56506 # 端口范围 + # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 + record-assist-port: 0 +# [根据业务需求配置] +user-settings: + # [可选] 服务ID,不写则为000000 + server-id: + # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true + auto-apply-play: true + # [可选] 部分设备需要扩展SDP,需要打开此设置 + senior-sdp: true + # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) + save-position-history: false + # 点播/录像回放 等待超时时间,单位:毫秒 + play-timeout: 18000 + # 上级点播等待超时时间,单位:毫秒 + platform-play-timeout: 60000 + # 是否开启接口鉴权 + interface-authentication: false + # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 + interface-authentication-excludes: + - /api/v1/** + # 推流直播是否录制 + record-push-live: false + # 国标是否录制 + record-sip: false + # 是否将日志存储进数据库 + logInDatabase: true + # 使用推流状态作为推流通道状态 + use-pushing-as-status: true + # 使用来源请求ip作为streamIp,当且仅当你只有zlm节点它与wvp在一起的情况下开启 + use-source-ip-as-stream-ip: false + # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 + stream-on-demand: true + # 推流鉴权, 默认开启 + push-authority: false + # 设备上线时是否自动同步通道 + sync-channel-on-device-online: true + # 是否使用设备来源Ip作为回复IP, 不设置则为 false + sip-use-source-ip-as-remote-address: false + # 是否开启sip日志 + sip-log: false + # 是否开启sql日志 + sql-log: false + # 收到ack消息后开始发流,默认false, 回复200ok后直接开始发流 + push-stream-after-ack: true + # 消息通道功能-缺少国标ID是否给所有上级发送消息 + send-to-platforms-when-id-lost: false + # 保持通道状态,不接受notify通道状态变化, 兼容海康平台发送错误消息 + refuse-channel-status-channel-form-notify: true + # 设置notify缓存队列最大长度,超过此长度的数据将返回486 BUSY_HERE,消息丢弃, 默认10000 + max-notify-count-queue: 10000 + # 设备/通道状态变化时发送消息 + device-status-notify: true + # 上级平台点播时不使用上级平台指定的ssrc,使用自定义的ssrc,参考国标文档-点播外域设备媒体流SSRC处理方式 + use-custom-ssrc-for-parent-invite: true + # 国标级联离线后多久重试一次注册 + register-again-after-time: 60 + # 国标续订方式,true为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话 + register-keep-int-dialog: true + # 跨域配置,不配置此项则允许所有跨域请求,配置后则只允许配置的页面的地址请求, 可以配置多个 + allowed-origins: +# - http://localhost:18080 +# - http://127.0.0.1:8080 +# [可选] 日志配置, 一般不需要改 +logging: + config: classpath:logback-spring.xml \ No newline at end of file diff --git "a/\346\211\223\345\214\205/config/wvp-application.yml" "b/\346\211\223\345\214\205/config/wvp-application.yml" index 71b5da2..0ac18cd 100644 --- "a/\346\211\223\345\214\205/config/wvp-application.yml" +++ "b/\346\211\223\345\214\205/config/wvp-application.yml" @@ -117,6 +117,4 @@ # 设备上线时是否自动同步通道 sync-channel-on-device-online: false # 消息通道功能-缺少国标ID是否给所有上级发送消息 - send-to-platforms-when-id-lost: false - - + send-to-platforms-when-id-lost: false \ No newline at end of file