Browse Source

灵州现场sip注册调试

master
wangguangyuan 1 month ago
parent
commit
534a3c4f07
64 changed files with 1142 additions and 16777 deletions
  1. +0
    -331
      hs_err_pid23324.log
  2. +0
    -330
      hs_err_pid53516.log
  3. +42
    -3
      pom.xml
  4. +0
    -65
      proguard.cfg
  5. +0
    -6869
      replay_pid23324.log
  6. +0
    -7104
      replay_pid53516.log
  7. +4
    -0
      src/main/java/com/inspect/tcpserver/TcpserverApplication.java
  8. +50
    -0
      src/main/java/com/inspect/tcpserver/domain/BasedataEqpBookMoMain.java
  9. +15
    -0
      src/main/java/com/inspect/tcpserver/mapper/ICameraMapper.java
  10. +0
    -27
      src/main/java/com/inspect/tcpserver/sip/config/AccountManagerImpl.java
  11. +14
    -0
      src/main/java/com/inspect/tcpserver/sip/feign/InspectIvsFeignService.java
  12. +15
    -0
      src/main/java/com/inspect/tcpserver/sip/feign/InspectMainFeignService.java
  13. +0
    -45
      src/main/java/com/inspect/tcpserver/sip/gb28181/Gb28181PsMuxer.java
  14. +0
    -71
      src/main/java/com/inspect/tcpserver/sip/gb28181/H264AnnexBExtractor.java
  15. +0
    -46
      src/main/java/com/inspect/tcpserver/sip/gb28181/MediaSession.java
  16. +0
    -28
      src/main/java/com/inspect/tcpserver/sip/gb28181/MediaSessionEx.java
  17. +0
    -30
      src/main/java/com/inspect/tcpserver/sip/gb28181/PesPacket.java
  18. +0
    -35
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsHeader.java
  19. +0
    -21
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsMuxer.java
  20. +0
    -10
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsPackHeader.java
  21. +0
    -28
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsPesPacket.java
  22. +0
    -12
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsProgramStreamMap.java
  23. +0
    -12
      src/main/java/com/inspect/tcpserver/sip/gb28181/PsSystemHeader.java
  24. +0
    -60
      src/main/java/com/inspect/tcpserver/sip/gb28181/RtpSender.java
  25. +0
    -84
      src/main/java/com/inspect/tcpserver/sip/gb28181/RtpSenderEx.java
  26. +0
    -74
      src/main/java/com/inspect/tcpserver/sip/gb28181/RtspClient.java
  27. +2
    -0
      src/main/java/com/inspect/tcpserver/sip/items/DeviceInfoItem.java
  28. +0
    -83
      src/main/java/com/inspect/tcpserver/sip/media/Gb28181RtpStreamer.java
  29. +411
    -152
      src/main/java/com/inspect/tcpserver/sip/media/Gb28181StreamService.java
  30. +0
    -45
      src/main/java/com/inspect/tcpserver/sip/media/MediaSession.java
  31. +0
    -26
      src/main/java/com/inspect/tcpserver/sip/media/PsMuxer.java
  32. +0
    -49
      src/main/java/com/inspect/tcpserver/sip/media/RtpSender.java
  33. +0
    -82
      src/main/java/com/inspect/tcpserver/sip/media/RtspPuller.java
  34. +0
    -92
      src/main/java/com/inspect/tcpserver/sip/media/SdpParser.java
  35. +0
    -24
      src/main/java/com/inspect/tcpserver/sip/media/rtcp/RtcpPacket.java
  36. +0
    -13
      src/main/java/com/inspect/tcpserver/sip/media/rtcp/RtcpSrSender.java
  37. +0
    -37
      src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpPacket.java
  38. +0
    -48
      src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpPacketizer.java
  39. +0
    -11
      src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpSender.java
  40. +0
    -31
      src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpTcpSender.java
  41. +0
    -32
      src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpUdpSender.java
  42. +0
    -21
      src/main/java/com/inspect/tcpserver/sip/media/rtsp/H264AnnexBExtractor.java
  43. +0
    -33
      src/main/java/com/inspect/tcpserver/sip/media/rtsp/RtspClient.java
  44. +480
    -52
      src/main/java/com/inspect/tcpserver/sip/service/SipClientService.java
  45. +0
    -230
      src/main/java/com/inspect/tcpserver/sip/service/SipVideoClient.java
  46. +0
    -35
      src/main/java/com/inspect/tcpserver/sip/stream/H264AnnexBExtractor.java
  47. +0
    -35
      src/main/java/com/inspect/tcpserver/sip/stream/MediaSession.java
  48. +0
    -15
      src/main/java/com/inspect/tcpserver/sip/stream/RtpClock.java
  49. +0
    -39
      src/main/java/com/inspect/tcpserver/sip/stream/RtpPacket.java
  50. +0
    -46
      src/main/java/com/inspect/tcpserver/sip/stream/RtpSender.java
  51. +0
    -26
      src/main/java/com/inspect/tcpserver/sip/stream/RtpSocket.java
  52. +0
    -59
      src/main/java/com/inspect/tcpserver/sip/stream/RtspClient.java
  53. +0
    -15
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsConstants.java
  54. +0
    -28
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsMuxer.java
  55. +0
    -27
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsPackHeader.java
  56. +0
    -35
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsPesPacket.java
  57. +0
    -26
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsProgramStreamMap.java
  58. +0
    -21
      src/main/java/com/inspect/tcpserver/sip/stream/ps/PsSystemHeader.java
  59. +2
    -1
      src/main/java/com/inspect/tcpserver/sip/utils/DigestUtil.java
  60. +8
    -1
      src/main/java/com/inspect/tcpserver/sip/utils/SipXmlParser.java
  61. +20
    -20
      src/main/java/com/inspect/tcpserver/tcp/NettyServer.java
  62. +13
    -0
      src/main/java/com/inspect/tcpserver/tcp/NettyServerHandler.java
  63. +21
    -2
      src/main/resources/application-dev.yml
  64. +45
    -0
      src/main/resources/mapper/ICameraMapper.xml

+ 0
- 331
hs_err_pid23324.log View File

@ -1,331 +0,0 @@
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 874896 bytes for Chunk::new
# Possible reasons:
# The system is out of physical RAM or swap space
# In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
# Out of Memory Error (allocation.cpp:390), pid=23324, tid=0x0000000000002980
#
# JRE version: Java(TM) SE Runtime Environment (8.0_151-b12) (build 1.8.0_151-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
--------------- T H R E A D ---------------
Current thread (0x0000000028375000): JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=10624, stack(0x0000000028b40000,0x0000000028c40000)]
Stack: [0x0000000028b40000,0x0000000028c40000]
[error occurred during error reporting (printing stack bounds), id 0xc0000005]
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
Current CompileTask:
C2: 11601 4172 ! 4 org.springframework.util.ClassUtils::getMostSpecificMethod (72 bytes)
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x0000000029a11800 JavaThread "DefaultSipTimerThread" [_thread_blocked, id=27708, stack(0x000000002c720000,0x000000002c820000)]
0x000000002e512800 JavaThread "EventScannerThread" [_thread_blocked, id=47768, stack(0x000000002c200000,0x000000002c300000)]
0x000000002a23e800 JavaThread "logback-2" daemon [_thread_blocked, id=27284, stack(0x000000002bf00000,0x000000002c000000)]
0x00000000295fa800 JavaThread "surefire-forkedjvm-command-thread" daemon [_thread_in_native, id=52020, stack(0x000000002a910000,0x000000002aa10000)]
0x0000000029863800 JavaThread "surefire-forkedjvm-stream-flusher" daemon [_thread_blocked, id=54208, stack(0x000000002a810000,0x000000002a910000)]
0x000000002840b000 JavaThread "Service Thread" daemon [_thread_blocked, id=22148, stack(0x0000000028e40000,0x0000000028f40000)]
0x000000002838a000 JavaThread "C1 CompilerThread3" daemon [_thread_in_native, id=47696, stack(0x0000000028d40000,0x0000000028e40000)]
0x0000000028382000 JavaThread "C2 CompilerThread2" daemon [_thread_in_native, id=49116, stack(0x0000000028c40000,0x0000000028d40000)]
=>0x0000000028375000 JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=10624, stack(0x0000000028b40000,0x0000000028c40000)]
0x0000000028372000 JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=27448, stack(0x0000000028a40000,0x0000000028b40000)]
0x0000000028370000 JavaThread "Attach Listener" daemon [_thread_blocked, id=37208, stack(0x0000000028940000,0x0000000028a40000)]
0x000000002831d000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=55748, stack(0x0000000028840000,0x0000000028940000)]
0x0000000026413000 JavaThread "Finalizer" daemon [_thread_blocked, id=44136, stack(0x00000000286e0000,0x00000000287e0000)]
0x0000000003478000 JavaThread "Reference Handler" daemon [_thread_blocked, id=54276, stack(0x00000000281e0000,0x00000000282e0000)]
0x0000000003383000 JavaThread "main" [_thread_in_vm, id=49520, stack(0x0000000003280000,0x0000000003380000)]
Other Threads:
0x0000000026407000 VMThread [stack: 0x00000000280e0000,0x00000000281e0000] [id=49352]
0x0000000028487000 WatcherThread [stack: 0x0000000028f40000,0x0000000029040000] [id=2304]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event])
[0x000000000327d720] CodeCache_lock - owner thread: 0x0000000000000000
Heap:
PSYoungGen total 235520K, used 91575K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 34% used [0x0000000716300000,0x000000071abba658,0x0000000723400000)
from space 21504K, 79% used [0x0000000723400000,0x00000007244b3840,0x0000000724900000)
to space 14336K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000725e00000)
ParOldGen total 240128K, used 15574K [0x00000005c2800000, 0x00000005d1280000, 0x0000000716300000)
object space 240128K, 6% used [0x00000005c2800000,0x00000005c3735b50,0x00000005d1280000)
Metaspace used 47829K, capacity 50844K, committed 51112K, reserved 1093632K
class space used 6153K, capacity 6710K, committed 6832K, reserved 1048576K
Card table byte_map: [0x0000000012840000,0x0000000013830000] byte_map_base: 0x000000000fa2c000
Marking Bits: (ParMarkBitMap*) 0x0000000058dfd850
Begin Bits: [0x0000000014ad0000, 0x000000001ca30000)
End Bits: [0x000000001ca30000, 0x0000000024990000)
Polling page: 0x00000000031f0000
CodeCache: size=245760Kb used=15852Kb max_used=15852Kb free=229907Kb
bounds [0x0000000003480000, 0x0000000004410000, 0x0000000012480000]
total_blobs=4845 nmethods=4307 adapters=449
compilation: enabled
Compilation events (10 events):
Event: 11.539 Thread 0x000000002838a000 4339 3 java.util.regex.Pattern$Dollar::match (209 bytes)
Event: 11.540 Thread 0x000000002838a000 nmethod 4339 0x00000000043f8a90 code [0x00000000043f8ca0, 0x00000000043f9998]
Event: 11.541 Thread 0x000000002838a000 4340 3 java.beans.PropertyDescriptor::<init> (112 bytes)
Event: 11.541 Thread 0x000000002838a000 nmethod 4340 0x00000000043f9cd0 code [0x00000000043f9ea0, 0x00000000043fa668]
Event: 11.541 Thread 0x000000002838a000 4342 3 org.springframework.util.StringUtils::changeFirstCharacterCase (64 bytes)
Event: 11.542 Thread 0x000000002838a000 nmethod 4342 0x00000000043fa950 code [0x00000000043fab80, 0x00000000043fb868]
Event: 11.542 Thread 0x000000002838a000 4341 ! 3 java.beans.PropertyDescriptor::updateGenericsFor (37 bytes)
Event: 11.544 Thread 0x000000002838a000 nmethod 4341 0x00000000043fbf10 code [0x00000000043fc180, 0x00000000043fd318]
Event: 11.575 Thread 0x000000002838a000 4344 3 org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor::isEligible (61 bytes)
Event: 11.576 Thread 0x000000002838a000 nmethod 4344 0x00000000043fdb90 code [0x00000000043fdd40, 0x00000000043fe468]
GC Heap History (10 events):
Event: 3.061 GC heap before
{Heap before GC invocations=3 (full 1):
PSYoungGen total 152576K, used 6591K [0x0000000716300000, 0x0000000720d00000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 30% used [0x000000071f800000,0x000000071fe6fec0,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 348160K, used 96K [0x00000005c2800000, 0x00000005d7c00000, 0x0000000716300000)
object space 348160K, 0% used [0x00000005c2800000,0x00000005c2818010,0x00000005d7c00000)
Metaspace used 19956K, capacity 21274K, committed 21296K, reserved 1067008K
class space used 2583K, capacity 2859K, committed 2864K, reserved 1048576K
Event: 3.109 GC heap after
Heap after GC invocations=3 (full 1):
PSYoungGen total 152576K, used 0K [0x0000000716300000, 0x0000000720d00000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 0% used [0x000000071f800000,0x000000071f800000,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 170496K, used 6434K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e48910,0x00000005cce80000)
Metaspace used 19956K, capacity 21274K, committed 21296K, reserved 1067008K
class space used 2583K, capacity 2859K, committed 2864K, reserved 1048576K
}
Event: 4.481 GC heap before
{Heap before GC invocations=4 (full 1):
PSYoungGen total 152576K, used 131072K [0x0000000716300000, 0x0000000720d00000, 0x00000007c0000000)
eden space 131072K, 100% used [0x0000000716300000,0x000000071e300000,0x000000071e300000)
from space 21504K, 0% used [0x000000071f800000,0x000000071f800000,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 170496K, used 6434K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e48910,0x00000005cce80000)
Metaspace used 27429K, capacity 29068K, committed 29232K, reserved 1075200K
class space used 3509K, capacity 3826K, committed 3888K, reserved 1048576K
Event: 4.493 GC heap after
Heap after GC invocations=4 (full 1):
PSYoungGen total 152576K, used 10255K [0x0000000716300000, 0x0000000726500000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 47% used [0x000000071e300000,0x000000071ed03ca8,0x000000071f800000)
to space 21504K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000726500000)
ParOldGen total 170496K, used 6442K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e4a910,0x00000005cce80000)
Metaspace used 27429K, capacity 29068K, committed 29232K, reserved 1075200K
class space used 3509K, capacity 3826K, committed 3888K, reserved 1048576K
}
Event: 6.643 GC heap before
{Heap before GC invocations=5 (full 1):
PSYoungGen total 152576K, used 108217K [0x0000000716300000, 0x0000000726500000, 0x00000007c0000000)
eden space 131072K, 74% used [0x0000000716300000,0x000000071c2aa7c8,0x000000071e300000)
from space 21504K, 47% used [0x000000071e300000,0x000000071ed03ca8,0x000000071f800000)
to space 21504K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000726500000)
ParOldGen total 170496K, used 6442K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e4a910,0x00000005cce80000)
Metaspace used 33569K, capacity 35468K, committed 35496K, reserved 1079296K
class space used 4387K, capacity 4770K, committed 4784K, reserved 1048576K
Event: 6.653 GC heap after
Heap after GC invocations=5 (full 1):
PSYoungGen total 228352K, used 10607K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723400000)
from space 14336K, 73% used [0x0000000725000000,0x0000000725a5bd10,0x0000000725e00000)
to space 21504K, 0% used [0x0000000723400000,0x0000000723400000,0x0000000724900000)
ParOldGen total 170496K, used 6450K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e4c910,0x00000005cce80000)
Metaspace used 33569K, capacity 35468K, committed 35496K, reserved 1079296K
class space used 4387K, capacity 4770K, committed 4784K, reserved 1048576K
}
Event: 6.653 GC heap before
{Heap before GC invocations=6 (full 2):
PSYoungGen total 228352K, used 10607K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723400000)
from space 14336K, 73% used [0x0000000725000000,0x0000000725a5bd10,0x0000000725e00000)
to space 21504K, 0% used [0x0000000723400000,0x0000000723400000,0x0000000724900000)
ParOldGen total 170496K, used 6450K [0x00000005c2800000, 0x00000005cce80000, 0x0000000716300000)
object space 170496K, 3% used [0x00000005c2800000,0x00000005c2e4c910,0x00000005cce80000)
Metaspace used 33569K, capacity 35468K, committed 35496K, reserved 1079296K
class space used 4387K, capacity 4770K, committed 4784K, reserved 1048576K
Event: 6.705 GC heap after
Heap after GC invocations=6 (full 2):
PSYoungGen total 228352K, used 0K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723400000)
from space 14336K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000725e00000)
to space 21504K, 0% used [0x0000000723400000,0x0000000723400000,0x0000000724900000)
ParOldGen total 240128K, used 15566K [0x00000005c2800000, 0x00000005d1280000, 0x0000000716300000)
object space 240128K, 6% used [0x00000005c2800000,0x00000005c3733b50,0x00000005d1280000)
Metaspace used 33569K, capacity 35468K, committed 35496K, reserved 1079296K
class space used 4387K, capacity 4770K, committed 4784K, reserved 1048576K
}
Event: 10.679 GC heap before
{Heap before GC invocations=7 (full 2):
PSYoungGen total 228352K, used 214016K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 100% used [0x0000000716300000,0x0000000723400000,0x0000000723400000)
from space 14336K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000725e00000)
to space 21504K, 0% used [0x0000000723400000,0x0000000723400000,0x0000000724900000)
ParOldGen total 240128K, used 15566K [0x00000005c2800000, 0x00000005d1280000, 0x0000000716300000)
object space 240128K, 6% used [0x00000005c2800000,0x00000005c3733b50,0x00000005d1280000)
Metaspace used 46147K, capacity 49000K, committed 49320K, reserved 1091584K
class space used 5914K, capacity 6458K, committed 6576K, reserved 1048576K
Event: 10.702 GC heap after
Heap after GC invocations=7 (full 2):
PSYoungGen total 235520K, used 17102K [0x0000000716300000, 0x0000000725e00000, 0x00000007c0000000)
eden space 214016K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723400000)
from space 21504K, 79% used [0x0000000723400000,0x00000007244b3840,0x0000000724900000)
to space 14336K, 0% used [0x0000000725000000,0x0000000725000000,0x0000000725e00000)
ParOldGen total 240128K, used 15574K [0x00000005c2800000, 0x00000005d1280000, 0x0000000716300000)
object space 240128K, 6% used [0x00000005c2800000,0x00000005c3735b50,0x00000005d1280000)
Metaspace used 46147K, capacity 49000K, committed 49320K, reserved 1091584K
class space used 5914K, capacity 6458K, committed 6576K, reserved 1048576K
}
Deoptimization events (10 events):
Event: 10.234 Thread 0x0000000003383000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000000410c454 method=org.springframework.core.annotation.TypeMappedAnnotations$IsPresent.doWithAnnotations(Ljava/lang/Object;ILjava/lang/Object;[Ljava/lang/annotation/Annotation;)Ljava/lang/Bool
Event: 10.443 Thread 0x0000000003383000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00000000040e0708 method=sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; @ 9
Event: 10.466 Thread 0x0000000003383000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000000431c78c method=org.springframework.core.ResolvableType.resolveType()Lorg/springframework/core/ResolvableType; @ 37
Event: 10.493 Thread 0x0000000003383000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000004335d08 method=org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(Ljava/lang/String;Lorg/springframework/core/ResolvableType;Z)Z @ 559
Event: 11.248 Thread 0x0000000003383000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00000000041f9338 method=org.springframework.core.annotation.TypeMappedAnnotations$IsPresent.doWithAnnotations(Ljava/lang/Object;ILjava/lang/Object;[Ljava/lang/annotation/Annotation;)Ljava/lang/Bool
Event: 11.273 Thread 0x0000000003383000 Uncommon trap: reason=predicate action=maybe_recompile pc=0x0000000003d04da8 method=org.springframework.util.AntPathMatcher.skipSegment(Ljava/lang/String;ILjava/lang/String;)I @ 15
Event: 11.289 Thread 0x0000000003383000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00000000042a3208 method=org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Z @ 21
Event: 11.289 Thread 0x0000000003383000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00000000042a3208 method=org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Z @ 21
Event: 11.289 Thread 0x0000000003383000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00000000042a3208 method=org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Z @ 21
Event: 11.289 Thread 0x0000000003383000 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00000000042a3208 method=org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Z @ 21
Internal exceptions (10 events):
Event: 11.572 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/AwareCustomizer> (0x000000071a63a058) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.579 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': java/lang/ObjectCustomizer> (0x000000071a6758a8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.581 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/web/filter/GenericFilterBeanCustomizer> (0x000000071a6a37a0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp,
Event: 11.583 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/web/filter/OncePerRequestFilterCustomizer> (0x000000071a6d8438) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cp
Event: 11.584 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/web/filter/RequestContextFilterCustomizer> (0x000000071a707a28) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cp
Event: 11.585 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/boot/web/servlet/filter/OrderedRequestContextFilterCustomizer> (0x000000071a740b80) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile
Event: 11.586 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/boot/web/servlet/filter/OrderedFilterCustomizer> (0x000000071a77ae90) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDiction
Event: 11.587 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': javax/servlet/FilterCustomizer> (0x000000071a798008) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.588 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/core/OrderedCustomizer> (0x000000071a7bbc50) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.588 Thread 0x0000000003383000 Exception <a 'java/lang/ClassNotFoundException': javax/servlet/FilterCustomizer> (0x000000071a7d96e0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Events (10 events):
Event: 11.588 loading class javax/servlet/FilterCustomizer
Event: 11.588 loading class javax/servlet/FilterCustomizer done
Event: 11.588 loading class javax/servlet/FilterCustomizer
Event: 11.588 loading class javax/servlet/FilterCustomizer done
Event: 11.588 loading class javax/servlet/FilterCustomizer
Event: 11.588 loading class javax/servlet/FilterCustomizer done
Event: 11.588 loading class org/springframework/beans/factory/BeanNameAwareCustomizer
Event: 11.588 loading class org/springframework/beans/factory/BeanNameAwareCustomizer done
Event: 11.589 loading class org/springframework/beans/factory/BeanNameAwareCustomizer
Event: 11.589 loading class org/springframework/beans/factory/BeanNameAwareCustomizer done
Dynamic libraries:
0x00007ff7d0830000 - 0x00007ff7d0867000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\java.exe
0x00007ffc75130000 - 0x00007ffc75328000 C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffc73470000 - 0x00007ffc7352d000 C:\WINDOWS\System32\KERNEL32.DLL
0x00007ffc72b10000 - 0x00007ffc72e06000 C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffc74f90000 - 0x00007ffc7503e000 C:\WINDOWS\System32\ADVAPI32.dll
0x00007ffc747a0000 - 0x00007ffc7483e000 C:\WINDOWS\System32\msvcrt.dll
0x00007ffc73530000 - 0x00007ffc735cc000 C:\WINDOWS\System32\sechost.dll
0x00007ffc74e60000 - 0x00007ffc74f86000 C:\WINDOWS\System32\RPCRT4.dll
0x00007ffc73e90000 - 0x00007ffc7402e000 C:\WINDOWS\System32\USER32.dll
0x00007ffc72810000 - 0x00007ffc72832000 C:\WINDOWS\System32\win32u.dll
0x00007ffc745a0000 - 0x00007ffc745cc000 C:\WINDOWS\System32\GDI32.dll
0x00007ffc72fd0000 - 0x00007ffc730ea000 C:\WINDOWS\System32\gdi32full.dll
0x00007ffc730f0000 - 0x00007ffc7318d000 C:\WINDOWS\System32\msvcp_win.dll
0x00007ffc72a10000 - 0x00007ffc72b10000 C:\WINDOWS\System32\ucrtbase.dll
0x00007ffc55b30000 - 0x00007ffc55dca000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e\COMCTL32.dll
0x00007ffc746f0000 - 0x00007ffc74720000 C:\WINDOWS\System32\IMM32.DLL
0x000000005a100000 - 0x000000005a1d2000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\msvcr100.dll
0x00000000585e0000 - 0x0000000058e7d000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\server\jvm.dll
0x00007ffc73d20000 - 0x00007ffc73d28000 C:\WINDOWS\System32\PSAPI.DLL
0x00007ffc5c130000 - 0x00007ffc5c157000 C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007ffc696c0000 - 0x00007ffc696ca000 C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007ffc53f30000 - 0x00007ffc53f39000 C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007ffc74730000 - 0x00007ffc7479b000 C:\WINDOWS\System32\WS2_32.dll
0x000000005ae40000 - 0x000000005ae4f000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\verify.dll
0x000000005a0d0000 - 0x000000005a0f9000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\java.dll
0x000000005a080000 - 0x000000005a096000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\zip.dll
0x00007ffc735d0000 - 0x00007ffc73d15000 C:\WINDOWS\System32\SHELL32.dll
0x00007ffc70880000 - 0x00007ffc7101b000 C:\WINDOWS\SYSTEM32\windows.storage.dll
0x00007ffc74160000 - 0x00007ffc744b4000 C:\WINDOWS\System32\combase.dll
0x00007ffc72250000 - 0x00007ffc7227e000 C:\WINDOWS\SYSTEM32\Wldp.dll
0x00007ffc745e0000 - 0x00007ffc7468d000 C:\WINDOWS\System32\SHCORE.dll
0x00007ffc732d0000 - 0x00007ffc73325000 C:\WINDOWS\System32\shlwapi.dll
0x00007ffc72740000 - 0x00007ffc72765000 C:\WINDOWS\SYSTEM32\profapi.dll
0x000000005a030000 - 0x000000005a03d000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\management.dll
0x000000005a060000 - 0x000000005a07a000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\net.dll
0x00007ffc71fb0000 - 0x00007ffc7201a000 C:\WINDOWS\system32\mswsock.dll
0x000000005a040000 - 0x000000005a051000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\nio.dll
0x00007ffc43500000 - 0x00007ffc43517000 C:\WINDOWS\system32\napinsp.dll
0x00007ffc434e0000 - 0x00007ffc434fb000 C:\WINDOWS\system32\pnrpnsp.dll
0x00007ffc6ce00000 - 0x00007ffc6ce15000 C:\WINDOWS\system32\wshbth.dll
0x00007ffc6dc80000 - 0x00007ffc6dc9d000 C:\WINDOWS\system32\NLAapi.dll
0x00007ffc71c50000 - 0x00007ffc71c8b000 C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL
0x00007ffc71ca0000 - 0x00007ffc71d6a000 C:\WINDOWS\SYSTEM32\DNSAPI.dll
0x00007ffc74720000 - 0x00007ffc74728000 C:\WINDOWS\System32\NSI.dll
0x00007ffc433c0000 - 0x00007ffc433d2000 C:\WINDOWS\System32\winrnr.dll
0x00007ffc69690000 - 0x00007ffc6969a000 C:\Windows\System32\rasadhlp.dll
0x00007ffc5ee90000 - 0x00007ffc5ef12000 C:\WINDOWS\System32\fwpuclnt.dll
0x00007ffc72e60000 - 0x00007ffc72e87000 C:\WINDOWS\System32\bcrypt.dll
0x00007ffc721a0000 - 0x00007ffc721b8000 C:\WINDOWS\SYSTEM32\CRYPTSP.dll
0x00007ffc71850000 - 0x00007ffc71884000 C:\WINDOWS\system32\rsaenh.dll
0x00007ffc72700000 - 0x00007ffc7272e000 C:\WINDOWS\SYSTEM32\USERENV.dll
0x00007ffc72f40000 - 0x00007ffc72fc2000 C:\WINDOWS\System32\bcryptprimitives.dll
0x00007ffc721c0000 - 0x00007ffc721cc000 C:\WINDOWS\SYSTEM32\CRYPTBASE.dll
0x00007ffc6acc0000 - 0x00007ffc6acd7000 C:\WINDOWS\SYSTEM32\dhcpcsvc6.DLL
0x00007ffc6a3e0000 - 0x00007ffc6a3fd000 C:\WINDOWS\SYSTEM32\dhcpcsvc.DLL
0x000000005a000000 - 0x000000005a024000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\sunec.dll
0x0000000059ff0000 - 0x0000000059ffb000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\sunmscapi.dll
0x00007ffc72840000 - 0x00007ffc7299e000 C:\WINDOWS\System32\CRYPT32.dll
VM Arguments:
java_command: C:\Users\gabri\AppData\Local\Temp\surefire1519680393763583179\surefirebooter-20250901203912518_3.jar C:\Users\gabri\AppData\Local\Temp\surefire1519680393763583179 2025-09-01T20-39-11_629-jvmRun1 surefire-20250901203912518_1tmp surefire_0-20250901203912518_2tmp
java_class_path (initial): C:\Users\gabri\AppData\Local\Temp\surefire1519680393763583179\surefirebooter-20250901203912518_3.jar
Launcher Type: SUN_STANDARD
Environment Variables:
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_151
USERNAME=gabri
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 12, GenuineIntel
--------------- S Y S T E M ---------------
OS: Windows 10.0 , 64 bit Build 19041 (10.0.19041.3393)
CPU:total 8 (initial active 8) (4 cores per cpu, 2 threads per core) family 6 model 142 stepping 12, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx
Memory: 4k page, physical 33388072k(11602516k free), swap 97777920k(4732k free)
vm_info: Java HotSpot(TM) 64-Bit Server VM (25.151-b12) for windows-amd64 JRE (1.8.0_151-b12), built on Sep 5 2017 19:33:46 by "java_re" with MS VC++ 10.0 (VS2010)
time: Mon Sep 01 20:39:24 2025
elapsed time: 11 seconds (0d 0h 0m 11s)

+ 0
- 330
hs_err_pid53516.log View File

@ -1,330 +0,0 @@
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 1822816 bytes for Chunk::new
# Possible reasons:
# The system is out of physical RAM or swap space
# In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.
#
# Out of Memory Error (allocation.cpp:390), pid=53516, tid=0x0000000000004254
#
# JRE version: Java(TM) SE Runtime Environment (8.0_151-b12) (build 1.8.0_151-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
--------------- T H R E A D ---------------
Current thread (0x000000002627b000): JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=16980, stack(0x0000000028990000,0x0000000028a90000)]
Stack: [0x0000000028990000,0x0000000028a90000]
[error occurred during error reporting (printing stack bounds), id 0xc0000005]
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
Current CompileTask:
C2: 11665 4173 4 org.springframework.core.annotation.TypeMappedAnnotations::get (52 bytes)
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
0x000000002f0c7000 JavaThread "DefaultSipTimerThread" [_thread_blocked, id=43516, stack(0x000000002c550000,0x000000002c650000)]
0x000000002ed14000 JavaThread "EventScannerThread" [_thread_blocked, id=54732, stack(0x000000002c040000,0x000000002c140000)]
0x000000002a027000 JavaThread "logback-2" daemon [_thread_blocked, id=57964, stack(0x000000002ad70000,0x000000002ae70000)]
0x0000000029565000 JavaThread "surefire-forkedjvm-command-thread" daemon [_thread_in_native, id=55436, stack(0x000000002a760000,0x000000002a860000)]
0x0000000029689000 JavaThread "surefire-forkedjvm-stream-flusher" daemon [_thread_blocked, id=56520, stack(0x000000002a660000,0x000000002a760000)]
0x00000000281e5800 JavaThread "Service Thread" daemon [_thread_blocked, id=55744, stack(0x0000000028c90000,0x0000000028d90000)]
0x00000000281da000 JavaThread "C1 CompilerThread3" daemon [_thread_blocked, id=30932, stack(0x0000000028b90000,0x0000000028c90000)]
0x000000002627d000 JavaThread "C2 CompilerThread2" daemon [_thread_in_native, id=23548, stack(0x0000000028a90000,0x0000000028b90000)]
=>0x000000002627b000 JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=16980, stack(0x0000000028990000,0x0000000028a90000)]
0x00000000281c7800 JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=2316, stack(0x0000000028890000,0x0000000028990000)]
0x00000000281c6000 JavaThread "Attach Listener" daemon [_thread_blocked, id=53716, stack(0x0000000028790000,0x0000000028890000)]
0x00000000281c5000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=22688, stack(0x0000000028690000,0x0000000028790000)]
0x0000000028150800 JavaThread "Finalizer" daemon [_thread_blocked, id=44620, stack(0x0000000028530000,0x0000000028630000)]
0x00000000032d8000 JavaThread "Reference Handler" daemon [_thread_blocked, id=56940, stack(0x0000000028030000,0x0000000028130000)]
0x00000000031e3000 JavaThread "main" [_thread_in_vm, id=58208, stack(0x00000000030e0000,0x00000000031e0000)]
Other Threads:
0x0000000026267800 VMThread [stack: 0x0000000027f30000,0x0000000028030000] [id=49952]
0x00000000281ec000 WatcherThread [stack: 0x0000000028d90000,0x0000000028e90000] [id=58300]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap:
PSYoungGen total 241152K, used 50932K [0x0000000716300000, 0x000000072de80000, 0x00000007c0000000)
eden space 219648K, 15% used [0x0000000716300000,0x000000071836d0b8,0x0000000723980000)
from space 21504K, 82% used [0x0000000723980000,0x0000000724ad00b8,0x0000000724e80000)
to space 17920K, 0% used [0x000000072cd00000,0x000000072cd00000,0x000000072de80000)
ParOldGen total 229888K, used 15584K [0x00000005c2800000, 0x00000005d0880000, 0x0000000716300000)
object space 229888K, 6% used [0x00000005c2800000,0x00000005c3738198,0x00000005d0880000)
Metaspace used 47449K, capacity 50356K, committed 50472K, reserved 1093632K
class space used 6105K, capacity 6644K, committed 6704K, reserved 1048576K
Card table byte_map: [0x00000000126a0000,0x0000000013690000] byte_map_base: 0x000000000f88c000
Marking Bits: (ParMarkBitMap*) 0x0000000058dfd850
Begin Bits: [0x0000000014930000, 0x000000001c890000)
End Bits: [0x000000001c890000, 0x00000000247f0000)
Polling page: 0x0000000002d20000
CodeCache: size=245760Kb used=13768Kb max_used=15128Kb free=231991Kb
bounds [0x00000000032e0000, 0x00000000041f0000, 0x00000000122e0000]
total_blobs=4346 nmethods=3808 adapters=449
compilation: enabled
Compilation events (10 events):
Event: 11.607 Thread 0x00000000281da000 4256 2 org.springframework.core.ResolvableType::forType (115 bytes)
Event: 11.608 Thread 0x00000000281da000 nmethod 4256 0x0000000003651390 code [0x0000000003651560, 0x0000000003651ae8]
Event: 11.627 Thread 0x00000000281da000 4257 2 org.springframework.beans.GenericTypeAwarePropertyDescriptor::<init> (323 bytes)
Event: 11.631 Thread 0x00000000281da000 nmethod 4257 0x00000000034b6ed0 code [0x00000000034b71c0, 0x00000000034b81b8]
Event: 11.657 Thread 0x00000000281da000 4258 3 org.springframework.context.support.AbstractApplicationContext::assertBeanFactoryActive (81 bytes)
Event: 11.659 Thread 0x00000000281da000 nmethod 4258 0x00000000034b4190 code [0x00000000034b4400, 0x00000000034b5698]
Event: 11.660 Thread 0x00000000281da000 4259 ! 3 com.sun.proxy.$Proxy11::value (29 bytes)
Event: 11.661 Thread 0x00000000281da000 nmethod 4259 0x00000000033edf90 code [0x00000000033ee120, 0x00000000033ee558]
Event: 11.661 Thread 0x00000000281da000 4260 3 org.springframework.core.annotation.AnnotationTypeMapping::areEquivalent (87 bytes)
Event: 11.663 Thread 0x00000000281da000 nmethod 4260 0x0000000003653ed0 code [0x0000000003654100, 0x00000000036550a8]
GC Heap History (10 events):
Event: 2.872 GC heap before
{Heap before GC invocations=3 (full 1):
PSYoungGen total 152576K, used 6505K [0x0000000716300000, 0x0000000728d00000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 30% used [0x000000071f800000,0x000000071fe5a790,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 348160K, used 96K [0x00000005c2800000, 0x00000005d7c00000, 0x0000000716300000)
object space 348160K, 0% used [0x00000005c2800000,0x00000005c2818010,0x00000005d7c00000)
Metaspace used 19945K, capacity 21266K, committed 21296K, reserved 1067008K
class space used 2581K, capacity 2859K, committed 2864K, reserved 1048576K
Event: 2.917 GC heap after
Heap after GC invocations=3 (full 1):
PSYoungGen total 152576K, used 0K [0x0000000716300000, 0x0000000728d00000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 0% used [0x000000071f800000,0x000000071f800000,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 165888K, used 6416K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e44240,0x00000005cca00000)
Metaspace used 19945K, capacity 21266K, committed 21296K, reserved 1067008K
class space used 2581K, capacity 2859K, committed 2864K, reserved 1048576K
}
Event: 4.223 GC heap before
{Heap before GC invocations=4 (full 1):
PSYoungGen total 152576K, used 131072K [0x0000000716300000, 0x0000000728d00000, 0x00000007c0000000)
eden space 131072K, 100% used [0x0000000716300000,0x000000071e300000,0x000000071e300000)
from space 21504K, 0% used [0x000000071f800000,0x000000071f800000,0x0000000720d00000)
to space 21504K, 0% used [0x000000071e300000,0x000000071e300000,0x000000071f800000)
ParOldGen total 165888K, used 6416K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e44240,0x00000005cca00000)
Metaspace used 27426K, capacity 29060K, committed 29232K, reserved 1075200K
class space used 3509K, capacity 3826K, committed 3888K, reserved 1048576K
Event: 4.231 GC heap after
Heap after GC invocations=4 (full 1):
PSYoungGen total 152576K, used 10275K [0x0000000716300000, 0x0000000726a00000, 0x00000007c0000000)
eden space 131072K, 0% used [0x0000000716300000,0x0000000716300000,0x000000071e300000)
from space 21504K, 47% used [0x000000071e300000,0x000000071ed08fe8,0x000000071f800000)
to space 21504K, 0% used [0x0000000725500000,0x0000000725500000,0x0000000726a00000)
ParOldGen total 165888K, used 6424K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e46240,0x00000005cca00000)
Metaspace used 27426K, capacity 29060K, committed 29232K, reserved 1075200K
class space used 3509K, capacity 3826K, committed 3888K, reserved 1048576K
}
Event: 6.507 GC heap before
{Heap before GC invocations=5 (full 1):
PSYoungGen total 152576K, used 108528K [0x0000000716300000, 0x0000000726a00000, 0x00000007c0000000)
eden space 131072K, 74% used [0x0000000716300000,0x000000071c2f31e8,0x000000071e300000)
from space 21504K, 47% used [0x000000071e300000,0x000000071ed08fe8,0x000000071f800000)
to space 21504K, 0% used [0x0000000725500000,0x0000000725500000,0x0000000726a00000)
ParOldGen total 165888K, used 6424K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e46240,0x00000005cca00000)
Metaspace used 33549K, capacity 35456K, committed 35496K, reserved 1079296K
class space used 4382K, capacity 4770K, committed 4784K, reserved 1048576K
Event: 6.519 GC heap after
Heap after GC invocations=5 (full 1):
PSYoungGen total 234496K, used 10581K [0x0000000716300000, 0x0000000726380000, 0x00000007c0000000)
eden space 219648K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723980000)
from space 14848K, 71% used [0x0000000725500000,0x0000000725f55710,0x0000000726380000)
to space 21504K, 0% used [0x0000000723980000,0x0000000723980000,0x0000000724e80000)
ParOldGen total 165888K, used 6432K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e48240,0x00000005cca00000)
Metaspace used 33549K, capacity 35456K, committed 35496K, reserved 1079296K
class space used 4382K, capacity 4770K, committed 4784K, reserved 1048576K
}
Event: 6.519 GC heap before
{Heap before GC invocations=6 (full 2):
PSYoungGen total 234496K, used 10581K [0x0000000716300000, 0x0000000726380000, 0x00000007c0000000)
eden space 219648K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723980000)
from space 14848K, 71% used [0x0000000725500000,0x0000000725f55710,0x0000000726380000)
to space 21504K, 0% used [0x0000000723980000,0x0000000723980000,0x0000000724e80000)
ParOldGen total 165888K, used 6432K [0x00000005c2800000, 0x00000005cca00000, 0x0000000716300000)
object space 165888K, 3% used [0x00000005c2800000,0x00000005c2e48240,0x00000005cca00000)
Metaspace used 33549K, capacity 35456K, committed 35496K, reserved 1079296K
class space used 4382K, capacity 4770K, committed 4784K, reserved 1048576K
Event: 6.580 GC heap after
Heap after GC invocations=6 (full 2):
PSYoungGen total 234496K, used 0K [0x0000000716300000, 0x0000000726380000, 0x00000007c0000000)
eden space 219648K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723980000)
from space 14848K, 0% used [0x0000000725500000,0x0000000725500000,0x0000000726380000)
to space 21504K, 0% used [0x0000000723980000,0x0000000723980000,0x0000000724e80000)
ParOldGen total 229888K, used 15576K [0x00000005c2800000, 0x00000005d0880000, 0x0000000716300000)
object space 229888K, 6% used [0x00000005c2800000,0x00000005c3736198,0x00000005d0880000)
Metaspace used 33549K, capacity 35456K, committed 35496K, reserved 1079296K
class space used 4382K, capacity 4770K, committed 4784K, reserved 1048576K
}
Event: 11.040 GC heap before
{Heap before GC invocations=7 (full 2):
PSYoungGen total 234496K, used 219648K [0x0000000716300000, 0x0000000726380000, 0x00000007c0000000)
eden space 219648K, 100% used [0x0000000716300000,0x0000000723980000,0x0000000723980000)
from space 14848K, 0% used [0x0000000725500000,0x0000000725500000,0x0000000726380000)
to space 21504K, 0% used [0x0000000723980000,0x0000000723980000,0x0000000724e80000)
ParOldGen total 229888K, used 15576K [0x00000005c2800000, 0x00000005d0880000, 0x0000000716300000)
object space 229888K, 6% used [0x00000005c2800000,0x00000005c3736198,0x00000005d0880000)
Metaspace used 46302K, capacity 49116K, committed 49320K, reserved 1091584K
class space used 5930K, capacity 6458K, committed 6576K, reserved 1048576K
Event: 11.069 GC heap after
Heap after GC invocations=7 (full 2):
PSYoungGen total 241152K, used 17728K [0x0000000716300000, 0x000000072de80000, 0x00000007c0000000)
eden space 219648K, 0% used [0x0000000716300000,0x0000000716300000,0x0000000723980000)
from space 21504K, 82% used [0x0000000723980000,0x0000000724ad00b8,0x0000000724e80000)
to space 17920K, 0% used [0x000000072cd00000,0x000000072cd00000,0x000000072de80000)
ParOldGen total 229888K, used 15584K [0x00000005c2800000, 0x00000005d0880000, 0x0000000716300000)
object space 229888K, 6% used [0x00000005c2800000,0x00000005c3738198,0x00000005d0880000)
Metaspace used 46302K, capacity 49116K, committed 49320K, reserved 1091584K
class space used 5930K, capacity 6458K, committed 6576K, reserved 1048576K
}
Deoptimization events (10 events):
Event: 8.813 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003e8cafc method=java.lang.CharacterDataLatin1.digit(II)I @ 60
Event: 9.387 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003501f58 method=java.lang.AbstractStringBuilder.append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder; @ 1
Event: 9.387 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00000000034bf490 method=java.lang.AbstractStringBuilder.append(Ljava/lang/String;)Ljava/lang/AbstractStringBuilder; @ 1
Event: 9.922 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003da8ae0 method=org.springframework.boot.context.properties.source.ConfigurationPropertyName$ElementsParser.add(IILorg/springframework/boot/context/properties/source/ConfigurationPropertyNa
Event: 9.927 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003f6a5d0 method=org.springframework.core.annotation.TypeMappedAnnotations$IsPresent.doWithAnnotations(Ljava/lang/Object;ILjava/lang/Object;[Ljava/lang/annotation/Annotation;)Ljava/lang/Bool
Event: 10.255 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00000000040ae318 method=org.springframework.core.annotation.AnnotationsScanner.processMethodHierarchy(Ljava/lang/Object;[ILjava/lang/Class;Lorg/springframework/core/annotation/AnnotationsProcessor;
Event: 10.259 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003f839d4 method=org.springframework.core.annotation.TypeMappedAnnotations$IsPresent.doWithAnnotations(Ljava/lang/Object;ILjava/lang/Object;[Ljava/lang/annotation/Annotation;)Ljava/lang/Bool
Event: 10.507 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000003f51848 method=sun.misc.Launcher$AppClassLoader.loadClass(Ljava/lang/String;Z)Ljava/lang/Class; @ 9
Event: 10.552 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000000004173d70 method=org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(Ljava/lang/String;Lorg/springframework/core/ResolvableType;Z)Z @ 559
Event: 11.659 Thread 0x00000000031e3000 Uncommon trap: reason=unstable_if action=reinterpret pc=0x000000000404c56c method=org.springframework.core.annotation.TypeMappedAnnotations$IsPresent.doWithAnnotations(Ljava/lang/Object;ILjava/lang/Object;[Ljava/lang/annotation/Annotation;)Ljava/lang/Bool
Internal exceptions (10 events):
Event: 11.637 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/AwareCustomizer> (0x000000071819e058) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.638 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/InitializingBeanCustomizer> (0x00000007181ca6e0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp
Event: 11.640 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/web/servlet/HandlerMappingCustomizer> (0x00000007181f5468) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, li
Event: 11.642 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/core/OrderedCustomizer> (0x00000007182184d0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.643 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/BeanNameAwareCustomizer> (0x00000007182438c0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, l
Event: 11.645 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/AwareCustomizer> (0x000000071826b220) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.646 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/web/context/ServletContextAwareCustomizer> (0x00000007182980e8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cp
Event: 11.649 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/AwareCustomizer> (0x00000007182bfad8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Event: 11.651 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/context/ApplicationContextAwareCustomizer> (0x00000007182ec790) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cp
Event: 11.652 Thread 0x00000000031e3000 Exception <a 'java/lang/ClassNotFoundException': org/springframework/beans/factory/AwareCustomizer> (0x0000000718314718) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u151\9699\hotspot\src\share\vm\classfile\systemDictionary.cpp, line 210]
Events (10 events):
Event: 11.651 loading class org/springframework/beans/factory/AwareCustomizer done
Event: 11.651 loading class org/springframework/beans/factory/AwareCustomizer
Event: 11.651 loading class org/springframework/beans/factory/AwareCustomizer done
Event: 11.652 loading class org/springframework/beans/factory/AwareCustomizer
Event: 11.652 loading class org/springframework/beans/factory/AwareCustomizer done
Event: 11.659 Thread 0x00000000031e3000 Uncommon trap: trap_request=0xffffff65 fr.pc=0x000000000404c56c
Event: 11.659 Thread 0x00000000031e3000 DEOPT PACKING pc=0x000000000404c56c sp=0x00000000031dc410
Event: 11.659 Thread 0x00000000031e3000 DEOPT UNPACKING pc=0x000000000332582a sp=0x00000000031dc318 mode 2
Event: 11.659 loading class org/springframework/web/servlet/handler/AbstractHandlerMethodMapping
Event: 11.659 loading class org/springframework/web/servlet/handler/AbstractHandlerMethodMapping done
Dynamic libraries:
0x00007ff7d0830000 - 0x00007ff7d0867000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\java.exe
0x00007ffc75130000 - 0x00007ffc75328000 C:\WINDOWS\SYSTEM32\ntdll.dll
0x00007ffc73470000 - 0x00007ffc7352d000 C:\WINDOWS\System32\KERNEL32.DLL
0x00007ffc72b10000 - 0x00007ffc72e06000 C:\WINDOWS\System32\KERNELBASE.dll
0x00007ffc74f90000 - 0x00007ffc7503e000 C:\WINDOWS\System32\ADVAPI32.dll
0x00007ffc747a0000 - 0x00007ffc7483e000 C:\WINDOWS\System32\msvcrt.dll
0x00007ffc73530000 - 0x00007ffc735cc000 C:\WINDOWS\System32\sechost.dll
0x00007ffc74e60000 - 0x00007ffc74f86000 C:\WINDOWS\System32\RPCRT4.dll
0x00007ffc73e90000 - 0x00007ffc7402e000 C:\WINDOWS\System32\USER32.dll
0x00007ffc72810000 - 0x00007ffc72832000 C:\WINDOWS\System32\win32u.dll
0x00007ffc745a0000 - 0x00007ffc745cc000 C:\WINDOWS\System32\GDI32.dll
0x00007ffc72fd0000 - 0x00007ffc730ea000 C:\WINDOWS\System32\gdi32full.dll
0x00007ffc730f0000 - 0x00007ffc7318d000 C:\WINDOWS\System32\msvcp_win.dll
0x00007ffc72a10000 - 0x00007ffc72b10000 C:\WINDOWS\System32\ucrtbase.dll
0x00007ffc55b30000 - 0x00007ffc55dca000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e\COMCTL32.dll
0x00007ffc746f0000 - 0x00007ffc74720000 C:\WINDOWS\System32\IMM32.DLL
0x000000005a100000 - 0x000000005a1d2000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\msvcr100.dll
0x00000000585e0000 - 0x0000000058e7d000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\server\jvm.dll
0x00007ffc73d20000 - 0x00007ffc73d28000 C:\WINDOWS\System32\PSAPI.DLL
0x00007ffc696c0000 - 0x00007ffc696ca000 C:\WINDOWS\SYSTEM32\VERSION.dll
0x00007ffc53f30000 - 0x00007ffc53f39000 C:\WINDOWS\SYSTEM32\WSOCK32.dll
0x00007ffc5c130000 - 0x00007ffc5c157000 C:\WINDOWS\SYSTEM32\WINMM.dll
0x00007ffc74730000 - 0x00007ffc7479b000 C:\WINDOWS\System32\WS2_32.dll
0x000000005ae40000 - 0x000000005ae4f000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\verify.dll
0x000000005a0d0000 - 0x000000005a0f9000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\java.dll
0x000000005a080000 - 0x000000005a096000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\zip.dll
0x00007ffc735d0000 - 0x00007ffc73d15000 C:\WINDOWS\System32\SHELL32.dll
0x00007ffc70880000 - 0x00007ffc7101b000 C:\WINDOWS\SYSTEM32\windows.storage.dll
0x00007ffc74160000 - 0x00007ffc744b4000 C:\WINDOWS\System32\combase.dll
0x00007ffc72250000 - 0x00007ffc7227e000 C:\WINDOWS\SYSTEM32\Wldp.dll
0x00007ffc745e0000 - 0x00007ffc7468d000 C:\WINDOWS\System32\SHCORE.dll
0x00007ffc732d0000 - 0x00007ffc73325000 C:\WINDOWS\System32\shlwapi.dll
0x00007ffc72740000 - 0x00007ffc72765000 C:\WINDOWS\SYSTEM32\profapi.dll
0x000000005a030000 - 0x000000005a03d000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\management.dll
0x000000005a060000 - 0x000000005a07a000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\net.dll
0x00007ffc71fb0000 - 0x00007ffc7201a000 C:\WINDOWS\system32\mswsock.dll
0x000000005a040000 - 0x000000005a051000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\nio.dll
0x00007ffc43500000 - 0x00007ffc43517000 C:\WINDOWS\system32\napinsp.dll
0x00007ffc434e0000 - 0x00007ffc434fb000 C:\WINDOWS\system32\pnrpnsp.dll
0x00007ffc6ce00000 - 0x00007ffc6ce15000 C:\WINDOWS\system32\wshbth.dll
0x00007ffc6dc80000 - 0x00007ffc6dc9d000 C:\WINDOWS\system32\NLAapi.dll
0x00007ffc71c50000 - 0x00007ffc71c8b000 C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL
0x00007ffc71ca0000 - 0x00007ffc71d6a000 C:\WINDOWS\SYSTEM32\DNSAPI.dll
0x00007ffc74720000 - 0x00007ffc74728000 C:\WINDOWS\System32\NSI.dll
0x00007ffc433c0000 - 0x00007ffc433d2000 C:\WINDOWS\System32\winrnr.dll
0x00007ffc69690000 - 0x00007ffc6969a000 C:\Windows\System32\rasadhlp.dll
0x00007ffc5ee90000 - 0x00007ffc5ef12000 C:\WINDOWS\System32\fwpuclnt.dll
0x00007ffc72e60000 - 0x00007ffc72e87000 C:\WINDOWS\System32\bcrypt.dll
0x00007ffc721a0000 - 0x00007ffc721b8000 C:\WINDOWS\SYSTEM32\CRYPTSP.dll
0x00007ffc71850000 - 0x00007ffc71884000 C:\WINDOWS\system32\rsaenh.dll
0x00007ffc72700000 - 0x00007ffc7272e000 C:\WINDOWS\SYSTEM32\USERENV.dll
0x00007ffc72f40000 - 0x00007ffc72fc2000 C:\WINDOWS\System32\bcryptprimitives.dll
0x00007ffc721c0000 - 0x00007ffc721cc000 C:\WINDOWS\SYSTEM32\CRYPTBASE.dll
0x00007ffc6acc0000 - 0x00007ffc6acd7000 C:\WINDOWS\SYSTEM32\dhcpcsvc6.DLL
0x00007ffc6a3e0000 - 0x00007ffc6a3fd000 C:\WINDOWS\SYSTEM32\dhcpcsvc.DLL
0x000000005a000000 - 0x000000005a024000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\sunec.dll
0x0000000059ff0000 - 0x0000000059ffb000 C:\Program Files\Java\jdk1.8.0_151\jre\bin\sunmscapi.dll
0x00007ffc72840000 - 0x00007ffc7299e000 C:\WINDOWS\System32\CRYPT32.dll
VM Arguments:
java_command: C:\Users\gabri\AppData\Local\Temp\surefire1848290997935119688\surefirebooter-20250901204000385_3.jar C:\Users\gabri\AppData\Local\Temp\surefire1848290997935119688 2025-09-01T20-39-59_496-jvmRun1 surefire-20250901204000385_1tmp surefire_0-20250901204000385_2tmp
java_class_path (initial): C:\Users\gabri\AppData\Local\Temp\surefire1848290997935119688\surefirebooter-20250901204000385_3.jar
Launcher Type: SUN_STANDARD
Environment Variables:
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_151
USERNAME=gabri
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 12, GenuineIntel
--------------- S Y S T E M ---------------
OS: Windows 10.0 , 64 bit Build 19041 (10.0.19041.3393)
CPU:total 8 (initial active 8) (4 cores per cpu, 2 threads per core) family 6 model 142 stepping 12, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx
Memory: 4k page, physical 33388072k(11668008k free), swap 97777920k(6560k free)
vm_info: Java HotSpot(TM) 64-Bit Server VM (25.151-b12) for windows-amd64 JRE (1.8.0_151-b12), built on Sep 5 2017 19:33:46 by "java_re" with MS VC++ 10.0 (VS2010)
time: Mon Sep 01 20:40:12 2025
elapsed time: 11 seconds (0d 0h 0m 11s)

+ 42
- 3
pom.xml View File

@ -14,6 +14,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencies>
@ -37,6 +38,24 @@
</exclusion>
</exclusions>
</dependency>
<!-- MySQL 数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId >
@ -136,10 +155,22 @@
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.bytedeco</groupId>-->
<!-- <artifactId>javacv-platform</artifactId>-->
<!-- <version>1.5.9</version>-->
<!-- </dependency>-->
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Cloud LoadBalancer (替代 Ribbon) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
@ -154,6 +185,14 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>


+ 0
- 65
proguard.cfg View File

@ -1,65 +0,0 @@
-target 1.8 ##Specify the java version number
-dontshrink ##Default is enabled, here the shrink is turned off, that is, the unused classes/members are not deleted.
-dontoptimize ##Default is enabled, here to turn off bytecode level optimization
-useuniqueclassmembernames ## Take a unique strategy for confusing the naming of class members
-adaptclassstrings ## After confusing the class name, replace it with a place like Class.forName('className')
-dontnote
-ignorewarnings ## warnings are ignored
-dontwarn
-keep public class * extends org.springframework.boot.web.support.SpringBootServletInitializer
-keepdirectories ## Keep the package structure
-keepclasseswithmembers public class * { public static void main(java.lang.String[]);} ##Maintain the class of the main method and its method name
-keepclassmembers enum * { *; } ##Reserving enumeration members and methods
-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Qualifier *;
@org.springframework.beans.factory.annotation.Value *;
@org.springframework.beans.factory.annotation.Required *;
@org.springframework.context.annotation.Bean *;
@org.springframework.context.annotation.Primary *;
@org.springframework.boot.context.properties.ConfigurationProperties *;
@org.springframework.boot.context.properties.EnableConfigurationProperties *;
@javax.inject.Inject *;
@javax.annotation.PostConstruct *;
@javax.annotation.PreDestroy *;
}
-keep @org.springframework.cache.annotation.EnableCaching class *
-keep @org.springframework.context.annotation.Configuration class *
-keep @org.springframework.boot.context.properties.ConfigurationProperties class *
-keep @org.springframework.boot.autoconfigure.SpringBootApplication class *
-allowaccessmodification
-keepattributes *Annotation*
-keepdirectories com.jayk.springboot.proguard.obfuscationdemo
-keepdirectories org.springframework.boot.autoconfigure
## Do not change names of the getters and setter, if you remove this ##thymeleaf unable to find the getter and setter i.e: ##${greetingDTO.message}
-keepclassmembers class * {
*** get*();
void set*(***);
}
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
public static ** fromValue(java.lang.String);
}
-keepnames class * implements java.io.Serializable
-keepclassmembernames public class com.test.blah.config.liquibase.AsyncSpringLiquibase
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired <fields>;
@org.springframework.beans.factory.annotation.Autowired <methods>;
@org.springframework.security.access.prepost.PreAuthorize <methods>;
}

+ 0
- 6869
replay_pid23324.log
File diff suppressed because it is too large
View File


+ 0
- 7104
replay_pid53516.log
File diff suppressed because it is too large
View File


+ 4
- 0
src/main/java/com/inspect/tcpserver/TcpserverApplication.java View File

@ -2,17 +2,21 @@ package com.inspect.tcpserver;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
@Slf4j
@SpringBootApplication
@EnableAsync
@EnableFeignClients
@MapperScan("com.inspect.tcpserver.mapper")
public class TcpserverApplication {
public static class CustomGenerator implements BeanNameGenerator {


+ 50
- 0
src/main/java/com/inspect/tcpserver/domain/BasedataEqpBookMoMain.java View File

@ -0,0 +1,50 @@
package com.inspect.tcpserver.domain;
import lombok.*;
import java.io.Serializable;
import java.util.List;
@ToString
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BasedataEqpBookMoMain implements Serializable {
private static final long serialVersionUID = 1L;
private Long eqpBookId;
private String stationName;
private String stationCode;
private Long areaId;
private String areaName;
private String patrolDeviceName;
private String patrolDeviceCode;
private String channelCode;
private String channelName;
private String upSystemDeviceCode;
private String deviceModel;
private String manufacturer;
private String useUnit;
private String deviceSource;
private String productionDate;
private String productionCode;
private String isTransport;
private String useMode;
private String videoMode;
private String place;
private String positionX;
private String positionY;
private String positionZ;
private String type;
private String patrolDeviceInfo;
private String robotsCode;
private String ipAddr;
private String port;
private String user;
private String password;
private String mainSystemCode;
private String delFlag;
private String status;
private List<String> algId;
}

+ 15
- 0
src/main/java/com/inspect/tcpserver/mapper/ICameraMapper.java View File

@ -0,0 +1,15 @@
package com.inspect.tcpserver.mapper;
import com.alibaba.fastjson.JSONObject;
import com.inspect.tcpserver.domain.BasedataEqpBookMoMain;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ICameraMapper {
List<BasedataEqpBookMoMain> selectCamera();
BasedataEqpBookMoMain getBasedataEqpBook(String upSystemDeviceCode);
}

+ 0
- 27
src/main/java/com/inspect/tcpserver/sip/config/AccountManagerImpl.java View File

@ -1,27 +0,0 @@
package com.inspect.tcpserver.sip.config;
import gov.nist.javax.sip.clientauthutils.AccountManager;
import gov.nist.javax.sip.clientauthutils.UserCredentials;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.sip.ClientTransaction;
@Component
public class AccountManagerImpl implements AccountManager {
@Value("${sip.username}")
private String username;
@Value("${sip.password}")
private String password;
@Value("${sip.domain}")
private String domain;
@Override
public UserCredentials getCredentials(ClientTransaction clientTransaction, String s) {
return null;
}
}

+ 14
- 0
src/main/java/com/inspect/tcpserver/sip/feign/InspectIvsFeignService.java View File

@ -0,0 +1,14 @@
package com.inspect.tcpserver.sip.feign;
import com.alibaba.fastjson.JSONObject;
import com.inspect.tcpserver.domain.AjaxResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "inspect-ivs",url = "http://199.199.199.154:9906")
public interface InspectIvsFeignService {
@GetMapping({"/api/v1/stream/rtspUrl"})
JSONObject rtspUrl(@RequestParam("cameraCode") String cameraCode);
}

+ 15
- 0
src/main/java/com/inspect/tcpserver/sip/feign/InspectMainFeignService.java View File

@ -0,0 +1,15 @@
package com.inspect.tcpserver.sip.feign;
import com.inspect.tcpserver.domain.AjaxResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "inspect-main",url = "http://199.199.199.104:9901")
public interface InspectMainFeignService {
@GetMapping({"/video/realtime"})
AjaxResult realtime(
@RequestParam("patroldeviceCode") String patrolDeviceCode,
@RequestParam("channelCode") String channelCode);
}

+ 0
- 45
src/main/java/com/inspect/tcpserver/sip/gb28181/Gb28181PsMuxer.java View File

@ -1,45 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
public class Gb28181PsMuxer {
private boolean headerSent = false;
public byte[] muxH264(byte[] annexB, long pts90k) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (!headerSent) {
out.write(PsHeader.packHeader());
out.write(PsHeader.systemHeader());
out.write(PsHeader.psmHeader());
headerSent = true;
}
out.write(PesPacket.buildH264Pes(annexB, pts90k));
return out.toByteArray();
} catch (Exception e) {
return null;
}
}
public byte[] muxOneFrame(byte[] h264, long pts90k) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 每一帧都必须有
out.write(PsHeader.packHeader());
out.write(PsHeader.systemHeader());
out.write(PsHeader.psmHeader());
out.write(PesPacket.buildH264Pes(h264, pts90k));
return out.toByteArray();
} catch (Exception e) {
return null;
}
}
}

+ 0
- 71
src/main/java/com/inspect/tcpserver/sip/gb28181/H264AnnexBExtractor.java View File

@ -1,71 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.javacpp.BytePointer;
import java.nio.ByteBuffer;
public class H264AnnexBExtractor {
private static final byte[] START_CODE = {0, 0, 0, 1};
/**
* AVPacket 中提取 Annex-B H264
*/
public static byte[] extractFromAvPacket(AVPacket pkt) {
if (pkt == null || pkt.size() <= 0 || pkt.data() == null) {
return null;
}
BytePointer ptr = pkt.data();
int size = pkt.size();
byte[] raw = new byte[size];
ptr.get(raw);
// 已经是 Annex-B
if (isAnnexB(raw)) {
return raw;
}
// AVCC Annex-B
return avccToAnnexB(raw);
}
/**
* 判断是否 Annex-B
*/
private static boolean isAnnexB(byte[] data) {
if (data.length < 4) return false;
return data[0] == 0 && data[1] == 0 && data[2] == 0 && data[3] == 1;
}
/**
* AVCClength-prefixed Annex-Bstart code
*/
private static byte[] avccToAnnexB(byte[] avcc) {
ByteBuffer in = ByteBuffer.wrap(avcc);
ByteBuffer out = ByteBuffer.allocate(avcc.length + 64);
while (in.remaining() >= 4) {
int nalLen =
((in.get() & 0xff) << 24) |
((in.get() & 0xff) << 16) |
((in.get() & 0xff) << 8) |
(in.get() & 0xff);
if (nalLen <= 0 || nalLen > in.remaining()) {
break;
}
out.put(START_CODE);
out.put(in.array(), in.position(), nalLen);
in.position(in.position() + nalLen);
}
byte[] annexB = new byte[out.position()];
out.flip();
out.get(annexB);
return annexB;
}
}

+ 0
- 46
src/main/java/com/inspect/tcpserver/sip/gb28181/MediaSession.java View File

@ -1,46 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.net.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class MediaSession {
private final String remoteIp;
private final int remotePort;
private final int ssrc;
private DatagramSocket socket;
private final AtomicBoolean running = new AtomicBoolean(false);
private final RtpSender rtpSender;
private final PsMuxer psMuxer;
public MediaSession(String ip, int port, int ssrc) throws Exception {
this.remoteIp = ip;
this.remotePort = port;
this.ssrc = ssrc;
this.socket = new DatagramSocket();
this.rtpSender = new RtpSender(socket, InetAddress.getByName(ip), port, ssrc);
this.psMuxer = new PsMuxer();
}
public void start() {
running.set(true);
}
public void stop() {
running.set(false);
socket.close();
}
// RTSP Client 回调此方法
public void onH264Frame(byte[] annexB, long pts90k) throws Exception {
if (!running.get()) return;
byte[] ps = psMuxer.muxH264(annexB, pts90k);
rtpSender.send(ps, true);
}
}

+ 0
- 28
src/main/java/com/inspect/tcpserver/sip/gb28181/MediaSessionEx.java View File

@ -1,28 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class MediaSessionEx {
private final RtpSenderEx rtpSenderEx;
private final Gb28181PsMuxer psMuxer;
public MediaSessionEx(String remoteIp, int remotePort, int ssrc) throws Exception {
this.rtpSenderEx = new RtpSenderEx(remoteIp, remotePort, ssrc, 96);
this.psMuxer = new Gb28181PsMuxer();
}
/** RTSP Client 回调 */
public void onH264Frame(byte[] annexB, long pts90k) {
byte[] ps = psMuxer.muxOneFrame(annexB, pts90k);
if (ps != null) {
rtpSenderEx.sendOne(ps, pts90k);
}
}
public void close() {
rtpSenderEx.close();
}
}

+ 0
- 30
src/main/java/com/inspect/tcpserver/sip/gb28181/PesPacket.java View File

@ -1,30 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.io.ByteArrayOutputStream;
public class PesPacket {
public static byte[] buildH264Pes(byte[] h264, long pts90k) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{
0x00,0x00,0x01,(byte)0xE0,
0x00,0x00,
(byte)0x80,(byte)0x80,0x05
});
writePts(out, pts90k);
out.write(h264);
return out.toByteArray();
}
private static void writePts(ByteArrayOutputStream out, long pts) {
long val = pts & 0x1FFFFFFFFL;
out.write((byte)(0x21 | ((val >> 29) & 0x0E)));
out.write((byte)(val >> 22));
out.write((byte)(0x01 | ((val >> 14) & 0xFE)));
out.write((byte)(val >> 7));
out.write((byte)(0x01 | ((val << 1) & 0xFE)));
}
}

+ 0
- 35
src/main/java/com/inspect/tcpserver/sip/gb28181/PsHeader.java View File

@ -1,35 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
public class PsHeader {
public static byte[] packHeader() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBA,
0x44,0x00,0x04,0x00,
0x04,0x01,(byte)0x89,(byte)0xC3,
(byte)0xF8
};
}
public static byte[] systemHeader() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBB,
0x00,0x0C,
(byte)0x80,0x04,
(byte)0xE0,0x07,
(byte)0xE0,(byte)0xC0,
0x20,(byte)0xBD,(byte)0xE0
};
}
public static byte[] psmHeader() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBC,
0x00,0x12,
0x00,0x00,
(byte)0xE0,0x00,
0x1B,0x00,0x00,
0x00,0x00
};
}
}

+ 0
- 21
src/main/java/com/inspect/tcpserver/sip/gb28181/PsMuxer.java View File

@ -1,21 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.io.*;
public class PsMuxer {
private boolean sentHeader = false;
public byte[] muxH264(byte[] annexB, long pts90k) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (!sentHeader) {
out.write(PsPackHeader.packHeader());
out.write(PsSystemHeader.systemHeader());
out.write(PsProgramStreamMap.psm());
sentHeader = true;
}
out.write(PsPesPacket.pes(annexB, pts90k));
return out.toByteArray();
}
}

+ 0
- 10
src/main/java/com/inspect/tcpserver/sip/gb28181/PsPackHeader.java View File

@ -1,10 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
public class PsPackHeader {
public static byte[] packHeader() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBA,
0x44,0x00,0x04,0x00,0x04,0x01,0x00,0x01
};
}
}

+ 0
- 28
src/main/java/com/inspect/tcpserver/sip/gb28181/PsPesPacket.java View File

@ -1,28 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.io.*;
public class PsPesPacket {
public static byte[] pes(byte[] h264, long pts) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{0x00,0x00,0x01,(byte)0xE0});
int len = h264.length + 13;
out.write((len >> 8) & 0xFF);
out.write(len & 0xFF);
out.write(new byte[]{(byte)0x80,(byte)0x80,0x05});
writePts(out, pts);
out.write(h264);
return out.toByteArray();
}
private static void writePts(ByteArrayOutputStream out, long pts) throws IOException {
long val = pts & 0x1FFFFFFFFL;
out.write((byte)(0x21 | (((val >> 30) & 0x07) << 1)));
out.write((byte)((val >> 22) & 0xFF));
out.write((byte)((((val >> 15) & 0x7F) << 1) | 1));
out.write((byte)((val >> 7) & 0xFF));
out.write((byte)(((val & 0x7F) << 1) | 1));
}
}

+ 0
- 12
src/main/java/com/inspect/tcpserver/sip/gb28181/PsProgramStreamMap.java View File

@ -1,12 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
public class PsProgramStreamMap {
public static byte[] psm() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBC,
0x00,0x12,
(byte)0xE0,0x00,0x00,0x00,
0x01,(byte)0xE0,0x00,0x00
};
}
}

+ 0
- 12
src/main/java/com/inspect/tcpserver/sip/gb28181/PsSystemHeader.java View File

@ -1,12 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
public class PsSystemHeader {
public static byte[] systemHeader() {
return new byte[]{
0x00,0x00,0x01,(byte)0xBB,
0x00,0x0C,
(byte)0x80,(byte)0x04,(byte)0xE4,(byte)0x7F,
(byte)0xE0,0x07,(byte)0xE1,0x07
};
}
}

+ 0
- 60
src/main/java/com/inspect/tcpserver/sip/gb28181/RtpSender.java View File

@ -1,60 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.net.*;
import java.util.concurrent.atomic.AtomicInteger;
public class RtpSender {
private static final int RTP_HEADER_SIZE = 12;
private static final int MTU = 1400;
private final DatagramSocket socket;
private final InetAddress remote;
private final int port;
private final int ssrc;
private final AtomicInteger seq = new AtomicInteger(0);
private int timestamp = 0;
public RtpSender(DatagramSocket socket, InetAddress remote, int port, int ssrc) {
this.socket = socket;
this.remote = remote;
this.port = port;
this.ssrc = ssrc;
}
public void send(byte[] ps, boolean marker) throws Exception {
int offset = 0;
while (offset < ps.length) {
int size = Math.min(MTU, ps.length - offset);
byte[] pkt = new byte[RTP_HEADER_SIZE + size];
pkt[0] = (byte) 0x80;
pkt[1] = (byte) (96 | (marker ? 0x80 : 0x00));
pkt[2] = (byte) (seq.get() >> 8);
pkt[3] = (byte) (seq.getAndIncrement());
timestamp += 3600;
pkt[4] = (byte) (timestamp >> 24);
pkt[5] = (byte) (timestamp >> 16);
pkt[6] = (byte) (timestamp >> 8);
pkt[7] = (byte) (timestamp);
pkt[8] = (byte) (ssrc >> 24);
pkt[9] = (byte) (ssrc >> 16);
pkt[10] = (byte) (ssrc >> 8);
pkt[11] = (byte) (ssrc);
System.arraycopy(ps, offset, pkt, RTP_HEADER_SIZE, size);
socket.send(new DatagramPacket(pkt, pkt.length, remote, port));
offset += size;
}
}
}

+ 0
- 84
src/main/java/com/inspect/tcpserver/sip/gb28181/RtpSenderEx.java View File

@ -1,84 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import java.net.*;
import java.util.concurrent.atomic.AtomicInteger;
public class RtpSenderEx {
private final DatagramSocket socket;
private final InetSocketAddress target;
private final int ssrc;
private final int payloadType;
private final AtomicInteger seq = new AtomicInteger(0);
public RtpSenderEx(String ip, int port, int ssrc, int pt) throws Exception {
this.socket = new DatagramSocket();
this.target = new InetSocketAddress(ip, port);
this.ssrc = ssrc;
this.payloadType = pt;
}
// public void send(byte[] ps, long ts90k) {
// int offset = 0;
// while (offset < ps.length) {
// int len = Math.min(1400, ps.length - offset);
// byte[] rtp = buildRtp(ps, offset, len, ts90k);
// socketSend(rtp);
// offset += len;
// }
// }
//
// private byte[] buildRtp(byte[] ps, int off, int len, long ts) {
// byte[] pkt = new byte[12 + len];
// pkt[0] = (byte) 0x80;
// pkt[1] = (byte) payloadType;
// pkt[2] = (byte) (seq.getAndIncrement() >> 8);
// pkt[3] = (byte) seq.get();
// pkt[4] = (byte) (ts >> 24);
// pkt[5] = (byte) (ts >> 16);
// pkt[6] = (byte) (ts >> 8);
// pkt[7] = (byte) ts;
// pkt[8] = (byte) (ssrc >> 24);
// pkt[9] = (byte) (ssrc >> 16);
// pkt[10] = (byte) (ssrc >> 8);
// pkt[11] = (byte) ssrc;
//
// System.arraycopy(ps, off, pkt, 12, len);
// return pkt;
// }
public void sendOne(byte[] ps, long ts90k) {
byte[] rtp = buildRtp(ps, ts90k, true);
socketSend(rtp);
}
private byte[] buildRtp(byte[] payload, long ts, boolean marker) {
byte[] pkt = new byte[12 + payload.length];
pkt[0] = (byte) 0x80;
pkt[1] = (byte) (payloadType | (marker ? 0x80 : 0));
pkt[2] = (byte) (seq.get() >> 8);
pkt[3] = (byte) seq.getAndIncrement();
pkt[4] = (byte) (ts >> 24);
pkt[5] = (byte) (ts >> 16);
pkt[6] = (byte) (ts >> 8);
pkt[7] = (byte) ts;
pkt[8] = (byte) (ssrc >> 24);
pkt[9] = (byte) (ssrc >> 16);
pkt[10] = (byte) (ssrc >> 8);
pkt[11] = (byte) ssrc;
System.arraycopy(payload, 0, pkt, 12, payload.length);
return pkt;
}
private void socketSend(byte[] pkt) {
try {
socket.send(new DatagramPacket(pkt, pkt.length, target));
} catch (Exception ignored) {}
}
public void close() {
socket.close();
}
}

+ 0
- 74
src/main/java/com/inspect/tcpserver/sip/gb28181/RtspClient.java View File

@ -1,74 +0,0 @@
package com.inspect.tcpserver.sip.gb28181;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
public class RtspClient {
private final String url;
private FFmpegFrameGrabber grabber;
private final AtomicBoolean running = new AtomicBoolean(false);
public RtspClient(String url) {
this.url = url;
}
/**
* @param onH264 callback(h264AnnexB, pts90k)
*/
public void start(BiConsumer<byte[], Long> onH264) throws Exception {
grabber = new FFmpegFrameGrabber(url);
grabber.setOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "5000000");
grabber.start();
running.set(true);
new Thread(() -> {
try {
while (running.get()) {
AVPacket pkt = grabber.grabPacket();
if (pkt == null || pkt.size() <= 0) {
continue;
}
// 1️ 提取 Annex-B H264
byte[] annexB = H264AnnexBExtractor.extractFromAvPacket(pkt);
if (annexB == null) {
continue;
}
// 2️ PTS 90kHz
long pts90k = ptsTo90k(pkt.pts(), grabber.getTimestamp());
onH264.accept(annexB, pts90k);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
stop();
}
}, "RtspClient-Thread").start();
}
private long ptsTo90k(long pts, double timeBase) {
if (pts <= 0 || timeBase <= 0) {
return System.nanoTime() / 11_111; // fallback
}
return (long) (pts * timeBase * 90_000);
}
public void stop() {
running.set(false);
try {
if (grabber != null) {
grabber.stop();
grabber.release();
}
} catch (Exception ignored) {
}
}
}

+ 2
- 0
src/main/java/com/inspect/tcpserver/sip/items/DeviceInfoItem.java View File

@ -3,10 +3,12 @@ package com.inspect.tcpserver.sip.items;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 图片抓拍请求信令
*/
@ToString
@Getter
@Setter
public class DeviceInfoItem {


+ 0
- 83
src/main/java/com/inspect/tcpserver/sip/media/Gb28181RtpStreamer.java View File

@ -1,83 +0,0 @@
package com.inspect.tcpserver.sip.media;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.*;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class Gb28181RtpStreamer {
private volatile boolean running = false;
private Thread worker;
public void start(String rtspUrl, String zlmIp, int zlmPort) {
if (running) return;
running = true;
worker = new Thread(() -> pushLoop(rtspUrl, zlmIp, zlmPort));
worker.start();
}
public void stop() {
running = false;
}
private void pushLoop(String rtspUrl, String ip, int port) {
while (running) {
try {
push(rtspUrl, ip, port);
} catch (Exception e) {
log.error("推流断开,5秒重连", e);
sleep(5000);
}
}
}
private void push(String rtspUrl, String ip, int port) throws Exception {
String outputUrl = "rtp://" + ip + ":" + port +
"?pkt_size=1400&localrtpport=50000";
log.info("开始推流 -> {}", outputUrl);
// RTSP
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl);
grabber.setOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "5000000");
grabber.start();
// 推RTP(MPEGTS)
FFmpegFrameRecorder recorder =
new FFmpegFrameRecorder(outputUrl,
grabber.getImageWidth(),
grabber.getImageHeight());
// 关键配置等价ffmpeg命令
recorder.setFormat("rtp_mpegts"); // 核心
recorder.setVideoCodec(grabber.getVideoCodec());
recorder.setFrameRate(grabber.getFrameRate());
recorder.setVideoBitrate(grabber.getVideoBitrate());
// AnnexB + SPS PPS
recorder.setVideoOption("bsf:v", "h264_mp4toannexb");
recorder.setOption("mpegts_flags", "resend_headers");
recorder.start();
Frame frame;
while (running && (frame = grabber.grab()) != null) {
recorder.record(frame);
}
recorder.stop();
grabber.stop();
}
private void sleep(long ms) {
try { Thread.sleep(ms); } catch (Exception ignored) {}
}
}

+ 411
- 152
src/main/java/com/inspect/tcpserver/sip/media/Gb28181StreamService.java View File

@ -1,10 +1,25 @@
package com.inspect.tcpserver.sip.media;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
//import org.bytedeco.ffmpeg.global.avcodec;
//import org.bytedeco.javacv.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class Gb28181StreamService {
@ -14,198 +29,442 @@ public class Gb28181StreamService {
private volatile boolean running = false;
private final String rtspInputUrl = "rtsp://admin:wd19216811@192.168.1.244:554/h264/ch1/sub/av_stream";
private final String rtspInputUrl = "";
private final String rtpOutputUrl= "rtp://192.168.1.116:30000";
public void startPush() {
if (running) {
log.warn("推流已在运行");
return;
}
private Process ffmpegProcess;
running = true;
pushThread = new Thread(() -> {
FFmpegFrameGrabber grabber = null;
FFmpegFrameRecorder recorder = null;
// ==================== 配置项 ====================
@Value("${zlm.http-ip:192.168.1.116}")
private String zlmHttpIp;
try {
// ================= 第一步拉取 RTSP =================
grabber = new FFmpegFrameGrabber("rtsp://admin:wd19216811@192.168.1.244:554/h264/ch1/sub/av_stream");
grabber.setOption("rtsp_transport", "tcp"); // 强制 TCP 拉流
grabber.setOption("fflags", "nobuffer"); // 降低延迟
grabber.setOption("flags", "low_delay");
grabber.setOption("analyzeduration", "2000000"); // 分析时长
grabber.setOption("probesize", "2000000");
grabber.start();
@Value("${zlm.http-port:33380}")
private int zlmHttpPort;
@Value("${zlm.secret:Xg@123456}")
private String zlmSecret;
// ================= 第二步配置 RTP_MPEGTS 输出 =================
String outputUrl = "rtp://192.168.1.116:30000?pkt_size=1400&localrtpport=50000";
// 记录当前推流的流ID用于后续停止
private String currentStreamId;
recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight(), 0); // 0 = 无音频通道
recorder.setFormat("rtp_mpegts"); // 核心rtp_mpegts 封装
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // H264
recorder.setVideoCodecName("copy"); // -c:v copy尽量不重新编码
recorder.setVideoBitrate(grabber.getVideoBitrate()); // 继承源码率
recorder.setFrameRate(grabber.getFrameRate()); // 继承帧率
// 模拟 -bsf:v h264_mp4toannexbJavaCV 会自动处理 Annex-B 输出
recorder.setVideoOption("bsf:v", "h264_mp4toannexb");
public void startPushStream(String sourceUrl, String rtpHost, int rtpPort) {
// 如果已有进程在运行就先停止它
if (ffmpegProcess != null && ffmpegProcess.isAlive()) {
log.warn("ffmpeg process is already running, stopping it first.");
stopPush();
}
// 模拟 -mpegts_flags resend_headers重复发送 TS
//recorder.setFormatOption("mpegts_flags", "resend_headers");
recorder.setFormat("rtp_mpegts");
recorder.setVideoCodecName("copy"); // -c:v copy
// 这里要注意使用静态 FFmpeg 的绝对路径
String ffmpegPath = "/usr/local/bin/ffmpeg";
// 构建 FFmpeg 命令
ProcessBuilder pb = new ProcessBuilder(
ffmpegPath,
"-rtsp_transport", "tcp",
"-i", sourceUrl,
"-c", "copy",
"-an",
"-f", "rtp",
"-rtsp_transport", "tcp",
"rtp://" + rtpHost + ":" + rtpPort
);
pb.redirectErrorStream(true); // 将错误输出合并到标准输出
try {
ffmpegProcess = pb.start();
isPushing = true; // 设置标志
log.info("Started ffmpeg process for pushing stream");
// 创建一个新的线程来读取 FFmpeg 的输出这样可以防止进程阻塞
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
log.info("[FFMPEG] {}", line);
}
} catch (IOException e) {
log.error("Error reading ffmpeg output", e);
}
}).start();
} catch (IOException e) {
log.error("Failed to start ffmpeg process", e);
}
}
// pkt_size localrtpport 通过输出 URL 参数已设置
private boolean addStreamProxy(String streamId, String url) {
try {
String apiUrl = String.format("http://%s:%d/index/api/addStreamProxy", zlmHttpIp, zlmHttpPort);
// 关键 url 进行 URL 编码
String encodedUrl = URLEncoder.encode(url, StandardCharsets.UTF_8.name());
String params = String.format("secret=%s&vhost=__defaultVhost__&app=live&stream=%s&url=%s&timeout_sec=15&add_mute_audio=true",
zlmSecret, streamId, encodedUrl);
String fullUrl = apiUrl + "?" + params;
log.info("addStreamProxy fullUrl {}",fullUrl);
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
String resp = readResponse(conn);
JSONObject json = JSONObject.parseObject(resp);
return json.getInteger("code") == 0;
}
} catch (Exception e) {
log.error("addStreamProxy 异常", e);
}
return false;
}
recorder.start();
/**
* 关闭流代理
*/
public void closeStreamProxy(String streamId) {
try {
String apiUrl = String.format("http://%s:%d/index/api/close_streams", zlmHttpIp, zlmHttpPort);
Map<String, Object> params = new HashMap<>();
params.put("secret", zlmSecret);
params.put("vhost", "__defaultVhost__");
params.put("app", "live");
params.put("stream", streamId);
params.put("force", 1);
String query = buildQueryString(params);
String fullUrl = apiUrl + "?" + query;
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setRequestMethod("GET");
log.info("close_streams 已调用, streamId: {},ResponseCode:{}", streamId, conn.getResponseCode());
} catch (Exception e) {
log.error("closeStreamProxy 异常", e);
}
}
log.info("GB28181 PS over RTP 推流启动:{} -> {}", grabber.getFormat(), outputUrl);
public void startPushToZlmAndSendToPlatform(String sourceUrl, String streamId,
String platformIp, int platformPort,
long ssrc, String payload) {
// 等待 FLV 地址就绪最多 10 500ms 检查一次
// if (!waitForFlvUrlReady(sourceUrl, 10000, 500)) {
// log.error("FLV URL not ready, abort push");
// return;
// }
Frame frame;
while (running && (frame = grabber.grabFrame()) != null) {
recorder.record(frame);
}
if (isPushing) {
log.warn("已有推流进行中,请先停止");
stopPush();
}
} catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
log.error("推流异常", e);
} finally {
try {
if (recorder != null) recorder.stop();
if (grabber != null) grabber.stop();
} catch (Exception e) {
log.error("关闭资源异常", e);
}
running = false;
log.info("推流线程结束");
// 第一步添加流代理
int maxRetries = 5;
boolean proxyAdded = false;
for (int i = 0; i < maxRetries; i++) {
proxyAdded = addStreamProxy(streamId, sourceUrl);
if (proxyAdded) {
break; // 成功退出循环
}
}, "rtp-push-thread");
log.warn("添加流代理失败,第 {} 次重试...", i + 1);
try {
Thread.sleep(500); // 等待 500ms 后重试
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("重试等待被中断");
break;
}
}
pushThread.start();
}
if (!proxyAdded) {
log.error("添加流代理失败(已重试 {} 次),推流终止", maxRetries);
return;
}
log.info("流代理添加成功,streamId: {}", streamId);
public void startPushStream() {
if (isPushing) {
log.warn("Push is already running.");
isPushing = true;
currentStreamId = streamId;
// 等待流就绪轮询 getMediaList
boolean ready = waitForStreamReady(streamId, 20000);
if (!ready) {
log.error("流未就绪,无法启动 startSendRtp");
stopPush(); // 清理资源
return;
}
pushThread = new Thread(() -> {
FFmpegFrameGrabber grabber = null;
FFmpegFrameRecorder recorder = null;
// 第二步调用 startSendRtp ZLM 转发到平台
boolean sendStarted = startZlmSendRtp(streamId, platformIp, platformPort, ssrc, payload);
if (!sendStarted) {
log.error("启动 ZLM 推流到平台失败");
stopPush();
return;
}
log.info("ZLM 已开始向平台 {}:{} 推流 (TCP)", platformIp, platformPort);
}
private boolean waitForStreamReady(String streamId, int maxWaitMs) {
int step = 200;
int waited = 0;
while (waited < maxWaitMs) {
if (isStreamExistInMediaList(streamId)) {
log.info("Stream {} is ready", streamId);
return true;
}
try {
// 初始化 grabber拉取 RTSP
grabber = new FFmpegFrameGrabber(rtspInputUrl);
grabber.setOption("rtsp_transport", "tcp"); // 使用 TCP 传输
grabber.start();
// 初始化 recorder输出 RTP over MPEG-TS
recorder = new FFmpegFrameRecorder(rtpOutputUrl, grabber.getImageWidth(), grabber.getImageHeight(), 0); // 0 表示无音频
recorder.setFormat("rtp_mpegts"); // 输出格式为 rtp_mpegts
// 配置视频编码器libx264
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoOption("preset", "ultrafast"); // 超快预设
recorder.setVideoOption("g", "60"); // GOP 大小 60
recorder.setVideoOption("keyint_min", "60"); // 最小关键帧间隔 60
recorder.setVideoOption("sc_threshold", "0"); // 场景变化阈值 0强制每 GOP 插入 I
recorder.start();
isPushing = true;
log.info("Started pushing stream from {} to {}", rtspInputUrl, rtpOutputUrl);
Frame frame;
while (isPushing && (frame = grabber.grabFrame()) != null) {
recorder.record(frame); // 推送帧
}
Thread.sleep(step);
waited += step;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
log.error("等待流 {} 就绪超时 ({}ms)", streamId, maxWaitMs);
return false;
}
} catch (Exception e) {
log.error("Error during push: {}", e.getMessage(), e);
} finally {
try {
if (recorder != null) recorder.stop();
if (grabber != null) grabber.stop();
} catch (Exception e) {
log.error("Error stopping resources: {}", e.getMessage(), e);
private boolean isStreamExistInMediaList(String streamId) {
try {
String apiUrl = String.format("http://%s:%d/index/api/getMediaList", zlmHttpIp, zlmHttpPort);
String params = String.format("secret=%s", zlmSecret != null ? zlmSecret : "");
String fullUrl = apiUrl + "?" + params;
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(2000);
int code = conn.getResponseCode();
if (code == 200) {
String resp = readResponse(conn);
JSONObject json = JSONObject.parseObject(resp);
if (json.getInteger("code") == 0) {
JSONArray data = json.getJSONArray("data");
if (data != null && !data.isEmpty()) {
for (int i = 0; i < data.size(); i++) {
JSONObject item = data.getJSONObject(i);
if (streamId.equals(item.getString("stream"))) {
return true;
}
}
}
}
isPushing = false;
log.info("Stopped pushing stream.");
}
});
} catch (Exception e) {
log.warn("检查流列表异常", e);
}
return false;
}
pushThread.start();
/**
* 等待 FLV 地址可访问直到超时
* @param url FLV 地址
* @param maxWaitMs 最大等待时间毫秒
* @param checkIntervalMs 每次检查间隔毫秒
* @return true 表示地址可访问false 表示超时
*/
private boolean waitForFlvUrlReady(String url, int maxWaitMs, int checkIntervalMs) {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < maxWaitMs) {
if (isFlvUrlAccessible(url, 2000)) {
log.info("FLV URL is ready: {}", url);
return true;
}
log.info("FLV URL not ready yet, waiting {} ms...", checkIntervalMs);
try {
Thread.sleep(checkIntervalMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
log.warn("FLV URL not ready after {} ms: {}", maxWaitMs, url);
return false;
}
public void startPushStream(String rtspSourceUrl, String rtpHost, int rtpPort) {
if (isPushing) {
log.warn("Push is already running.");
return;
/**
* 检测 FLV 地址是否返回 HTTP 200 OK
* @param url FLV 地址
* @param timeoutMs 单次检测超时毫秒
* @return true 表示可访问
*/
private boolean isFlvUrlAccessible(String url, int timeoutMs) {
HttpURLConnection conn = null;
try {
URL targetUrl = new URL(url);
conn = (HttpURLConnection) targetUrl.openConnection();
conn.setConnectTimeout(timeoutMs);
conn.setReadTimeout(timeoutMs);
conn.setRequestMethod("HEAD");
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
return true;
}
// 如果 HEAD 不被支持尝试 GET 并只读第一个字节
if (responseCode == HttpURLConnection.HTTP_BAD_METHOD) {
conn.disconnect();
conn = (HttpURLConnection) targetUrl.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=0-0");
conn.setConnectTimeout(timeoutMs);
conn.setReadTimeout(timeoutMs);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK ||
conn.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
return true;
}
}
} catch (Exception e) {
log.debug("FLV URL check failed: {}", e.getMessage());
} finally {
if (conn != null) conn.disconnect();
}
return false;
}
pushThread = new Thread(() -> {
FFmpegFrameGrabber grabber = null;
FFmpegFrameRecorder recorder = null;
try {
// 初始化 grabber拉取 RTSP
grabber = new FFmpegFrameGrabber(rtspSourceUrl);
grabber.setOption("rtsp_transport", "tcp"); // 使用 TCP 传输
grabber.start();
// 初始化 recorder输出 RTP over MPEG-TS
String rtpDestUrl = "rtp://" + rtpHost + ":" + rtpPort;
recorder = new FFmpegFrameRecorder(rtpDestUrl, grabber.getImageWidth(), grabber.getImageHeight(), 0); // 0 表示无音频
recorder.setFormat("rtp_mpegts"); // 输出格式为 rtp_mpegts
// 配置视频编码器libx264
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoOption("preset", "ultrafast"); // 超快预设
recorder.setVideoOption("g", "60"); // GOP 大小 60
recorder.setVideoOption("keyint_min", "60"); // 最小关键帧间隔 60
recorder.setVideoOption("sc_threshold", "0"); // 场景变化阈值 0强制每 GOP 插入 I
recorder.start();
isPushing = true;
log.info("Started pushing rtsp stream from {} to {}", rtspSourceUrl, rtpDestUrl);
Frame frame;
while (isPushing && (frame = grabber.grabFrame()) != null) {
recorder.record(frame); // 推送帧
/**
* 调用 ZLM openRtpServer获取本地监听端口
*/
private int openZlmRtpServer(String streamId, long ssrc) {
try {
String apiUrl = String.format("http://%s:%d/index/api/openRtpServer",
zlmHttpIp, zlmHttpPort);
// 参数port=0 ZLM 自动分配enable_tcp=0 只开 UDP
String params = String.format("secret=%s&port=30055&stream_id=%s&tcp_mode=0",
zlmSecret != null ? zlmSecret : "",
streamId);
String fullUrl = apiUrl + "?" + params;
log.info("openRtpServer url:{}",fullUrl);
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setConnectTimeout(3000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
String resp = readResponse(conn);
JSONObject json = JSONObject.parseObject(resp);
if (json.getInteger("code") == 0) {
return json.getInteger("port");
} else {
log.error("openRtpServer 返回错误: {}", json.getString("msg"));
}
} else {
log.error("openRtpServer HTTP 错误: {}", code);
}
} catch (Exception e) {
log.error("openRtpServer 异常", e);
}
return -1;
}
} catch (Exception e) {
log.error("Error during push: {}", e.getMessage(), e);
} finally {
try {
if (recorder != null) recorder.stop();
if (grabber != null) grabber.stop();
} catch (Exception e) {
log.error("Error stopping resources: {}", e.getMessage(), e);
/**
* 调用 ZLM startSendRtp ZLM 将流以 TCP 推送到平台
*/
private boolean startZlmSendRtp(String streamId, String dstIp, int dstPort, long ssrc, String payload) {
try {
String apiUrl = String.format("http://%s:%d/index/api/startSendRtp",
zlmHttpIp, zlmHttpPort);
// 构建参数
Map<String, Object> params = new HashMap<>();
params.put("secret", zlmSecret != null ? zlmSecret : "");
params.put("vhost", "__defaultVhost__");
params.put("app", "live");
params.put("stream", streamId);
params.put("ssrc", ssrc);
params.put("dst_url", dstIp);
params.put("dst_port", dstPort);
params.put("is_udp", 0); // 0=TCP, 1=UDP
params.put("tcp_type", 1); // 1=TCP主动客户端设备主动连接平台
// 可选设置 payload type (pt) 默认 100
params.put("pt", payload);
params.put("use_ps", 1);
params.put("type", 1); // 设置为PS流符合国标要求
params.put("rtcp_send_sr", 1);
params.put("rtcp_send_interval_ms", 5000);
String query = buildQueryString(params);
String fullUrl = apiUrl + "?" + query;
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setConnectTimeout(3000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
String resp = readResponse(conn);
JSONObject json = JSONObject.parseObject(resp);
if (json.getInteger("code") == 0) {
log.info("startSendRtp 成功");
return true;
} else {
log.error("startSendRtp 失败: {}", json.getString("msg"));
}
isPushing = false;
log.info("Stopped pushing stream.");
} else {
log.error("startSendRtp HTTP 错误: {}", code);
}
});
} catch (Exception e) {
log.error("startSendRtp 异常", e);
}
return false;
}
private String buildQueryString(Map<String, Object> params) throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (sb.length() > 0) sb.append("&");
sb.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
sb.append("=");
sb.append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
}
return sb.toString();
}
private void stopZlmSendRtp(String streamId) {
try {
String apiUrl = String.format("http://%s:%d/index/api/stopSendRtp",
zlmHttpIp, zlmHttpPort);
String params = String.format("secret=%s&vhost=__defaultVhost__&app=live&stream=%s",
zlmSecret != null ? zlmSecret : "", streamId);
String fullUrl = apiUrl + "?" + params;
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setRequestMethod("GET");
log.info("stopSendRtp 已调用 streamId:{},ResponseCode:{}", streamId, conn.getResponseCode());
} catch (Exception e) {
log.error("stopSendRtp 异常", e);
}
}
pushThread.start();
private void closeZlmRtpServer(String streamId) {
try {
String apiUrl = String.format("http://%s:%d/index/api/closeRtpServer",
zlmHttpIp, zlmHttpPort);
String params = String.format("secret=%s&schema=rtp&vhost=__defaultVhost__&app=rtp&stream=%s",
zlmSecret != null ? zlmSecret : "", streamId);
String fullUrl = apiUrl + "?" + params;
HttpURLConnection conn = (HttpURLConnection) new URL(fullUrl).openConnection();
conn.setRequestMethod("GET");
conn.getResponseCode();
log.info("closeRtpServer 已调用");
} catch (Exception e) {
log.error("closeRtpServer 异常", e);
}
}
private String readResponse(HttpURLConnection conn) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
}
public void stopPush() {
isPushing = false;
if (pushThread != null) {
try {
pushThread.join(); // 等待线程结束
} catch (InterruptedException e) {
log.error("Error joining push thread: {}", e.getMessage(), e);
}
// 额外清理 ZLM 资源若线程未清理
if (currentStreamId != null) {
stopZlmSendRtp(currentStreamId);
closeStreamProxy(currentStreamId);
// closeZlmRtpServer(currentStreamId);
currentStreamId = null;
}
log.info("{},推流已停止",currentStreamId);
}
public boolean isPushing() {
return isPushing;
}
}
}

+ 0
- 45
src/main/java/com/inspect/tcpserver/sip/media/MediaSession.java View File

@ -1,45 +0,0 @@
package com.inspect.tcpserver.sip.media;
import com.inspect.tcpserver.sip.media.rtcp.RtcpSrSender;
import com.inspect.tcpserver.sip.media.rtp.RtpPacketizer;
import com.inspect.tcpserver.sip.media.rtp.RtpSender;
import com.inspect.tcpserver.sip.media.rtp.RtpTcpSender;
import com.inspect.tcpserver.sip.media.rtp.RtpUdpSender;
import com.inspect.tcpserver.sip.media.rtsp.RtspClient;
public class MediaSession {
private final String remoteIp;
private final int remotePort;
private final long ssrc;
private final boolean tcp;
private final String rtspUrl;
public MediaSession(String remoteIp, int remotePort, long ssrc, boolean tcp, String rtspUrl) {
this.remoteIp = remoteIp;
this.remotePort = remotePort;
this.ssrc = ssrc;
this.tcp = tcp;
this.rtspUrl = rtspUrl;
}
public void start() throws Exception {
RtpSender sender = tcp
? new RtpTcpSender(remoteIp, remotePort)
: new RtpUdpSender(remoteIp, remotePort);
// 先发 RTCP SRB.6.1
RtcpSrSender.send(sender.getControlStream(), ssrc);
// 启动 RTSP 拉流 RTP
RtspClient rtspClient = new RtspClient(rtspUrl);
rtspClient.start(nal -> {
try {
RtpPacketizer.packetizerAndSend(nal, ssrc, sender);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}

+ 0
- 26
src/main/java/com/inspect/tcpserver/sip/media/PsMuxer.java View File

@ -1,26 +0,0 @@
package com.inspect.tcpserver.sip.media;
import java.io.ByteArrayOutputStream;
public class PsMuxer {
public byte[] pack(byte[] h264) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// PS header (简化版)
out.write(new byte[]{
0x00,0x00,0x01,(byte)0xBA,
0x44,0x00,0x04,0x00,0x04,0x01,(byte)0x89,(byte)0xC3,(byte)0xF8
});
// PES header
out.write(new byte[]{
0x00,0x00,0x01,(byte)0xE0,
0x00,0x00
});
out.write(h264);
return out.toByteArray();
}
}

+ 0
- 49
src/main/java/com/inspect/tcpserver/sip/media/RtpSender.java View File

@ -1,49 +0,0 @@
package com.inspect.tcpserver.sip.media;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class RtpSender {
private DatagramSocket socket;
private InetAddress address;
private int port;
private int seq = 0;
private long timestamp = 0;
private int ssrc;
public RtpSender(String ip, int port, int ssrc) throws Exception {
this.socket = new DatagramSocket();
this.address = InetAddress.getByName(ip);
this.port = port;
this.ssrc = ssrc;
}
public void send(byte[] payload, boolean mark) throws Exception {
byte[] rtp = new byte[12 + payload.length];
rtp[0] = (byte) 0x80;
rtp[1] = (byte) (96 | (mark ? 0x80 : 0));
rtp[2] = (byte) (seq >> 8);
rtp[3] = (byte) (seq);
seq++;
timestamp += 3600; // 90k时钟
rtp[4] = (byte) (timestamp >> 24);
rtp[5] = (byte) (timestamp >> 16);
rtp[6] = (byte) (timestamp >> 8);
rtp[7] = (byte) (timestamp);
rtp[8] = (byte) (ssrc >> 24);
rtp[9] = (byte) (ssrc >> 16);
rtp[10] = (byte) (ssrc >> 8);
rtp[11] = (byte) (ssrc);
System.arraycopy(payload, 0, rtp, 12, payload.length);
socket.send(new DatagramPacket(rtp, rtp.length, address, port));
}
}

+ 0
- 82
src/main/java/com/inspect/tcpserver/sip/media/RtspPuller.java View File

@ -1,82 +0,0 @@
package com.inspect.tcpserver.sip.media;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import java.nio.ByteBuffer;
import java.io.ByteArrayOutputStream;
public class RtspPuller {
public interface StreamCallback {
void onH264(byte[] data, boolean keyFrame) throws Exception;
}
private final String rtspUrl;
public RtspPuller(String rtspUrl) {
this.rtspUrl = rtspUrl;
}
public void start(StreamCallback callback) throws Exception {
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl);
grabber.setOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "5000000");
grabber.start();
System.out.println("RTSP connected: " + rtspUrl);
AVPacket pkt;
while (true) {
pkt = grabber.grabPacket();
if (pkt == null || pkt.size() <= 0)
continue;
if (pkt.stream_index() != grabber.getVideoStream())
continue;
// ===== 读取裸数据 =====
ByteBuffer buffer = pkt.data().asByteBuffer();
buffer.rewind();
byte[] avcc = new byte[pkt.size()];
buffer.get(avcc);
// ===== AVCC AnnexB 转换 =====
byte[] annexb = avccToAnnexB(avcc);
boolean keyFrame = (pkt.flags() & 1) != 0;
callback.onH264(annexb, keyFrame);
}
}
/**
* AVCC AnnexB (核心函数)
*/
private byte[] avccToAnnexB(byte[] avcc) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
while (offset < avcc.length) {
int naluSize =
((avcc[offset] & 0xff) << 24) |
((avcc[offset+1] & 0xff) << 16) |
((avcc[offset+2] & 0xff) << 8) |
(avcc[offset+3] & 0xff);
offset += 4;
// 写入起始码 00 00 00 01
out.write(new byte[]{0,0,0,1});
out.write(avcc, offset, naluSize);
offset += naluSize;
}
return out.toByteArray();
}
}

+ 0
- 92
src/main/java/com/inspect/tcpserver/sip/media/SdpParser.java View File

@ -1,92 +0,0 @@
package com.inspect.tcpserver.sip.media;
import java.util.StringTokenizer;
public class SdpParser {
public static SdpInfo parse(String sdp) {
SdpInfo info = new SdpInfo();
String[] lines = sdp.split("\\r?\\n");
for (String line : lines) {
line = line.trim();
if (line.isEmpty()) continue;
// ---------- 会话级 ----------
if (line.startsWith("c=")) {
// c=IN IP4 192.168.1.116
String[] parts = line.split("\\s+");
if (parts.length >= 3) {
info.setRemoteIp(parts[2]);
}
}
// ---------- media ----------
else if (line.startsWith("m=video")) {
// m=video 50000 TCP/AVP 98
StringTokenizer st = new StringTokenizer(line);
st.nextToken(); // m=video
info.setMediaPort(Integer.parseInt(st.nextToken()));
String proto = st.nextToken();
if (proto.toUpperCase().contains("TCP")) {
info.setTransport(SdpInfo.Transport.RTP_TCP);
} else {
info.setTransport(SdpInfo.Transport.RTP_UDP);
}
info.setPayloadType(Integer.parseInt(st.nextToken()));
}
// ---------- rtpmap ----------
else if (line.startsWith("a=rtpmap")) {
// a=rtpmap:98 H264/90000
String value = line.substring("a=rtpmap:".length());
String[] parts = value.split("\\s+");
if (parts.length == 2) {
String[] codecInfo = parts[1].split("/");
info.setCodec(codecInfo[0]);
info.setClockRate(Integer.parseInt(codecInfo[1]));
}
}
// ---------- setup ----------
else if (line.startsWith("a=setup:")) {
info.setSetup(line.substring("a=setup:".length()));
}
// ---------- connection ----------
else if (line.startsWith("a=connection:")) {
info.setConnection(line.substring("a=connection:".length()));
}
// ---------- fmtp ----------
else if (line.startsWith("a=fmtp:")) {
// 可留作扩展
info.putAttribute("fmtp", line);
}
// ---------- y= (SSRC) ----------
else if (line.startsWith("y=")) {
// y=0700000038
info.setSsrc(Long.parseLong(line.substring(2)));
}
// ---------- 其他属性 ----------
else if (line.startsWith("a=")) {
int idx = line.indexOf(':');
if (idx > 0) {
info.putAttribute(
line.substring(2, idx),
line.substring(idx + 1)
);
}
}
}
return info;
}
}

+ 0
- 24
src/main/java/com/inspect/tcpserver/sip/media/rtcp/RtcpPacket.java View File

@ -1,24 +0,0 @@
package com.inspect.tcpserver.sip.media.rtcp;
import java.nio.ByteBuffer;
public class RtcpPacket {
public static byte[] buildSr(long ssrc) {
ByteBuffer buf = ByteBuffer.allocate(28);
buf.put((byte) 0x80);
buf.put((byte) 200);
buf.putShort((short) 6);
buf.putInt((int) ssrc);
long ntp = System.currentTimeMillis() * 2208988800L;
buf.putLong(ntp);
buf.putInt(0);
buf.putInt(0);
buf.putInt(0);
return buf.array();
}
}

+ 0
- 13
src/main/java/com/inspect/tcpserver/sip/media/rtcp/RtcpSrSender.java View File

@ -1,13 +0,0 @@
package com.inspect.tcpserver.sip.media.rtcp;
import java.io.OutputStream;
public class RtcpSrSender {
public static void send(OutputStream out, long ssrc) throws Exception {
byte[] sr = RtcpPacket.buildSr(ssrc);
out.write(sr);
out.flush();
}
}

+ 0
- 37
src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpPacket.java View File

@ -1,37 +0,0 @@
package com.inspect.tcpserver.sip.media.rtp;
public class RtpPacket {
public static byte[] build(
int payloadType,
int seq,
int timestamp,
long ssrc,
byte[] payload,
boolean marker
) {
int headerSize = 12;
byte[] packet = new byte[headerSize + payload.length];
packet[0] = (byte) 0x80;
packet[1] = (byte) (payloadType & 0x7F);
if (marker) {
packet[1] |= 0x80;
}
packet[2] = (byte) (seq >> 8);
packet[3] = (byte) seq;
packet[4] = (byte) (timestamp >> 24);
packet[5] = (byte) (timestamp >> 16);
packet[6] = (byte) (timestamp >> 8);
packet[7] = (byte) timestamp;
packet[8] = (byte) (ssrc >> 24);
packet[9] = (byte) (ssrc >> 16);
packet[10] = (byte) (ssrc >> 8);
packet[11] = (byte) ssrc;
System.arraycopy(payload, 0, packet, headerSize, payload.length);
return packet;
}
}

+ 0
- 48
src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpPacketizer.java View File

@ -1,48 +0,0 @@
package com.inspect.tcpserver.sip.media.rtp;
public class RtpPacketizer {
private static final int MTU = 1400;
private static int seq = 0;
private static int timestamp = 0;
public static void packetizerAndSend(byte[] nal, long ssrc, RtpSender sender) throws Exception {
if (nal.length <= MTU) {
byte[] pkt = RtpPacket.build(
98, seq++, timestamp, ssrc, nal, true
);
sender.send(pkt, pkt.length);
} else {
// FU-A
int nalHeader = nal[0] & 0xFF;
int fuIndicator = (nalHeader & 0xE0) | 28;
int fuHeaderStart = 0x80 | (nalHeader & 0x1F);
int fuHeaderMid = nalHeader & 0x1F;
int fuHeaderEnd = 0x40 | (nalHeader & 0x1F);
int offset = 1;
boolean start = true;
while (offset < nal.length) {
int size = Math.min(MTU - 2, nal.length - offset);
byte[] payload = new byte[size + 2];
payload[0] = (byte) fuIndicator;
payload[1] = (byte) (start ? fuHeaderStart :
(offset + size >= nal.length ? fuHeaderEnd : fuHeaderMid));
System.arraycopy(nal, offset, payload, 2, size);
offset += size;
start = false;
byte[] pkt = RtpPacket.build(
98, seq++, timestamp, ssrc, payload, offset >= nal.length
);
sender.send(pkt, pkt.length);
}
}
timestamp += 3600;
}
}

+ 0
- 11
src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpSender.java View File

@ -1,11 +0,0 @@
package com.inspect.tcpserver.sip.media.rtp;
import java.io.OutputStream;
public interface RtpSender {
void send(byte[] data, int len) throws Exception;
OutputStream getControlStream();
}

+ 0
- 31
src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpTcpSender.java View File

@ -1,31 +0,0 @@
package com.inspect.tcpserver.sip.media.rtp;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
public class RtpTcpSender implements RtpSender {
private final Socket socket;
private final OutputStream out;
public RtpTcpSender(String ip, int port) throws Exception {
this.socket = new Socket(ip, port);
this.out = socket.getOutputStream();
}
@Override
public void send(byte[] data, int len) throws Exception {
ByteBuffer buf = ByteBuffer.allocate(len + 2);
buf.putShort((short) len);
buf.put(data, 0, len);
out.write(buf.array());
out.flush();
}
@Override
public OutputStream getControlStream() {
return out;
}
}

+ 0
- 32
src/main/java/com/inspect/tcpserver/sip/media/rtp/RtpUdpSender.java View File

@ -1,32 +0,0 @@
package com.inspect.tcpserver.sip.media.rtp;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class RtpUdpSender implements RtpSender {
private final DatagramSocket socket;
private final InetAddress addr;
private final int port;
public RtpUdpSender(String ip, int port) throws Exception {
this.socket = new DatagramSocket();
this.addr = InetAddress.getByName(ip);
this.port = port;
}
@Override
public void send(byte[] data, int len) throws Exception {
DatagramPacket packet = new DatagramPacket(data, len, addr, port);
socket.send(packet);
}
@Override
public OutputStream getControlStream() {
return new ByteArrayOutputStream(); // UDP 场景可忽略
}
}

+ 0
- 21
src/main/java/com/inspect/tcpserver/sip/media/rtsp/H264AnnexBExtractor.java View File

@ -1,21 +0,0 @@
package com.inspect.tcpserver.sip.media.rtsp;
import org.bytedeco.javacv.Frame;
import java.nio.ByteBuffer;
public class H264AnnexBExtractor {
public static byte[] extract(Frame frame) {
if (frame.image == null || frame.image.length == 0) {
return null;
}
ByteBuffer buffer = (ByteBuffer) frame.image[0];
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
return data;
}
}

+ 0
- 33
src/main/java/com/inspect/tcpserver/sip/media/rtsp/RtspClient.java View File

@ -1,33 +0,0 @@
package com.inspect.tcpserver.sip.media.rtsp;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import java.util.function.Consumer;
public class RtspClient {
private final String url;
public RtspClient(String url) {
this.url = url;
}
public void start(Consumer<byte[]> onNal) throws Exception {
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(url);
grabber.setOption("rtsp_transport", "tcp");
grabber.start();
while (true) {
Frame frame = grabber.grabImage();
if (frame == null || frame.image == null) {
continue;
}
byte[] annexB = H264AnnexBExtractor.extract(frame);
if (annexB != null) {
onNal.accept(annexB);
}
}
}
}

+ 480
- 52
src/main/java/com/inspect/tcpserver/sip/service/SipClientService.java View File

@ -1,16 +1,21 @@
package com.inspect.tcpserver.sip.service;
import com.inspect.tcpserver.sip.media.Gb28181RtpStreamer;
import com.alibaba.fastjson.JSONObject;
import com.inspect.tcpserver.domain.BasedataEqpBookMoMain;
import com.inspect.tcpserver.mapper.ICameraMapper;
import com.inspect.tcpserver.sip.feign.InspectIvsFeignService;
import com.inspect.tcpserver.sip.feign.InspectMainFeignService;
import com.inspect.tcpserver.sip.media.Gb28181StreamService;
import com.inspect.tcpserver.sip.media.InviteSdpInfo;
import com.inspect.tcpserver.sip.registry.SipEventRegistry;
import com.inspect.tcpserver.sip.registry.SipEventRegistry;
import com.inspect.tcpserver.sip.utils.DigestUtil;
import com.inspect.tcpserver.sip.utils.Gb28181SdpParser;
import com.inspect.tcpserver.sip.utils.SipXmlEnvelope;
import com.inspect.tcpserver.sip.utils.SipXmlParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@ -42,6 +47,13 @@ import java.util.concurrent.atomic.AtomicInteger;
@ConditionalOnProperty(name = "sip.enable", havingValue = "true")
public class SipClientService implements SipListener {
@Autowired
private ICameraMapper cameraMapper;
@Autowired
private InspectMainFeignService mainFeignService;
@Autowired
private InspectIvsFeignService ivsFeignService;
private SipFactory sipFactory;
private SipStack sipStack;
private SipProvider sipProvider;
@ -86,21 +98,36 @@ public class SipClientService implements SipListener {
@Value("${sip.expires}")
private int expires;
@Value("${zlm.http-ip:127.0.0.1}")
private String zlmHttpIp;
@Value("${zlm.http-port:33380}")
private int zlmHttpPort;
@Value("${zlm.media-server-id:192.168.1.116}") // ZLM服务器ID对应配置文件中的 id
private String zlmServerId;
private String rtpStreamHost= "192.168.1.116";
private int rtpStreamPort= 30000;
private long rtpStreamSSRC = 12345678;
private String payload = "100";
private ClientTransaction lastRegisterTransaction;
private Timer refreshTimer = new Timer(true);
private String fromTag = Long.toHexString(System.currentTimeMillis());
private AtomicInteger cSeqCounter = new AtomicInteger(1);
private AtomicInteger registerCSeqCounter = new AtomicInteger(1);
// 新增保存第一次注册的 Call-ID用于认证重发和刷新
private CallIdHeader initialCallId;
private int authRetryCount = 0; // 认证重试次数
private static final int MAX_AUTH_RETRIES = 3; // 最大重试次数
@Autowired
Gb28181StreamService streamService;
@Autowired
Gb28181RtpStreamer gb28181RtpStreamer;
private static final String[] IP_SERVICES = {
"https://api.ipify.org",
@ -208,7 +235,7 @@ public class SipClientService implements SipListener {
addressFactory = sipFactory.createAddressFactory();
messageFactory = sipFactory.createMessageFactory();
// 获取本地实际IP地址不是0.0.0.0
if (localIp == null || localIp.equals("0.0.0.0")) {
if (localIp == null) {
try {
// 尝试获取公网IP
String publicIp = getPublicIp();
@ -244,7 +271,7 @@ public class SipClientService implements SipListener {
sipProvider = sipStack.createSipProvider(lp);
sipProvider.addSipListener(this);
sendRegister(null);
sendRegister(null, null);
}
public static String getPublicIp() {
@ -288,7 +315,7 @@ public class SipClientService implements SipListener {
return null;
}
public void sendRegister(AuthorizationHeader authHeader) throws Exception {
public void sendRegister(AuthorizationHeader authHeader, CallIdHeader existingCallId) throws Exception {
SipURI requestUri = addressFactory.createSipURI(null, domain);
requestUri.setTransportParam(transport.toUpperCase());
requestUri.setPort(port);
@ -298,8 +325,19 @@ public class SipClientService implements SipListener {
Address toAddress = addressFactory.createAddress(username, addressFactory.createSipURI(username, domain));
ToHeader toHeader = headerFactory.createToHeader(toAddress, null);
CallIdHeader callId = sipProvider.getNewCallId();
CSeqHeader cSeq = headerFactory.createCSeqHeader(1L, Request.REGISTER);
CallIdHeader callId;
if (existingCallId != null) {
callId = existingCallId;
} else {
callId = sipProvider.getNewCallId();
// 保存 initialCallId用于后续认证和刷新
if (initialCallId == null) {
initialCallId = callId;
}
}
registerCSeqCounter.incrementAndGet();
// CallIdHeader callId = sipProvider.getNewCallId();
CSeqHeader cSeq = headerFactory.createCSeqHeader(registerCSeqCounter.get(), Request.REGISTER);
MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);
//String natIp = "172.19.1.1"; // 避免硬编码用环境变量注入
@ -311,7 +349,9 @@ public class SipClientService implements SipListener {
//SipURI contactUri = addressFactory.createSipURI(username, localIp);
SipURI contactUri = addressFactory.createSipURI(username, natIp);
//contactUri.setPort(localPort);
contactUri.setPort(natPort);
if (natPort > 0) {
contactUri.setPort(natPort);
}
contactUri.setTransportParam(transport.toUpperCase());
contactUri.setParameter("deviceid", "123456");
@ -495,13 +535,17 @@ public class SipClientService implements SipListener {
CSeqHeader cSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
if (cSeqHeader == null) return;
String method = cSeqHeader.getMethod();
log.info("Received response: {} {}, method: {}", response.getStatusCode(), response.getReasonPhrase(), method);
log.info("Response:\n {}", response);
// log.info("Received response: {} {}, method: {}", response.getStatusCode(), response.getReasonPhrase(), method);
// log.info("Response:\n {}", response);
try {
if (Request.REGISTER.equalsIgnoreCase(method)) {
if (status == 401 || status == 407) {
log.info("Received 401/407, attempt auth...");
// if (authRetryCount >= MAX_AUTH_RETRIES) {
// log.error("Authentication failed after {} retries, giving up", MAX_AUTH_RETRIES);
// return;
// }
// authRetryCount++;
WWWAuthenticateHeader wwwAuth = (WWWAuthenticateHeader) response.getHeader(WWWAuthenticateHeader.NAME);
if (wwwAuth == null) {
log.error("No WWW-Authenticate header found, cannot authenticate");
@ -511,12 +555,15 @@ public class SipClientService implements SipListener {
String realm = wwwAuth.getRealm();
String nonce = wwwAuth.getNonce();
String qop = wwwAuth.getQop();
String algorithm = wwwAuth.getAlgorithm();
String uri = "sip:" + domain + ":" + port;
String nc = "00000001";
String cNonce = generateCNonce();
log.info("Auth params -> username: {}, realm: {}, nonce: {}, uri: {}, qop: {}", username, realm, nonce, uri, qop);
String responseDigest = DigestUtil.computeResponse(
username,
password,
@ -535,32 +582,41 @@ public class SipClientService implements SipListener {
authHeader.setNonce(nonce);
authHeader.setURI(addressFactory.createURI(uri));
authHeader.setResponse(responseDigest);
authHeader.setAlgorithm(algorithm);
if (qop != null) {
authHeader.setQop(qop);
authHeader.setCNonce(cNonce);
authHeader.setNonceCount(Integer.parseInt(nc, 16));
}
sendRegister(authHeader);
sendRegister(authHeader, initialCallId);
} else if (status >= 200 && status < 300) {
log.info("REGISTER success: {}", status);
// authRetryCount = 0; // 认证成功重置重试计数
int delay = Math.max(5, expires - 60);
refreshTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
sendRegister(null);
log.info("第{}次,Refreshing REGISTER...",authRetryCount++);
sendRegister(null, initialCallId);
} catch (Exception e) {
log.error("Failed to refresh register", e);
}
}
}, delay * 1000L);
//sendNotify(username, domain, port, testXml);
// 向SIP服务器订阅消息不符合SIP/GB28181标准
//sendSubscribe(username, domain, port, "Push_Resource");
// 注册成功后上报设备资源信息支持MTU分片和UDP/TCP双协议
// 异步发送避免阻塞注册响应处理
new Thread(() -> {
try {
// 等待注册流程完全完成
Thread.sleep(1000);
sendResourceReport(username, domain, port);
} catch (Exception e) {
log.error("Failed to send resource report", e);
}
}).start();
} else {
log.warn("REGISTER response: {}", status);
}
@ -581,14 +637,17 @@ public class SipClientService implements SipListener {
String realm = null;
String nonce = null;
String qop = null;
String algorithm = null;
if (wwwAuth != null) {
realm = wwwAuth.getRealm();
nonce = wwwAuth.getNonce();
qop = wwwAuth.getQop();
algorithm = wwwAuth.getAlgorithm();
} else if (proxyAuth != null) {
realm = proxyAuth.getRealm();
nonce = proxyAuth.getNonce();
qop = proxyAuth.getQop();
algorithm = proxyAuth.getAlgorithm();
} else {
log.error("No Authenticate header found for SUBSCRIBE");
return;
@ -629,6 +688,7 @@ public class SipClientService implements SipListener {
authHeader.setNonce(nonce);
authHeader.setURI(addressFactory.createURI(uri));
authHeader.setResponse(responseDigest);
authHeader.setAlgorithm(algorithm);
if (qop != null) {
authHeader.setQop(qop);
authHeader.setCNonce(cNonce);
@ -639,9 +699,14 @@ public class SipClientService implements SipListener {
sendSubscribeWithAuth(deviceCode, serverIp, serverPort, event, authHeader);
} else if (status >= 200 && status < 300) {
log.info("SUBSCRIBE 成功: {}", status);
// 成功订阅后向服务器上报资源 NOTIFY
// sendNotify(username, domain, port, resourcesReportTestXml);
sendNotify(username, domain, port, notifyTestXml);
// 成功订阅后异步上报设备资源信息
// new Thread(() -> {
// try {
// sendResourceReport(username, domain, port);
// } catch (Exception e) {
// log.error("Failed to send resource report after SUBSCRIBE", e);
// }
// }).start();
} else {
log.warn("SUBSCRIBE 响应: {}", status);
}
@ -669,6 +734,206 @@ public class SipClientService implements SipListener {
}
}
// MTU限制UDP建议1400字节留出IP/UDP/SIP头部空间
private static final int MTU_LIMIT = 1400;
/**
* 动态生成资源上报 XML resourcesReportTestXml 格式一致
* 格式示例
* <?xml version="1.0" encoding="UTF-8"?>
* <SIP_XML EventType="Push_Resource">
* <Code>父节点编码</Code>
* <SubList SubNum="N">
* <Item Code="设备编码" Name="名称" Status="1" DecoderTag="H264" Longitude="经度" Latitude="纬度" SubNum="0"/>
* </SubList>
* </SIP_XML>
*
* @param platformCode 前端平台编码父节点地址编码
* @param cameras 设备列表
* @return 完整的 SIP_XML 字符串
*/
private String buildResourceReportXml(String platformCode, List<BasedataEqpBookMoMain> cameras) {
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<SIP_XML EventType=\"Push_Resource\">\n");
sb.append(" <Code>").append(platformCode).append("</Code>\n");
sb.append(" <SubList SubNum=\"").append(cameras.size()).append("\">\n");
for (BasedataEqpBookMoMain cam : cameras) {
sb.append(" <Item")
.append(" Code=\"").append(cam.getUpSystemDeviceCode() != null ? cam.getUpSystemDeviceCode() : "").append("\"")
.append(" Name=\"").append(cam.getPatrolDeviceName() != null ? cam.getPatrolDeviceName() : "").append("\"")
.append(" Status=\"1\"")
.append(" DecoderTag=\"H264\"")
.append(" Longitude=\"").append(cam.getPositionX() != null ? cam.getPositionX() : "").append("\"")
.append(" Latitude=\"").append(cam.getPositionY() != null ? cam.getPositionY() : "").append("\"")
.append(" SubNum=\"0\"")
.append("/>\n");
}
sb.append(" </SubList>\n");
sb.append("</SIP_XML>\n");
return sb.toString();
}
/**
* 生成单个设备的资源XML用于分片发送
*
* @param platformCode 前端平台编码
* @param camera 单个设备
* @return 单个设备的 XML 字符串
*/
private String buildSingleDeviceXml(String platformCode, BasedataEqpBookMoMain camera) {
StringBuilder sb = new StringBuilder();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
sb.append("<SIP_XML EventType=\"Push_Resource\">\n");
sb.append(" <Code>").append(platformCode).append("</Code>\n");
sb.append(" <SubList SubNum=\"1\">\n");
sb.append(" <Item")
.append(" Code=\"").append(camera.getUpSystemDeviceCode() != null ? camera.getUpSystemDeviceCode() : "").append("\"")
.append(" Name=\"").append(camera.getPatrolDeviceName() != null ? camera.getPatrolDeviceName() : "").append("\"")
.append(" Status=\"").append(camera.getStatus() != null ? camera.getStatus() : "1").append("\"")
.append(" DecoderTag=\"H264\"")
.append(" Longitude=\"").append(camera.getPositionX() != null ? camera.getPositionX() : "").append("\"")
.append(" Latitude=\"").append(camera.getPositionY() != null ? camera.getPositionY() : "").append("\"")
.append(" SubNum=\"0\"")
.append("/>\n");
sb.append(" </SubList>\n");
sb.append("</SIP_XML>\n");
return sb.toString();
}
/**
* 将XML按MTU限制分片
* 每个分片保持完整的XML结构格式与 resourcesReportTestXml 一致
*
* @param xml 完整XML
* @param maxBytes 最大字节数
* @return 分片后的XML列表
*/
private List<String> splitXmlByMtu(String xml, int maxBytes, List<BasedataEqpBookMoMain> cameras) {
List<String> parts = new ArrayList<>();
try {
byte[] data = xml.getBytes(StandardCharsets.UTF_8);
if (data.length <= maxBytes) {
parts.add(xml);
return parts;
}
// 从数据库获取设备列表进行分片
if (cameras == null || cameras.isEmpty()) {
parts.add(xml);
return parts;
}
// XML头部
String xmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<SIP_XML EventType=\"Push_Resource\">\n" +
" <Code>" + username + "</Code>\n";
// XML尾部
String xmlFooter = "</SIP_XML>\n";
// SubList标签模板
String subListStart = " <SubList SubNum=\"";
String subListEnd = "\">\n";
String subListClose = " </SubList>\n";
int headerLen = xmlHeader.getBytes(StandardCharsets.UTF_8).length;
int footerLen = xmlFooter.getBytes(StandardCharsets.UTF_8).length;
int subListOverhead = subListStart.getBytes(StandardCharsets.UTF_8).length +
subListEnd.getBytes(StandardCharsets.UTF_8).length +
subListClose.getBytes(StandardCharsets.UTF_8).length + 10; // 预留数字位数
int availableBytes = maxBytes - headerLen - footerLen - subListOverhead;
StringBuilder currentItems = new StringBuilder();
int currentSize = 0;
int itemCount = 0;
for (BasedataEqpBookMoMain cam : cameras) {
String itemXml = " <Item" +
" Code=\"" + (cam.getUpSystemDeviceCode() != null ? cam.getUpSystemDeviceCode() : "") + "\"" +
" Name=\"" + (cam.getPatrolDeviceName() != null ? cam.getPatrolDeviceName() : "") + "\"" +
" Status=\"1\"" +
" DecoderTag=\"H264\"" +
" Longitude=\"" + (cam.getPositionX() != null ? cam.getPositionX() : "") + "\"" +
" Latitude=\"" + (cam.getPositionY() != null ? cam.getPositionY() : "") + "\"" +
" SubNum=\"0\"" +
"/>\n";
int itemSize = itemXml.getBytes("UTF-8").length;
if (currentSize + itemSize > availableBytes && currentItems.length() > 0) {
// 当前批次已满生成一个分片
String part = xmlHeader + subListStart + itemCount + subListEnd +
currentItems.toString() + subListClose + xmlFooter;
parts.add(part);
currentItems = new StringBuilder();
currentSize = 0;
itemCount = 0;
}
currentItems.append(itemXml);
currentSize += itemSize;
itemCount++;
}
// 添加最后一个批次
if (currentItems.length() > 0) {
String part = xmlHeader + subListStart + itemCount + subListEnd +
currentItems.toString() + subListClose + xmlFooter;
parts.add(part);
}
} catch (UnsupportedEncodingException e) {
log.error("Failed to split XML", e);
// 降级直接返回原始XML
parts.add(xml);
}
return parts;
}
/**
* 发送资源报告支持MTU分片和UDP/TCP双协议
*
* @param deviceCode 设备编码
* @param serverIp 服务器IP
* @param serverPort 服务器端口
*/
public void sendResourceReport(String deviceCode, String serverIp, int serverPort) {
try {
List<BasedataEqpBookMoMain> cameras = cameraMapper.selectCamera();
if (cameras == null || cameras.isEmpty()) {
log.warn("No cameras found for resource report");
return;
}
log.info("Preparing resource report for {} cameras", cameras.size());
// 生成完整XML
String fullXml = buildResourceReportXml(deviceCode, cameras);
log.info("Full resource XML size: {} bytes", fullXml.getBytes(StandardCharsets.UTF_8).length);
// 按MTU分片
List<String> xmlParts = splitXmlByMtu(fullXml, MTU_LIMIT, cameras);
log.info("Split into {} parts for MTU compliance", xmlParts.size());
// 逐片发送
for (int i = 0; i < xmlParts.size(); i++) {
String part = xmlParts.get(i);
// log.info("Sending resource report part {}/{}, size: {} bytes",
// i + 1, xmlParts.size(), part.getBytes("UTF-8").length);
sendNotify(deviceCode, serverIp, serverPort, part);
// 分片间隔避免拥塞
if (i < xmlParts.size() - 1) {
Thread.sleep(100);
}
}
log.info("Resource report sent successfully");
} catch (Exception e) {
log.error("Failed to send resource report", e);
}
}
private void resendNotifyWithAuth() throws Exception {
String method = Request.NOTIFY;
String uriStr = lastDeviceCode + "@" + lastServerIp;
@ -700,24 +965,29 @@ public class SipClientService implements SipListener {
authHeader.setNonceCount(1);
Request requestWithAuth = createNotifyRequest(lastDeviceCode, lastServerIp, lastServerPort, lastXmlBody, authHeader);
log.info("Sending notifyWithAuth request:\n {}", requestWithAuth);
ClientTransaction transaction = sipProvider.getNewClientTransaction(requestWithAuth);
transaction.sendRequest();
}
// 构造NOTIFY请求
// 构造NOTIFY请求支持UDP和TCP双协议
private Request createNotifyRequest(String deviceCode, String serverIp, int serverPort, String xmlBody, AuthorizationHeader authHeader) throws Exception {
String notifierUser = "290010021201070000";
// 前端系统所属平台地址编码
String notifierUser = "290010000000000000";
String localHost = this.localIp;
int localPort = this.localPort;
SipURI requestUri = addressFactory.createSipURI(deviceCode, serverIp);
requestUri.setTransportParam("tcp");
// 前端系统所属平台地址编码@前端系统所属平台域名或IP地址
SipURI requestUri = addressFactory.createSipURI(notifierUser, serverIp);
// 使用配置的传输协议UDP或TCP
requestUri.setTransportParam(transport.toUpperCase());
requestUri.setPort(serverPort);
Address fromAddress = addressFactory.createAddress("sip:" + username + "@" + localHost);
// 前端系统地址编码@前端系统所属平台域名或IP地址
Address fromAddress = addressFactory.createAddress("sip:" + deviceCode + "@" + serverIp);
FromHeader fromHeader = headerFactory.createFromHeader(fromAddress, UUID.randomUUID().toString().substring(0, 8));
Address toAddress = addressFactory.createAddress("sip:" + deviceCode + "@" + serverIp);
// 前端系统所属平台地址编码@前端系统所属平台域名或IP地址
Address toAddress = addressFactory.createAddress("sip:" + notifierUser + "@" + serverIp);
ToHeader toHeader = headerFactory.createToHeader(toAddress, null);
CallIdHeader callId = sipProvider.getNewCallId();
@ -725,14 +995,15 @@ public class SipClientService implements SipListener {
MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);
List<ViaHeader> viaHeaders = new ArrayList<>();
// 前端系统所属平台ip地址
ViaHeader viaHeader = headerFactory.createViaHeader(localHost, localPort, transport, null);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
Address contactAddr = addressFactory.createAddress("sip:" + username + "@" + localHost + ":" + localPort);
// 前端系统地址编码@前端系统所属平台域名或IP地址
Address contactAddr = addressFactory.createAddress("sip:" + deviceCode + "@" + localHost + ":" + localPort);
ContactHeader contactHeader = headerFactory.createContactHeader(contactAddr);
// EventHeader eventHeader = headerFactory.createEventHeader("Push_Resource");
EventHeader eventHeader = headerFactory.createEventHeader("Notify_Test");
EventHeader eventHeader = headerFactory.createEventHeader("Push_Resource");
SubscriptionStateHeader subscriptionStateHeader = headerFactory.createSubscriptionStateHeader(SubscriptionStateHeader.TERMINATED);
@ -766,7 +1037,9 @@ public class SipClientService implements SipListener {
return Long.toHexString(System.currentTimeMillis() & 0xffffffffL);
}
private final String rtspInputUrl = "rtsp://admin:wd19216811@192.168.1.244:554/h264/ch1/sub/av_stream";
// ffmpeg -rtsp_transport tcp -i "rtsp://admin:htjc2018@192.168.1.134:554/cam/realmonitor?channel=3&subtype=0" -c copy -an -f rtp -rtsp_transport tcp "rtp://192.168.1.116:30000"
// private String flvInputUrl = "http://192.168.1.116:33380/live/1f4e292a-0b46-4f37-9cc7-a4f56c54361a.live.flv";
private String flvInputUrl = "rtsp://admin:wd19216811@192.168.1.244:554/h264/ch1/sub/av_stream";
@Override
public void processRequest(RequestEvent requestEvent) {
Request request = requestEvent.getRequest();
@ -805,7 +1078,8 @@ public class SipClientService implements SipListener {
st.sendResponse(ok);
SipXmlEnvelope<?> envelope = SipXmlParser.parse(xml, itemClass);
//handleSipEvent(envelope);
// TODO: 事件处理逻辑
// handleSipEvent(envelope);
}
} else if (Request.NOTIFY.equalsIgnoreCase(method)) {
ContentTypeHeader ct = (ContentTypeHeader) request.getHeader(ContentTypeHeader.NAME);
@ -851,17 +1125,28 @@ public class SipClientService implements SipListener {
} else if(Request.ACK.equals(request.getMethod())) {
// RFC 3261: The ACK request does not generate a response.
// ACK "事务内请求", 不是普通 SIP 方法, 不生成任何 Response
log.info("CALL startRtspToRtp");
log.info("CALL startRtspToRtp flv {}",flvInputUrl);
log.info("Received SIP request: \n {}", request);
byte[] raw = request.getRawContent();
if (raw != null) {
String inviteAckContent = new String(raw, StandardCharsets.UTF_8);
log.info("INVITE ACK content: \n{}", inviteAckContent);
}
streamService.startPushStream(rtspInputUrl, rtpStreamHost, rtpStreamPort);
String streamId = String.valueOf(rtpStreamSSRC);
streamService.startPushToZlmAndSendToPlatform(
flvInputUrl,
streamId,
rtpStreamHost, // 平台 IP ( SDP 解析)
rtpStreamPort, // 平台端口
rtpStreamSSRC, // SSRC
payload
);
// streamService.startPushStream(flvInputUrl, rtpStreamHost, rtpStreamPort);
//streamService.startPush();//PS OVER RTP
//gb28181RtpStreamer.start(rtspInputUrl, rtpStreamHost, rtpStreamPort);
} else if(Request.BYE.equals(request.getMethod())) {
log.info("Received BYE:\n{}", request);
streamService.stopPush();
} else {
Response notImpl = messageFactory.createResponse(Response.NOT_IMPLEMENTED, request);
@ -879,6 +1164,109 @@ public class SipClientService implements SipListener {
}
}
/**
* 调用 ZLMediaKit startSendRtp 接口 ZLM 主动推流到平台
*/
private void startZlmSendRtp(String streamId, String platformIp, int platformPort, long ssrc) {
try {
// 构建 API URL
// http://zlm-ip:8080/index/api/startSendRtp?secret=xxx&streamId=xxx&dst_url=xxx&dst_port=xxx&ssrc=xxx&tcp_type=0
String apiUrl = String.format("http://%s:%d/index/api/startSendRtp",
zlmHttpIp, zlmHttpPort);
// 这里的 src_url 应该是你摄像头的 RTSP 地址或者你本地推给 ZLM 的流标识
// 假设 ZLM 可以直接拉取摄像头的流
// 注意实际项目中url 应该从数据库或配置中获取这里为了演示使用硬编码或解析逻辑
String cameraRtspUrl = flvInputUrl; // 或者从 SDP 中解析出的其他标识获取
// 构建请求参数
String params = String.format("secret=Xg@123456" + // 默认密钥需替换为你的
"&streamId=%s" +
"&src_url=%s" +
"&dst_url=%s" +
"&dst_port=%d" +
"&ssrc=%d" +
"&pt=96" + // GB28181 通常 H264 96 100根据 SDP 确定
"&tcp_type=0" + // 0=UDP, 1=TCP_CLIENT, 2=TCP_SERVER
"&mediaServerId=%s",
streamId,
URLEncoder.encode(cameraRtspUrl, "UTF-8"),
platformIp,
platformPort,
ssrc,
zlmServerId);
URL url = new URL(apiUrl + "?" + params);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
int responseCode = conn.getResponseCode();
if (responseCode == 200) {
log.info("成功调用 ZLM startSendRtp,推流到平台: {}:{}", platformIp, platformPort);
} else {
log.error("调用 ZLM startSendRtp 失败,HTTP 状态码: {}", responseCode);
}
} catch (Exception e) {
log.error("调用 ZLM API 异常", e);
}
}
private void handleSipEvent(SipXmlEnvelope<?> envelope) {
String eventType = envelope.getEventType();
List<?> items = envelope.getItems();
log.info("=============Handle SipEvent: {}, items size = {}", eventType, items.size());
// 根据事件类型分发处理
switch (eventType) {
case "Push_Resource":
handleResourcePush(envelope);
break;
case "Notify_Alarm":
handleAlarmNotification(envelope);
break;
case "Notify_Test":
handleTestNotification(envelope);
break;
default:
log.warn("Unhandled event type: {}", eventType);
}
}
/**
* 处理资源推送
*/
private void handleResourcePush(SipXmlEnvelope<?> envelope) {
log.info("Processing resource push, {} items", envelope.getItems().size());
// TODO: 实现具体的资源处理逻辑
}
/**
* 处理告警通知
*/
private void handleAlarmNotification(SipXmlEnvelope<?> envelope) {
log.info("Processing alarm notification, {} items", envelope.getItems().size());
// TODO: 实现告警处理逻辑
}
/**
* 处理测试通知
*/
private void handleTestNotification(SipXmlEnvelope<?> envelope) {
log.info("Processing test notification");
// TODO: 实现测试通知处理逻辑
}
/**
* 处理通知内容
*/
private void handleNotifyContent(String xml, String eventType) {
log.info("Processing {} notify content", eventType);
// TODO: 实现通知内容处理
}
private void handleInvite(RequestEvent requestEvent) throws Exception {
Request request = requestEvent.getRequest();
log.info("Received INVITE:\n{}", request);
@ -892,6 +1280,7 @@ public class SipClientService implements SipListener {
// 100 Trying非常推荐
Response trying = messageFactory.createResponse(Response.TRYING, request);
st.sendResponse(trying);
log.info("INVITE handled: 100 OK sent \n{}",trying);
// 解析对方 SDP可先只打印
byte[] raw = request.getRawContent();
@ -904,16 +1293,51 @@ public class SipClientService implements SipListener {
rtpStreamPort = sdpInfo.port;
rtpStreamSSRC = sdpInfo.ssrc;
}
SipURI requestUri = (SipURI) request.getRequestURI();
log.info("-------------------requestUri {}",requestUri);
String videoCodec = "H264";
String payload = "100";
String systemDeviceCode = requestUri.getUser();
if (StringUtils.isNotEmpty(systemDeviceCode)) {
log.info("fffffffffffffffffffffffffffffffffffffffffff");
BasedataEqpBookMoMain basedataEqpBook = cameraMapper.getBasedataEqpBook(systemDeviceCode);
log.info("----------------handleInvite basedataEqpBook {}", basedataEqpBook);
if (basedataEqpBook == null) {
log.info("basedataEqpBook no data");
return;
}
String channelName = basedataEqpBook.getChannelName();
// if (channelName != null && channelName.contains("控制柜")) {
// videoCodec = "H265";
// payload = "108";
// }
this.payload = payload;
String patrolDeviceCode = basedataEqpBook.getPatrolDeviceCode();
String channelCode = basedataEqpBook.getChannelCode();
log.info("patrolDeviceCode {},channelCode {}",patrolDeviceCode,channelCode);
// AjaxResult realtimeAjaxResult = mainFeignService.realtime(patrolDeviceCode, channelCode);
// JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(realtimeAjaxResult.get("data")));
JSONObject jsonObject = ivsFeignService.rtspUrl(channelCode);
log.info("jsonObject {}",jsonObject);
if (jsonObject != null) {
String flvURL = jsonObject.getString("rtspURL");
log.info("rtspURL{}",flvURL);
flvInputUrl = flvURL;
}
}
// 构造 200 OK + SDP
Response ok = messageFactory.createResponse(Response.OK, request);
String localSipId = "29001002120107000001";
// 这个端口几乎没有任何作用可以改成任何值只是为了协议的完整性因为这里的TCP是设备主动连接平台的不需要平台通过这个端口反过来连接设备
int localRtpPort = 554;
int localRtpPort = rtpStreamPort;
// Contact 必须
Address contactAddress = addressFactory.createAddress(
"sip:" + localSipId + "@" + localIp + ":" + localPort
"sip:" + username + "@" + localIp + ":" + localPort
);
ContactHeader contactHeader = headerFactory.createContactHeader(contactAddress);
ok.addHeader(contactHeader);
@ -925,22 +1349,25 @@ public class SipClientService implements SipListener {
// 返回 SDP示例
String sdp =
"v=0\r\n" +
"o=" + localSipId + " 0 0 IN IP4 " + localIp + "\r\n" +
"s=Play\r\n" +
"c=IN IP4 " + localIp + "\r\n" +
"t=0 0\r\n" +
"m=video " + localRtpPort + " TCP/RTP/AVP 96\r\n" +
"a=sendonly\r\n" +
"a=setup:active\r\n" +
"a=connection:new\r\n" +
"a=rtpmap:96 PS/90000\r\n";
"o=- 0 0 IN IP4 " + localIp + "\r\n" +
"s=Play\r\n" +
"c=IN IP4 " + localIp + "\r\n" +
"t=0 0\r\n" +
"m=video " + localRtpPort + " TCP/RTP/AVP " + payload + "\r\n" +
"y=" + rtpStreamSSRC + "\r\n" +
"a=rtpmap:"+ payload + " " + videoCodec + "/90000\r\n" +
// "a=fmtp:" + payload + " CIF=1;profile-level-id=420028;sprop-parameter-sets=Z0IAKOkBQHsg,aM44gA==\r\n" +
"a=sendonly\r\n" +
"a=setup:active\r\n" +
"a=connection:new\r\n";
log.info("--------sdp\n {}",sdp);
ok.setContent(sdp, contentType);
// 发送 200 OK
st.sendResponse(ok);
log.info("INVITE handled: 200 OK sent");
log.info("INVITE handled: 200 OK sent \n{}",ok);
}
@ -988,6 +1415,7 @@ public class SipClientService implements SipListener {
lastXmlBody = xmlBody;
Request request = createNotifyRequest(deviceCode, serverIp, serverPort, xmlBody, null);
log.info("Sending notify request:\n"+request);
ClientTransaction transaction = sipProvider.getNewClientTransaction(request);
transaction.sendRequest();
}


+ 0
- 230
src/main/java/com/inspect/tcpserver/sip/service/SipVideoClient.java View File

@ -1,230 +0,0 @@
package com.inspect.tcpserver.sip.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.sip.*;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.*;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Random;
@Slf4j
@Component
@ConditionalOnProperty(name = "sip.enable", havingValue = "true")
public class SipVideoClient implements SipListener {
private SipFactory sipFactory;
private SipStack sipStack;
private SipProvider sipProvider;
private HeaderFactory headerFactory;
private AddressFactory addressFactory;
private MessageFactory messageFactory;
@Value("${sip.local-ip}")
private String localIp; // 本地IP
@Value("${sip.local-port2:5062}")
private int localPort; // 本地监听端口
@Value("${sip.domain}")
private String remoteIp; // Asterisk IP
@Value("${sip.port}")
private int remotePort; // Asterisk端口
@Value("${sip.username}")
private String username;
@Value("${sip.domain}")
private String domain;
@Value("${sip.transport}")
private String transport;
@PostConstruct
public void init() throws Exception {
sipFactory = SipFactory.getInstance();
sipFactory.setPathName("gov.nist");
headerFactory = sipFactory.createHeaderFactory();
addressFactory = sipFactory.createAddressFactory();
messageFactory = sipFactory.createMessageFactory();
Properties properties = new Properties();
properties.setProperty("javax.sip.STACK_NAME", "sip-video-client");
properties.setProperty("gov.nist.javax.sip.IP_ADDRESS", localIp);
sipStack = sipFactory.createSipStack(properties);
ListeningPoint lp = sipStack.createListeningPoint(localIp, localPort, transport);
//ListeningPoint lp = sipStack.createListeningPoint("0.0.0.0", localPort, transport);
sipProvider = sipStack.createSipProvider(lp);
sipProvider.addSipListener(this);
}
public void sendInvite() throws Exception {
SipURI requestUri = addressFactory.createSipURI(null, domain);
requestUri.setTransportParam(transport);
requestUri.setPort(remotePort);
Address fromAddress = addressFactory.createAddress("sip:" + username + "@" + domain);
FromHeader fromHeader = headerFactory.createFromHeader(fromAddress, Integer.toHexString(new Random().nextInt()));
Address toAddress = addressFactory.createAddress("sip:" + username + "@" + domain);
ToHeader toHeader = headerFactory.createToHeader(toAddress, null);
CallIdHeader callIdHeader = sipProvider.getNewCallId();
CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L, Request.INVITE);
MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);
List<ViaHeader> viaHeaders = new ArrayList<>();
viaHeaders.add(headerFactory.createViaHeader(localIp, localPort, transport, null));
Request inviteRequest = messageFactory.createRequest(
requestUri,
Request.INVITE,
callIdHeader,
cSeqHeader,
fromHeader,
toHeader,
viaHeaders,
maxForwards);
// 添加Contact头
Address contactAddress = addressFactory.createAddress("sip:" + username + "@" + localIp + ":" + localPort);
ContactHeader contactHeader = headerFactory.createContactHeader(contactAddress);
inviteRequest.addHeader(contactHeader);
// 添加SDP Body 这描述视频流的RTP信息
String sdpData = buildSdpBody(localIp, 9000); // 本地RTP端口9000
ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader("application", "sdp");
inviteRequest.setContent(sdpData, contentTypeHeader);
ClientTransaction inviteTransaction = sipProvider.getNewClientTransaction(inviteRequest);
inviteTransaction.sendRequest();
}
private String buildSdpBody(String ip, int rtpPort) {
return "v=0\r\n" +
"o=- 0 0 IN IP4 " + ip + "\r\n" +
"s=Video Call\r\n" +
"c=IN IP4 " + ip + "\r\n" +
"t=0 0\r\n" +
"m=video " + rtpPort + " RTP/AVP 96\r\n" +
"a=rtpmap:96 H264/90000\r\n" +
"a=sendrecv\r\n";
}
@Override
public void processResponse(ResponseEvent responseEvent) {
Response response = responseEvent.getResponse();
CSeqHeader cSeq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
int statusCode = response.getStatusCode();
log.info("Received response: {} for: {}", statusCode, cSeq.getMethod());
if (statusCode == 200 && Request.INVITE.equals(cSeq.getMethod())) {
try {
ClientTransaction ct = responseEvent.getClientTransaction();
Dialog dialog = ct.getDialog();
Request ackRequest = dialog.createAck(cSeq.getSeqNumber());
dialog.sendAck(ackRequest);
log.info("Sent ACK, 开始推送视频流");
startVideoStreaming();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void processRequest(RequestEvent requestEvent) {
Request request = requestEvent.getRequest();
String method = request.getMethod();
log.info("Received request: {}", method);
if (Request.BYE.equals(method)) {
try {
ServerTransaction st = requestEvent.getServerTransaction();
if (st == null) {
st = sipProvider.getNewServerTransaction(request);
}
Response response = messageFactory.createResponse(200, request);
st.sendResponse(response);
log.info("Received BYE,通话结束,停止推流");
stopVideoStreaming();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void processTimeout(TimeoutEvent timeoutEvent) {}
@Override
public void processIOException(IOExceptionEvent exceptionEvent) {}
@Override
public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {}
@Override
public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {}
private Process ffmpegProcess;
private void startVideoStreaming() {
try {
String rtspUrl = "rtsp://localhost:8554/mystream";
ProcessBuilder pb = new ProcessBuilder(
"ffmpeg",
"-rtsp_transport", "tcp", // 如果rtsp拉流失败可试试tcp
"-i", rtspUrl,
"-vcodec", "copy",
"-an",
"-f", "rtp",
"rtp://" + remoteIp + ":9000"
);
pb.redirectErrorStream(true);
ffmpegProcess = pb.start();
// 启动一个线程打印FFMPEG日志
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
log.info("[FFMPEG] {}", line);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
log.info("视频推流开始");
} catch (Exception e) {
e.printStackTrace();
}
}
private void stopVideoStreaming() {
if (ffmpegProcess != null) {
ffmpegProcess.destroy();
System.out.println("视频推流停止");
}
}
}

+ 0
- 35
src/main/java/com/inspect/tcpserver/sip/stream/H264AnnexBExtractor.java View File

@ -1,35 +0,0 @@
package com.inspect.tcpserver.sip.stream;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.javacpp.BytePointer;
public class H264AnnexBExtractor {
private static final byte[] START_CODE = {0x00, 0x00, 0x00, 0x01};
public static byte[] extractFromAvPacket(AVPacket pkt) {
BytePointer dataPtr = pkt.data();
int size = pkt.size();
if (dataPtr == null || size <= 0) {
return null;
}
byte[] raw = new byte[size];
dataPtr.get(raw);
// 如果已经是 Annex-B00 00 00 01
if (raw.length >= 4 &&
raw[0] == 0x00 && raw[1] == 0x00 &&
raw[2] == 0x00 && raw[3] == 0x01) {
return raw;
}
// AVCC Annex-B简单处理前置 start code
byte[] annexB = new byte[START_CODE.length + raw.length];
System.arraycopy(START_CODE, 0, annexB, 0, START_CODE.length);
System.arraycopy(raw, 0, annexB, START_CODE.length, raw.length);
return annexB;
}
}

+ 0
- 35
src/main/java/com/inspect/tcpserver/sip/stream/MediaSession.java View File

@ -1,35 +0,0 @@
package com.inspect.tcpserver.sip.stream;
import com.inspect.tcpserver.sip.stream.ps.PsMuxer;
public class MediaSession {
private final PsMuxer psMuxer;
private final RtpSender rtpSender;
private RtspClient rtspClient;
public MediaSession(String remoteIp, int remotePort, int ssrc) throws Exception {
this.psMuxer = new PsMuxer();
this.rtpSender = new RtpSender(remoteIp, remotePort, ssrc);
}
public void startRtsp(String rtspUrl) throws Exception {
rtspClient = new RtspClient(rtspUrl);
rtspClient.start(h264 -> {
try {
byte[] ps = psMuxer.mux(h264);
rtpSender.sendPs(ps);
} catch (Exception e) {
e.printStackTrace();
}
});
}
public void stop() {
if (rtspClient != null) {
rtspClient.stop();
}
rtpSender.close();
}
}

+ 0
- 15
src/main/java/com/inspect/tcpserver/sip/stream/RtpClock.java View File

@ -1,15 +0,0 @@
package com.inspect.tcpserver.sip.stream;
public class RtpClock {
private static final long CLOCK_90K = 90000;
private static final long FRAME_INTERVAL = 3600; // 40ms
private long timestamp = 0;
public long next() {
timestamp += FRAME_INTERVAL;
return timestamp;
}
}

+ 0
- 39
src/main/java/com/inspect/tcpserver/sip/stream/RtpPacket.java View File

@ -1,39 +0,0 @@
package com.inspect.tcpserver.sip.stream;
public class RtpPacket {
public static final int HEADER_SIZE = 12;
public byte[] buffer;
public int length;
public RtpPacket(int payloadSize) {
buffer = new byte[HEADER_SIZE + payloadSize];
}
public void setHeader(
int payloadType,
int seq,
long timestamp,
int ssrc,
boolean marker
) {
buffer[0] = (byte) 0x80;
buffer[1] = (byte) (payloadType & 0x7F);
if (marker) buffer[1] |= 0x80;
buffer[2] = (byte) (seq >> 8);
buffer[3] = (byte) (seq);
buffer[4] = (byte) (timestamp >> 24);
buffer[5] = (byte) (timestamp >> 16);
buffer[6] = (byte) (timestamp >> 8);
buffer[7] = (byte) (timestamp);
buffer[8] = (byte) (ssrc >> 24);
buffer[9] = (byte) (ssrc >> 16);
buffer[10] = (byte) (ssrc >> 8);
buffer[11] = (byte) (ssrc);
}
}

+ 0
- 46
src/main/java/com/inspect/tcpserver/sip/stream/RtpSender.java View File

@ -1,46 +0,0 @@
package com.inspect.tcpserver.sip.stream;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RtpSender {
private static final int MTU = 1400;
private static final int PAYLOAD_TYPE = 98;
private int seq = 0;
private final int ssrc;
private final RtpSocket socket;
private final RtpClock clock = new RtpClock();
public RtpSender(String ip, int port, int ssrc) throws Exception {
this.ssrc = ssrc;
this.socket = new RtpSocket(ip, port);
}
public void sendPs(byte[] ps) throws Exception {
long ts = clock.next();
int offset = 0;
while (offset < ps.length) {
int size = Math.min(MTU, ps.length - offset);
boolean marker = (offset + size) >= ps.length;
RtpPacket pkt = new RtpPacket(size);
pkt.setHeader(PAYLOAD_TYPE, seq++, ts, ssrc, marker);
System.arraycopy(ps, offset, pkt.buffer, RtpPacket.HEADER_SIZE, size);
pkt.length = RtpPacket.HEADER_SIZE + size;
socket.send(pkt.buffer, pkt.length);
offset += size;
log.info("sendPs offset = {}", offset);
}
}
public void close() {
socket.close();
}
}

+ 0
- 26
src/main/java/com/inspect/tcpserver/sip/stream/RtpSocket.java View File

@ -1,26 +0,0 @@
package com.inspect.tcpserver.sip.stream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
public class RtpSocket {
private final DatagramSocket socket;
private final InetSocketAddress remote;
public RtpSocket(String ip, int port) throws Exception {
socket = new DatagramSocket();
remote = new InetSocketAddress(ip, port);
}
public void send(byte[] data, int len) throws Exception {
DatagramPacket packet = new DatagramPacket(data, len, remote);
socket.send(packet);
}
public void close() {
socket.close();
}
}

+ 0
- 59
src/main/java/com/inspect/tcpserver/sip/stream/RtspClient.java View File

@ -1,59 +0,0 @@
package com.inspect.tcpserver.sip.stream;
import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
public class RtspClient {
private final String url;
private FFmpegFrameGrabber grabber;
private final AtomicBoolean running = new AtomicBoolean(false);
public RtspClient(String url) {
this.url = url;
}
public void start(Consumer<byte[]> onH264) throws Exception {
grabber = new FFmpegFrameGrabber(url);
grabber.setOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "5000000");
grabber.start();
running.set(true);
new Thread(() -> {
try {
while (running.get()) {
AVPacket pkt = grabber.grabPacket();
if (pkt == null || pkt.size() <= 0) {
continue;
}
byte[] annexB = H264AnnexBExtractor.extractFromAvPacket(pkt);
if (annexB != null) {
onH264.accept(annexB);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
stop();
}
}, "RtspClient-Thread").start();
}
public void stop() {
running.set(false);
try {
if (grabber != null) {
grabber.stop();
grabber.release();
}
} catch (Exception ignored) {
}
}
}

+ 0
- 15
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsConstants.java View File

@ -1,15 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
public final class PsConstants {
public static final int PACK_START_CODE = 0x000001BA;
public static final int SYSTEM_HEADER_START_CODE = 0x000001BB;
public static final int PROGRAM_STREAM_MAP = 0x000001BC;
public static final int PES_VIDEO_START_CODE = 0x000001E0;
public static final int STREAM_ID_VIDEO = 0xE0;
public static final long CLOCK_90K = 90000L;
private PsConstants() {}
}

+ 0
- 28
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsMuxer.java View File

@ -1,28 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
import java.io.ByteArrayOutputStream;
public class PsMuxer {
private boolean headerSent = false;
private long scr = 0;
public byte[] mux(byte[] h264) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
scr += 3600;
if (!headerSent) {
out.write(PsPackHeader.create(scr));
out.write(PsSystemHeader.create());
out.write(PsProgramStreamMap.create());
headerSent = true;
}
out.write(PsPackHeader.create(scr));
out.write(PsPesPacket.create(h264, scr));
return out.toByteArray();
}
}

+ 0
- 27
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsPackHeader.java View File

@ -1,27 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
import java.io.ByteArrayOutputStream;
public class PsPackHeader {
public static byte[] create(long scr) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{0, 0, 1, (byte) 0xBA});
long b = scr & 0x1FFFFFFFFL;
out.write((byte) (0x44 | ((b >> 27) & 0x38)));
out.write((byte) (b >> 19));
out.write((byte) (0x04 | ((b >> 14) & 0xF8)));
out.write((byte) (b >> 6));
out.write((byte) (0x04 | ((b << 2) & 0xF8)));
out.write(0x01);
out.write(new byte[]{0x00, 0x01, (byte) 0x89, (byte) 0xC3});
out.write(0xF8);
return out.toByteArray();
}
}

+ 0
- 35
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsPesPacket.java View File

@ -1,35 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
import java.io.ByteArrayOutputStream;
public class PsPesPacket {
public static byte[] create(byte[] es, long pts) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{0, 0, 1, (byte) 0xE0});
int len = es.length + 8;
out.write((len >> 8) & 0xFF);
out.write(len & 0xFF);
out.write(0x80);
out.write(0x80);
out.write(0x05);
writePts(out, pts);
out.write(es);
return out.toByteArray();
}
private static void writePts(ByteArrayOutputStream out, long pts) {
long v = pts & 0x1FFFFFFFFL;
out.write((byte) (0x21 | ((v >> 29) & 0x0E)));
out.write((byte) (v >> 22));
out.write((byte) (0x01 | ((v >> 14) & 0xFE)));
out.write((byte) (v >> 7));
out.write((byte) (0x01 | ((v << 1) & 0xFE)));
}
}

+ 0
- 26
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsProgramStreamMap.java View File

@ -1,26 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
import java.io.ByteArrayOutputStream;
public class PsProgramStreamMap {
public static byte[] create() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{0, 0, 1, (byte) 0xBC});
out.write(new byte[]{0x00, 0x12});
out.write(0xE0);
out.write(new byte[]{0x00, 0x00});
out.write(new byte[]{0x00, 0x08});
out.write(0x1B); // H264
out.write(PsConstants.STREAM_ID_VIDEO);
out.write(new byte[]{0x00, 0x00});
out.write(new byte[]{0, 0, 0, 0}); // CRC
return out.toByteArray();
}
}

+ 0
- 21
src/main/java/com/inspect/tcpserver/sip/stream/ps/PsSystemHeader.java View File

@ -1,21 +0,0 @@
package com.inspect.tcpserver.sip.stream.ps;
import java.io.ByteArrayOutputStream;
public class PsSystemHeader {
public static byte[] create() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
out.write(new byte[]{0, 0, 1, (byte) 0xBB});
out.write(new byte[]{0x00, 0x0C});
out.write(new byte[]{(byte) 0x80, 0x04, (byte) 0xE4});
out.write(0x04);
out.write(0xE1);
out.write(new byte[]{0x7F, (byte) 0xE0, 0x7F});
return out.toByteArray();
}
}

+ 2
- 1
src/main/java/com/inspect/tcpserver/sip/utils/DigestUtil.java View File

@ -1,5 +1,6 @@
package com.inspect.tcpserver.sip.utils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
@ -42,7 +43,7 @@ public class DigestUtil {
*/
private static String md5Hex(String data) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(data.getBytes());
byte[] digest = md.digest(data.getBytes(StandardCharsets.UTF_8));
return byteArrayToHexString(digest);
}


+ 8
- 1
src/main/java/com/inspect/tcpserver/sip/utils/SipXmlParser.java View File

@ -3,10 +3,13 @@ package com.inspect.tcpserver.sip.utils;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.inspect.tcpserver.sip.items.DeviceInfoItem;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class SipXmlParser {
private static final XmlMapper XML_MAPPER = new XmlMapper();
@ -41,7 +44,11 @@ public class SipXmlParser {
//String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SIP_XML EventType=\"Device_Info\"></SIP_XML>";//ok
//String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SIP_XML EventType=\"Device_Info\"><Item /></SIP_XML>";
String eventType = SipXmlParser.peekEventType(xml);
System.out.println(eventType);
SipXmlEnvelope<DeviceInfoItem> parse = SipXmlParser.parse(xml, DeviceInfoItem.class);
String eventType1 = parse.getEventType();
List<DeviceInfoItem> items = parse.getItems();
System.out.println(items);
System.out.println(eventType1);
} catch (Exception e) {
e.printStackTrace();
}


+ 20
- 20
src/main/java/com/inspect/tcpserver/tcp/NettyServer.java View File

@ -255,15 +255,15 @@ public class NettyServer {
resetSendMsg(binaryModel.receiveIndex, sendCode);
return;
} else if (code.equals(ResponseType.succeed)) {
log.info(Color.YELLOW + "###### 客户端[{}]响应结果为成功 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]响应结果为成功 ######\n{}" + Color.END, sendCode, compactXml);
if(command == SystemType.no_response) {
return;
}
} else if (code.equals(ResponseType.fault)) {
log.info(Color.RED + "###### 客户端[{}]响应结果为失败 ######" + Color.END, sendCode);
log.info(Color.RED + "###### 客户端[{}]响应结果为失败 ######\n{}" + Color.END, sendCode, compactXml);
return;
} else if (code.equals(ResponseType.reject)) {
log.info(Color.RED + "###### 客户端[{}]响应结果为拒绝 ######" + Color.END, sendCode);
log.info(Color.RED + "###### 客户端[{}]响应结果为拒绝 ######\n{}" + Color.END, sendCode, compactXml);
return;
}
}
@ -275,12 +275,12 @@ public class NettyServer {
switch (command) {
case SystemType.register_request:
// 收到接入侧注册信息
log.info(Color.YELLOW + "###### 客户端[{}]注册 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]注册 ######\n{}" + Color.END, sendCode, compactXml);
dealRegister(binaryModel.uuid, compactXml);
break;
case SystemType.heart_request:
// 处理心跳请求响应
log.info(Color.YELLOW + "###### 客户端[{}]上报心跳 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报心跳 ######\n{}" + Color.END, sendCode, compactXml);
sendHeartBeat(binaryModel.uuid, compactXml);
break;
case SystemType.has_response:
@ -289,7 +289,7 @@ public class NettyServer {
// 处理设备上报的模型同步响应
if (null != root.element("Items").element("Item").attribute("device_file_path")) {
// 收到接入侧模型同步数据
log.info(Color.YELLOW + "###### 模型同步收到客户端[{}]响应数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 模型同步收到客户端[{}]响应数据 ######\n{}" + Color.END, sendCode, compactXml);
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, ModelControl.class);
JSONObject jsonObject = JSONObject.parseObject(json);
jsonObject.put("uuid", binaryModel.uuid);
@ -299,64 +299,64 @@ public class NettyServer {
// 任务控制响应任务执行ID
if (null != root.element("Items").element("Item").attribute("task_patrolled_id")) {
// 收到接入侧任务下发或控制回复数据
log.info(Color.YELLOW + "###### 任务下发收到客户端[{}]响应数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 任务下发收到客户端[{}]响应数据 ######\n{}" + Color.END, sendCode, compactXml);
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, ModelControl.class);
JSONObject jsonObject = JSONObject.parseObject(json);
jsonObject.put("SendCode", "");
upstreamClientController.sendMsg(binaryModel.uuid, jsonObject.toJSONString());
}
} else {
log.info(Color.RED + "###### 客户端[{}]响应数据没有items ######" + Color.END, sendCode);
log.info(Color.RED + "###### 客户端[{}]响应数据没有items ######\n{}" + Color.END, sendCode, compactXml);
}
break;
default:
log.info(Color.RED + "###### 客户端[{}]非法的消息不予处理 ######" + Color.END, sendCode);
log.info(Color.RED + "###### 客户端[{}]非法的消息不予处理 ######\n{}" + Color.END, sendCode, compactXml);
}
break;
case PushType.patrolDeviceState:// insert into basedata_mont_patdevstadata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, PatrolDeviceStateControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备状态数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备状态数据 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.patrolDeviceRunning:// insert into basedata_mont_patdevrundata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, PatrolDeviceRunningControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备运行数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备运行数据 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.nestState:// insert into basedata_mont_neststadata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, NestStateControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢状态数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢状态数据 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.nestRunning:// insert into basedata_mont_nestrundata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, NestRunningControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢运行数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢运行数据 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.location:// insert into basedata_mont_patdevcoord
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, LocationControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备坐标 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备坐标 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.route:// insert into basedata_mont_patdevpatroute
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, RouteControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备路线 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备路线 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.alarm:// insert into basedata_mont_patdevalmabn
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, AlarmControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备异常告警 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备异常告警 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.environment:// insert into basedata_mont_evndata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, EnvironmentControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备环境数据 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备环境数据 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.taskState:// insert into basedata_mont_taskstadata and patrol_task_status
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, TaskStateControl.class);
//root@Linx:/home/atia/data/log/inspect-main# grep -rn "type:41, messageBody:" info.log
log.info(Color.YELLOW + "###### 客户端[{}]上报设备任务状态 ######" + Color.END, sendCode);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备任务状态 ######\n{}" + Color.END, sendCode, compactXml);
break;
case PushType.result:// insert into basedata_mont_taskresult and patrol_task_result_main
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, TaskResultControl.class);
//root@Linx:/home/atia/data/log/inspect-main# grep -rn "type:61, messageBody:" info.log
log.info(Color.YELLOW + "###### 客户端[{}]上报巡视结果 ######\n {}" + Color.END, sendCode, json);
log.info(Color.YELLOW + "###### 客户端[{}]上报巡视结果 ######\n {}" + Color.END, sendCode, compactXml);
break;
default:
log.info(Color.RED + "###### 客户端[{}]上报的非法消息不予处理 ######" + Color.END, sendCode);
log.info(Color.RED + "###### 客户端[{}]上报的非法消息不予处理 ######\n{}" + Color.END, sendCode, compactXml);
}
if (type != SystemType.system && !StringUtil.isNullOrEmpty(json)) {
if ((type == NestCtlType.courseReversal && command == 3)) { // 处理用SSCOM模拟的数据, 向无人机发送控制指令


+ 13
- 0
src/main/java/com/inspect/tcpserver/tcp/NettyServerHandler.java View File

@ -4,6 +4,7 @@ import com.inspect.tcpserver.util.Color;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@ -23,6 +24,18 @@ public class NettyServerHandler extends ChannelInboundHandlerAdapter {
public void sendMsg(String uuid, String clientKey, ByteBuf byteBuf, String xml, boolean request) {
ChannelHandlerContext ctx = ChannelCache.getInstance().get(clientKey);
if(ctx != null) {
// 详细检查 Channel 状态
Channel channel = ctx.channel();
boolean isActive = channel.isActive();
boolean isOpen = channel.isOpen();
boolean isWritable = channel.isWritable();
log.info("clientKey: {} Channel状态 - Active: {}, Open: {}, Writable: {}, Remote: {}",
clientKey, isActive, isOpen, isWritable, channel.remoteAddress());
if (!isActive || !isWritable) {
log.info("Channel不可用,无法发送数据。Active: {}, Writable: {}", isActive, isWritable);
}
// 打印下行报文
ByteBuf forPrint = byteBuf.copy();
log.info("WRITE_AND_FLUSH SESSION :{}, CLIENT: {}, HEX: {}", uuid, ctx.channel().id().asShortText(), ByteBufUtil.hexDump(forPrint));


+ 21
- 2
src/main/resources/application-dev.yml View File

@ -3,12 +3,27 @@ spring:
name: tcpServer
redis:
host: 127.0.0.1
datasource:
url: jdbc:mysql://192.168.1.116:4406/inspect_shaoxing_260511?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: atia2018
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 10
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
rabbitmq:
host: 10.10.18.13
port: 5673
username: guest
password: guest
mybatis:
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: com.inspect.tcpserver.domain
configuration:
map-underscore-to-camel-case: true
server:
port: 22508
@ -52,7 +67,11 @@ sip:
domain: 192.168.1.116 # 平台SIP服务IP或域名
port: 5060
transport: tcp # 也可以为udp
local-ip: 192.168.1.3 # 本服务的外网或可达IP
local-ip: 192.168.1.89 # 本服务的外网或可达IP
local-port: 5061
expires: 3600
zlm:
http-ip: 192.168.1.116
http-port: 33380
secret: Xg@123456

+ 45
- 0
src/main/resources/mapper/ICameraMapper.xml View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.inspect.tcpserver.mapper.ICameraMapper">
<select id="selectCamera" resultType="com.inspect.tcpserver.domain.BasedataEqpBookMoMain">
SELECT
a.eqp_book_id,
a.station_name,
a.station_code,
a.area_id,
a.area_name,
b.channel_name AS patrol_device_name,
b.patrol_device_code,
b.up_system_device_code,
a.device_model,
a.manufacturer,
a.use_unit,
b.device_source,
a.production_date,
a.production_code,
a.is_transport,
ifnull(a.use_mode,b.use_mode) as use_mode,
ifnull(a.video_mode,b.video_mode) as video_mode,
a.place,
a.position_x,
a.position_y,
a.position_z,
a.type,
a.patrol_device_info,
a.robots_code,
b.HOST AS ip_addr,
b.PORT as port,
b.username AS user,
b.`password`,
b.online_state status,
a.main_system_code
from basedata_eqpbook a
inner join basedata_eqpbook_channel b on a.eqp_book_id = b.eqp_book_id
where type in ('10')
</select>
<select id="getBasedataEqpBook" resultType="com.inspect.tcpserver.domain.BasedataEqpBookMoMain">
select channel_id,channel_name,eqp_book_id,channel_code,patrol_device_code from basedata_eqpbook_channel where up_system_device_code = #{upSystemDeviceCode}
</select>
</mapper>

Loading…
Cancel
Save