refactor: onpub and onsub

This commit is contained in:
langhuihui
2024-08-27 13:00:26 +08:00
parent a214f51378
commit 2261d75ac1
24 changed files with 343 additions and 440 deletions

View File

@@ -2,6 +2,10 @@ global:
loglevel: trace
http:
listenaddr: :8082
onpublish:
record:
.* :
filepath: $0
# enableauth: true
# tcp:
# listenaddr: :50051
@@ -22,9 +26,9 @@ rtmp:
subscribe:
# submode: 1
# subaudio: false
pull:
pullonsub:
# live/pull: rtmp://localhost/live/test
onsub:
pull:
live/.*: rtmp://localhost/$0
#flv:
# pull:
# pullonstart:
@@ -33,7 +37,6 @@ gb28181:
sip:
listenaddr:
- udp::5060
pull:
enableregexp: true
pullonsub:
onsubscribe:
pull:
.* : $0

View File

@@ -18,6 +18,5 @@ rtmp:
tcp:
autolisten: false
flv:
pull:
pullonstart:
pull:
live/test: /Users/dexter/Movies/002.flv

53
go.mod
View File

@@ -12,16 +12,18 @@ require (
github.com/emiago/sipgo v0.22.0
github.com/glebarez/sqlite v1.11.0
github.com/go-delve/delve v1.23.0
github.com/gobwas/ws v1.3.2
github.com/google/gopacket v1.1.19
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8
github.com/icholy/digest v0.1.22
github.com/mcuadros/go-defaults v1.2.0
github.com/pion/interceptor v0.1.29
github.com/pion/logging v0.2.2
github.com/pion/rtcp v1.2.14
github.com/pion/rtp v1.8.6
github.com/pion/sdp/v3 v3.0.9
github.com/pion/webrtc/v3 v3.2.12
github.com/polarsignals/frostdb v0.0.0-20240613134636-1d823f7d7299
github.com/quic-go/quic-go v0.43.1
github.com/rs/zerolog v1.33.0
github.com/samber/slog-common v0.17.1
@@ -35,67 +37,35 @@ require (
)
require (
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect
github.com/RoaringBitmap/roaring v1.9.3 // indirect
github.com/VictoriaMetrics/easyproto v0.1.4 // indirect
github.com/VictoriaMetrics/fastcache v1.12.2 // indirect
github.com/VictoriaMetrics/metrics v1.35.1 // indirect
github.com/VictoriaMetrics/metricsql v0.76.0 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/apache/arrow/go/v16 v16.1.0 // indirect
github.com/benbjohnson/immutable v0.4.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.12.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/coreos/etcd v3.3.27+incompatible // indirect
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/efficientgo/core v1.0.0-rc.2 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.3.2 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/flatbuffers v24.3.25+incompatible // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hamba/avro/v2 v2.20.1 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/oklog/ulid/v2 v2.1.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/parquet-go/parquet-go v0.22.0 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pion/datachannel v1.5.6 // indirect
github.com/pion/dtls/v2 v2.2.11 // indirect
github.com/pion/ice/v2 v2.3.9 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.12 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/sctp v1.8.16 // indirect
@@ -103,44 +73,27 @@ require (
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.5 // indirect
github.com/pion/turn/v2 v2.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/planetscale/vtprotobuf v0.6.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polarsignals/iceberg-go v0.0.0-20240502213135-2ee70b71e76b // indirect
github.com/polarsignals/wal v0.0.0-20240514152147-1cd4b81c9b88 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/samber/lo v1.44.0 // indirect
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
github.com/segmentio/encoding v0.3.6 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/thanos-io/objstore v0.0.0-20240512204237-71ef2d0cf7c4 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/valyala/fastrand v1.1.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/valyala/gozstd v1.21.1 // indirect
github.com/valyala/histogram v1.2.0 // indirect
github.com/valyala/quicktemplate v1.8.0 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
golang.org/x/arch v0.6.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect
modernc.org/libc v1.41.0 // indirect
modernc.org/mathutil v1.6.0 // indirect

117
go.sum
View File

@@ -1,9 +1,5 @@
github.com/Eyevinn/mp4ff v0.45.1 h1:Hlx8ZUu8agN7XrHVcZAGIa+dVZ0UW/g/SLv63Pm/+w0=
github.com/Eyevinn/mp4ff v0.45.1/go.mod h1:hJNUUqOBryLAzUW9wpCJyw2HaI+TCd2rUPhafoS5lgg=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/RoaringBitmap/roaring v1.9.3 h1:t4EbC5qQwnisr5PrP9nt0IRhRTb9gMUgQF4t4S2OByM=
github.com/RoaringBitmap/roaring v1.9.3/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
github.com/VictoriaMetrics/VictoriaMetrics v1.102.0 h1:eRi6VGT7ntLG/OW8XTWUYhSvA+qGD3FHaRkzdgYHOOw=
github.com/VictoriaMetrics/VictoriaMetrics v1.102.0/go.mod h1:QZhCsD2l+S+BHTdspVSsE4oiFhdKzgVziSy5Q/FZHcs=
github.com/VictoriaMetrics/easyproto v0.1.4 h1:r8cNvo8o6sR4QShBXQd1bKw/VVLSQma/V2KhTBPf+Sc=
@@ -19,18 +15,8 @@ github.com/alchemy/rotoslog v0.2.2 h1:yzAOjaQBKgJvAdPi0sF5KSPMq5f2vNJZEnPr73CPDz
github.com/alchemy/rotoslog v0.2.2/go.mod h1:pOHF0DKryPLaQzjcUlidLVRTksvk9yW75YIu1yYiiEQ=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/apache/arrow/go/v16 v16.1.0 h1:dwgfOya6s03CzH9JrjCBx6bkVb4yPD4ma3haj9p7FXI=
github.com/apache/arrow/go/v16 v16.1.0/go.mod h1:9wnc9mn6vEDTRIm4+27pEjQpRKuTvBaessPoEXQzxWA=
github.com/asavie/xdp v0.3.3 h1:b5Aa3EkMJYBeUO5TxPTIAa4wyUqYcsQr2s8f6YLJXhE=
github.com/asavie/xdp v0.3.3/go.mod h1:Vv5p+3mZiDh7ImdSvdon3E78wXyre7df5V58ATdIYAY=
github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA=
github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.12.0 h1:U/q1fAF7xXRhFCrhROzIfffYnu+dlS38vCZtmFVPHmA=
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bluenviron/mediacommon v1.9.2 h1:EHcvoC5YMXRcFE010bTNf07ZiSlB/e/AdZyG7GsEYN0=
github.com/bluenviron/mediacommon v1.9.2/go.mod h1:lt8V+wMyPw8C69HAqDWV5tsAwzN9u2Z+ca8B6C//+n0=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -47,13 +33,7 @@ github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk=
github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso=
github.com/cloudwego/goref v0.0.0-20240724113447-685d2a9523c8 h1:K7L7KFg5siEysLit42Bf7n4qNRkGxniPeBtmpsxsfdQ=
github.com/cloudwego/goref v0.0.0-20240724113447-685d2a9523c8/go.mod h1:IMGV1p8Mw3uyZYClI5bA8uqk8LGr/MYFv92V0m88XUk=
github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA=
github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ=
github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/creack/pty v1.1.20 h1:VIPb/a2s17qNeQgDnkfZC35RScx+blkKF8GV68n80J4=
github.com/creack/pty v1.1.20/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -62,12 +42,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deepch/vdk v0.0.27 h1:j/SHaTiZhA47wRpaue8NRp7P9xwOOO/lunxrDJBwcao=
github.com/deepch/vdk v0.0.27/go.mod h1:JlgGyR2ld6+xOIHa7XAxJh+stSDBAkdNvIPkUIdIywk=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/efficientgo/core v1.0.0-rc.2 h1:7j62qHLnrZqO3V3UA0AqOGd5d5aXV3AX6m/NZBHp78I=
github.com/efficientgo/core v1.0.0-rc.2/go.mod h1:FfGdkzWarkuzOlY04VY+bGfb1lWrjaL6x/GLcQ4vJps=
github.com/emiago/sipgo v0.22.0 h1:GaQ51m26M9QnVBVY2aDJ/mXqq/BDfZ1A+nW7XgU/4Ts=
github.com/emiago/sipgo v0.22.0/go.mod h1:a77FgPEEjJvfYWYfP3p53u+dNhWEMb/VGVS6guvBzx0=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
@@ -79,10 +55,6 @@ github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GM
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
github.com/go-delve/delve v1.23.0 h1:jYgZISZ14KAO3ys8kD07kjrowrygE9F9SIwnpz9xXys=
github.com/go-delve/delve v1.23.0/go.mod h1:S3SLuEE2mn7wipKilTvk1p9HdTMnXXElcEpiZ+VcuqU=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
@@ -100,8 +72,6 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q=
github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
@@ -116,8 +86,6 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -127,9 +95,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/pprof v0.0.0-20230309165930-d61513b1440d h1:um9/pc7tKMINFfP1eE7Wv6PRGXlcCSJkVajF7KJw3uQ=
@@ -141,12 +106,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
github.com/hamba/avro/v2 v2.20.1 h1:3WByQiVn7wT7d27WQq6pvBRC00FVOrniP6u67FLA/2E=
github.com/hamba/avro/v2 v2.20.1/go.mod h1:xHiKXbISpb3Ovc809XdzWow+XGTn+Oyf/F9aZbTLAig=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 h1:4Jk58quTZmzJcTrLlbB5L1Q6qXu49EIjCReWxcBFWKo=
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8/go.mod h1:medl9/CfYoQlqAXtAARmMW5dAX2UOdwwkhaszYPk0AM=
@@ -158,12 +119,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -184,31 +141,16 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc=
github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
@@ -222,13 +164,8 @@ github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/parquet-go/parquet-go v0.22.0 h1:9G32efs+11L/MDc0Zt05AuvBubRGAp5lRKufv6pB/B8=
github.com/parquet-go/parquet-go v0.22.0/go.mod h1:3VBP+djJCNuV+D5uSUs2pWQufk2yKO+9pwYvXglsB8Y=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/phsym/console-slog v0.3.1 h1:Fuzcrjr40xTc004S9Kni8XfNsk+qrptQmyR+wZw9/7A=
github.com/phsym/console-slog v0.3.1/go.mod h1:oJskjp/X6e6c0mGpfP8ELkfKUsrkDifYRAqJQgmdDS0=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg=
github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4=
@@ -282,36 +219,16 @@ github.com/pion/turn/v2 v2.1.2/go.mod h1:1kjnPkBcex3dhCU2Am+AAmxDcGhLX3WnMfmkNpv
github.com/pion/webrtc/v3 v3.2.12 h1:pVqz5NdtTqyhKIhMcXR8bPp709kCf9blyAhDjoVRLvA=
github.com/pion/webrtc/v3 v3.2.12/go.mod h1:/Oz6K95CGWaN+3No+Z0NYvgOPOr3aY8UyTlMm/dec3A=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/planetscale/vtprotobuf v0.6.0 h1:nBeETjudeJ5ZgBHUz1fVHvbqUKnYOXNhsIEabROxmNA=
github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polarsignals/frostdb v0.0.0-20240613134636-1d823f7d7299 h1:+hojr9kZJjaP2ec/TAhmk2Cm0H/xyBRW4lbFKNT+71g=
github.com/polarsignals/frostdb v0.0.0-20240613134636-1d823f7d7299/go.mod h1:6n9DbDuO0wTtg26S5hoZzrA+pEQRYAB1mpN5Z4U5nqI=
github.com/polarsignals/iceberg-go v0.0.0-20240502213135-2ee70b71e76b h1:Dbm5itapR0uYIMujR8OntWpDJ/nm5OM6JiaKauLcZ4Y=
github.com/polarsignals/iceberg-go v0.0.0-20240502213135-2ee70b71e76b/go.mod h1:5T9ChEZjRNhAGGLwH1cqzDA7wXB84SmU+WkXQr/ZAjo=
github.com/polarsignals/wal v0.0.0-20240514152147-1cd4b81c9b88 h1:FZvQW8MXcNjwLfWDRAatOA83Pof5+iKW7veuInygBXY=
github.com/polarsignals/wal v0.0.0-20240514152147-1cd4b81c9b88/go.mod h1:EVDHAAe+7GQ33A1/x+/gE+sBPN4toQ0XG5RoLD49xr8=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/quic-go/quic-go v0.43.1 h1:fLiMNfQVe9q2JvSsiXo4fXOEguXHGGl9+6gLp4RPeZQ=
github.com/quic-go/quic-go v0.43.1/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
@@ -328,9 +245,6 @@ github.com/samber/slog-multi v1.0.0/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECt
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM=
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ=
github.com/segmentio/encoding v0.3.6/go.mod h1:n0JeuIqEQrQoPDGsjo8UNd1iA0U8d8+oHAA4E3G3OxM=
github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
@@ -356,8 +270,6 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/thanos-io/objstore v0.0.0-20240512204237-71ef2d0cf7c4 h1:7p7g2AVMNRCTHbtmJVjhNKJhRgiI9U3a9FN5ZfgjJMM=
github.com/thanos-io/objstore v0.0.0-20240512204237-71ef2d0cf7c4/go.mod h1:CuSIQu7lCntygNhEGKdLZLaoA8FtpAiC+454oLTXeUY=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
@@ -368,8 +280,6 @@ github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXV
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8=
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/gozstd v1.21.1 h1:TQFZVTk5zo7iJcX3o4XYBJujPdO31LFb4fVImwK873A=
github.com/valyala/gozstd v1.21.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ=
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
@@ -386,20 +296,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
@@ -465,7 +361,6 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -474,7 +369,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -540,10 +434,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ=
gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A=
@@ -562,6 +452,7 @@ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6h
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

29
pkg/config/listen.go Normal file
View File

@@ -0,0 +1,29 @@
package config
import (
"gopkg.in/yaml.v3"
"strconv"
"strings"
)
type Listen struct {
Protocol string
Host string
Port int
}
func (l *Listen) UnmarshalYAML(node *yaml.Node) (err error) {
vs := strings.Split(node.Value, ":")
vsl := len(vs)
switch vsl {
case 1:
l.Protocol = "tcp"
case 2:
l.Protocol = vs[0]
case 3:
l.Protocol = vs[0]
l.Host = vs[1]
}
l.Port, err = strconv.Atoi(vs[vsl-1])
return
}

View File

@@ -1,9 +1,8 @@
package config
import (
"regexp"
"gopkg.in/yaml.v3"
"regexp"
)
type Regexp struct {

View File

@@ -1,178 +1,92 @@
package config
import (
"fmt"
"m7s.live/m7s/v5/pkg/util"
"regexp"
"strings"
"time"
)
type Publish struct {
MaxCount int `default:"0" desc:"最大发布者数量"` // 最大发布者数量
PubAudio bool `default:"true" desc:"是否发布音频"`
PubVideo bool `default:"true" desc:"是否发布频"`
KickExist bool `desc:"是否踢掉已经存在的发布者"` // 是否踢掉已经存在的发布者
PublishTimeout time.Duration `default:"10s" desc:"发布无数据超时"` // 发布无数据超时
WaitCloseTimeout time.Duration `desc:"延迟自动关闭(等待重连)"` // 延迟自动关闭(等待重连)
DelayCloseTimeout time.Duration `desc:"延迟自动关闭(无订阅时"` // 延迟自动关闭(无订阅时
IdleTimeout time.Duration `desc:"空闲(无订阅)超时"` // 空闲(无订阅)超时
PauseTimeout time.Duration `default:"30s" desc:"暂停超时时间"` // 暂停超时
BufferTime time.Duration `desc:"缓冲时长0代表取最近关键帧"` // 缓冲长度(单位:秒)0代表取最近关键帧
Speed float64 `default:"0" desc:"倍速"` // 倍速0 为不限速
Key string `desc:"发布鉴权key"` // 发布鉴权key
RingSize util.Range[int] `default:"20-1024" desc:"RingSize范围"` // 缓冲区大小范围
Dump bool
}
type Subscribe struct {
MaxCount int `default:"0" desc:"最大订阅者数量"` // 最大订阅者数量
SubAudio bool `default:"true" desc:"是否订阅音频"`
SubVideo bool `default:"true" desc:"是否订阅视频"`
BufferTime time.Duration `desc:"缓冲时长,从缓冲时长的关键帧开始播放"`
SubMode int `desc:"订阅模式" enum:"0:实时模式,1:首屏后不进行追赶"` // 0实时模式追赶发布者进度在播放首屏后等待发布者的下一个关键帧然后跳到该帧。1、首屏后不进行追赶。2、从缓冲最大的关键帧开始播放也不追赶需要发布者配置缓存长度
SyncMode int `default:"1" desc:"同步模式" enum:"0:采用时间戳同步,1:采用写入时间同步"` // 0采用时间戳同步1采用写入时间同步
IFrameOnly bool `desc:"只要关键帧"` // 只要关键帧
WaitTimeout time.Duration `default:"10s" desc:"等待流超时时间"` // 等待流超时
WriteBufferSize int `desc:"写缓冲大小"` // 写缓冲大小
Key string `desc:"订阅鉴权key"` // 订阅鉴权key
Internal bool `default:"false" desc:"是否内部订阅"` // 是否内部订阅
}
type Pull struct {
RePull int `desc:"断开后自动重试次数,0:不重试,-1:无限重试"` // 断开后自动重拉,0 表示不自动重拉,-1 表示无限重拉高于0 的数代表最大重拉次数
EnableRegexp bool `desc:"是否启用正则表达式"` // 是否启用正则表达式
PullOnStart map[string]string `desc:"启动时拉流的列表"` // 启动时拉流的列表
PullOnSub map[string]string `desc:"订阅时自动拉流的列表"` // 订阅时自动拉流的列表
Proxy string `desc:"代理地址"` // 代理地址
Header map[string][]string
}
func (p *Pull) CheckPullOnStart(streamPath string) string {
// p.PullOnStartLocker.RLock()
// defer p.PullOnStartLocker.RUnlock()
if p.PullOnStart == nil {
return ""
type (
Publish struct {
MaxCount int `default:"0" desc:"最大发布者数量"` // 最大发布者数量
PubAudio bool `default:"true" desc:"是否发布频"`
PubVideo bool `default:"true" desc:"是否发布视频"`
KickExist bool `desc:"是否踢掉已经存在的发布者"` // 是否踢掉已经存在的发布者
PublishTimeout time.Duration `default:"10s" desc:"发布无数据超时"` // 发布无数据超时
WaitCloseTimeout time.Duration `desc:"延迟自动关闭(等待重连"` // 延迟自动关闭(等待重连
DelayCloseTimeout time.Duration `desc:"延迟自动关闭(无订阅时)"` // 延迟自动关闭(无订阅时)
IdleTimeout time.Duration `desc:"空闲(无订阅)超时"` // 空闲(无订阅)超时
PauseTimeout time.Duration `default:"30s" desc:"暂停超时时间"` // 暂停超时
BufferTime time.Duration `desc:"缓冲时长0代表取最近关键帧"` // 缓冲长度(单位:秒)0代表取最近关键帧
Speed float64 `default:"0" desc:"倍速"` // 倍速0 为不限速
Key string `desc:"发布鉴权key"` // 发布鉴权key
RingSize util.Range[int] `default:"20-1024" desc:"RingSize范围"` // 缓冲区大小范围
Dump bool
}
url, ok := p.PullOnStart[streamPath]
if !ok && p.EnableRegexp {
for k, url := range p.PullOnStart {
if r, err := regexp.Compile(k); err != nil {
if group := r.FindStringSubmatch(streamPath); group != nil {
for i, value := range group {
url = strings.Replace(url, fmt.Sprintf("$%d", i), value, -1)
}
return url
}
}
return ""
}
Subscribe struct {
MaxCount int `default:"0" desc:"最大订阅者数量"` // 最大订阅者数量
SubAudio bool `default:"true" desc:"是否订阅音频"`
SubVideo bool `default:"true" desc:"是否订阅视频"`
BufferTime time.Duration `desc:"缓冲时长,从缓冲时长的关键帧开始播放"`
SubMode int `desc:"订阅模式" enum:"0:实时模式,1:首屏后不进行追赶"` // 0实时模式追赶发布者进度在播放首屏后等待发布者的下一个关键帧然后跳到该帧。1、首屏后不进行追赶。2、从缓冲最大的关键帧开始播放也不追赶需要发布者配置缓存长度
SyncMode int `default:"1" desc:"同步模式" enum:"0:采用时间戳同步,1:采用写入时间同步"` // 0采用时间戳同步1采用写入时间同步
IFrameOnly bool `desc:"只要关键帧"` // 只要关键帧
WaitTimeout time.Duration `default:"10s" desc:"等待流超时时间"` // 等待流超时
WriteBufferSize int `desc:"写缓冲大小"` // 写缓冲大小
Key string `desc:"订阅鉴权key"` // 订阅鉴权key
Internal bool `default:"false" desc:"是否内部订阅"` // 是否内部订阅
}
return url
}
func (p *Pull) CheckPullOnSub(streamPath string) string {
// p.PullOnSubLocker.RLock()
// defer p.PullOnSubLocker.RUnlock()
if p.PullOnSub == nil {
return ""
Pull struct {
URL string `desc:"拉流地址"`
MaxRetry int `desc:"断开后自动重试次数,0:不重试,-1:无限重试"` // 断开后自动重拉,0 表示不自动重拉,-1 表示无限重拉高于0 的数代表最大重拉次数
Proxy string `desc:"代理地址"` // 代理地址
Header map[string][]string
}
url, ok := p.PullOnSub[streamPath]
if !ok && p.EnableRegexp {
for k, url := range p.PullOnSub {
if r, err := regexp.Compile(k); err == nil {
if group := r.FindStringSubmatch(streamPath); group != nil {
for i, value := range group {
url = strings.Replace(url, fmt.Sprintf("$%d", i), value, -1)
}
return url
}
}
return ""
}
Push struct {
URL string `desc:"推送地址"` // 推送地址
MaxRetry int `desc:"断开后自动重试次数,0:不重试,-1:无限重试"` // 断开后自动重推,0 表示不自动重推,-1 表示无限重推高于0 的数代表最大重推次数
RetryInterval time.Duration `desc:"重试间隔" default:"5s"` // 重试间隔
Proxy string `desc:"代理地址"` // 代理地址
Header map[string][]string
}
return url
}
type Push struct {
EnableRegexp bool `desc:"是否启用正则表达式"` // 是否启用正则表达式
RePush int `desc:"断开后自动重试次数,0:不重试,-1:无限重试"` // 断开后自动重推,0 表示不自动重推,-1 表示无限重推高于0 的数代表最大重推次数
PushList map[string]string `desc:"自动推流列表"` // 自动推流列表
Proxy string `desc:"代理地址"` // 代理地址
Header map[string][]string
}
func (p *Push) AddPush(url string, streamPath string) {
if p.PushList == nil {
p.PushList = make(map[string]string)
Record struct {
FilePath string `desc:"录制文件路径"` // 录制文件路径
Fragment time.Duration `desc:"分片时长"` // 分片时长
Append bool `desc:"是否追加录制"` // 是否追加录制
}
p.PushList[streamPath] = url
}
func (p *Push) CheckPush(streamPath string) string {
url, ok := p.PushList[streamPath]
if !ok && p.EnableRegexp {
for k, url := range p.PushList {
if r, err := regexp.Compile(k); err == nil {
if group := r.FindStringSubmatch(streamPath); group != nil {
for i, value := range group {
url = strings.Replace(url, fmt.Sprintf("$%d", i), value, -1)
}
return url
}
}
return ""
}
Transform struct {
Target string `desc:"转码目标"` // 转码目标
Conf any
}
return url
}
type Record struct {
EnableRegexp bool `desc:"是否启用正则表达式"` // 是否启用正则表达式
RecordList map[string]string
Fragment time.Duration `desc:"分片时长"` // 分片时长
Append bool `desc:"是否追加录制"` // 是否追加录制
}
OnPublish struct {
Push map[Regexp]Push
Record map[Regexp]Record
Transform map[Regexp]Transform
}
OnSubscribe struct {
Pull map[Regexp]Pull
Transform map[Regexp]Transform
}
Common struct {
PublicIP string
PublicIPv6 string
LogLevel string `default:"info" enum:"trace:跟踪,debug:调试,info:信息,warn:警告,error:错误"` //日志级别
EnableAuth bool `desc:"启用鉴权"` //启用鉴权
Publish
Subscribe
HTTP
Quic
TCP
UDP
Pull map[string]Pull
OnSub OnSubscribe
OnPub OnPublish
DB
}
ICommonConf interface {
GetCommonConf() *Common
}
)
func (p *Record) GetRecordConfig() *Record {
return p
}
func (p *Record) CheckRecord(streamPath string) string {
url, ok := p.RecordList[streamPath]
if !ok && p.EnableRegexp {
for k, url := range p.RecordList {
if r, err := regexp.Compile(k); err == nil {
if group := r.FindStringSubmatch(streamPath); group != nil {
for i, value := range group {
url = strings.Replace(url, fmt.Sprintf("$%d", i), value, -1)
}
return url
}
}
return ""
}
}
return url
}
type Common struct {
PublicIP string
PublicIPv6 string
LogLevel string `default:"info" enum:"trace:跟踪,debug:调试,info:信息,warn:警告,error:错误"` //日志级别
EnableAuth bool `desc:"启用鉴权"` //启用鉴权
Publish
Subscribe
HTTP
Quic
TCP
UDP
Pull
Push
Record
DB
}
type ICommonConf interface {
GetCommonConf() *Common
}

View File

@@ -17,9 +17,15 @@ type Manager[K comparable, T ManagerItem[K]] struct {
func (m *Manager[K, T]) Add(ctx T, opt ...any) *Task {
ctx.OnStart(func() {
m.Collection.Add(ctx)
if m.Logger != nil {
m.Logger.Debug("add", "key", ctx.GetKey(), "count", m.Length)
}
})
ctx.OnDispose(func() {
m.Remove(ctx)
if m.Logger != nil {
m.Logger.Debug("remove", "key", ctx.GetKey(), "count", m.Length)
}
})
return m.AddTask(ctx, opt...)
}

View File

@@ -46,6 +46,7 @@ type (
TaskState byte
TaskType byte
ITask interface {
context.Context
keepalive() bool
getParent() *Job
GetParent() ITask

View File

@@ -56,7 +56,8 @@ type (
task.IJob
OnInit() error
OnStop()
Pull(path string, url string)
Pull(string, config.Pull)
Transform(string, config.Transform)
}
IRegisterHandler interface {
@@ -78,6 +79,10 @@ type (
IQUICPlugin interface {
OnQUICConnect(quic.Connection) task.ITask
}
IListenPublishPlugin interface {
OnPublish(*Publisher) task.ITask
}
)
var plugins []PluginMeta
@@ -182,6 +187,8 @@ func InstallPlugin[C iPlugin](options ...any) error {
meta.Pusher = v
case Recorder:
meta.Recorder = v
case Transformer:
meta.Transformer = v
case AuthPublisher:
meta.OnAuthPub = v
case AuthSubscriber:
@@ -196,6 +203,8 @@ func InstallPlugin[C iPlugin](options ...any) error {
return nil
}
var _ IPlugin = (*Plugin)(nil)
type Plugin struct {
task.Work
Disabled bool
@@ -400,24 +409,24 @@ func (p *Plugin) Subscribe(ctx context.Context, streamPath string) (subscriber *
return p.SubscribeWithConfig(ctx, streamPath, p.config.Subscribe)
}
func (p *Plugin) Pull(streamPath string, url string) {
func (p *Plugin) Pull(streamPath string, conf config.Pull) {
puller := p.Meta.Puller()
puller.GetPullJob().Init(puller, p, streamPath, url)
puller.GetPullJob().Init(puller, p, streamPath, conf)
}
func (p *Plugin) Push(streamPath string, url string) {
func (p *Plugin) Push(streamPath string, conf config.Push) {
pusher := p.Meta.Pusher()
pusher.GetPushJob().Init(pusher, p, streamPath, url)
pusher.GetPushJob().Init(pusher, p, streamPath, conf)
}
func (p *Plugin) Record(streamPath string, filePath string) {
func (p *Plugin) Record(streamPath string, conf config.Record) {
recorder := p.Meta.Recorder()
recorder.GetRecordJob().Init(recorder, p, streamPath, filePath)
recorder.GetRecordJob().Init(recorder, p, streamPath, conf)
}
func (p *Plugin) Transform(fromStreamPath, toStreamPath string) {
func (p *Plugin) Transform(streamPath string, conf config.Transform) {
transformer := p.Meta.Transformer()
transformer.GetTransformJob().Init(transformer, p, fromStreamPath, toStreamPath)
transformer.GetTransformJob().Init(transformer, p, streamPath, conf)
}
func (p *Plugin) registerHandler(handlers map[string]http.HandlerFunc) {

View File

@@ -292,11 +292,11 @@ func (gb *GB28181Plugin) StoreDevice(id string, req *sip.Request) (d *Device) {
return
}
func (gb *GB28181Plugin) Pull(streamPath, url string) {
func (gb *GB28181Plugin) Pull(streamPath string, conf config.Pull) {
dialog := Dialog{
gb: gb,
}
dialog.GetPullJob().Init(&dialog, &gb.Plugin, streamPath, url)
dialog.GetPullJob().Init(&dialog, &gb.Plugin, streamPath, conf)
}
func (gb *GB28181Plugin) GetPullableList() []string {

View File

@@ -41,7 +41,7 @@ func (p *PreviewPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
} else if plugin.Meta.Puller != nil {
s += fmt.Sprintf("<h3>%s</h3>", plugin.Meta.Name)
for _, streamPath := range slices.Collect(maps.Keys(plugin.GetCommonConf().PullOnSub)) {
for _, streamPath := range slices.Collect(maps.Keys(plugin.GetCommonConf().OnSub.Pull)) {
s += fmt.Sprintf("<a href='%s'>%s</a><br>", streamPath, streamPath)
}
}

View File

@@ -3,12 +3,13 @@ package plugin_rtmp
import (
"context"
gpb "m7s.live/m7s/v5/pb"
"m7s.live/m7s/v5/pkg/config"
"m7s.live/m7s/v5/plugin/rtmp/pb"
rtmp "m7s.live/m7s/v5/plugin/rtmp/pkg"
)
func (r *RTMPPlugin) PushOut(ctx context.Context, req *pb.PushRequest) (res *gpb.SuccessResponse, err error) {
pusher := rtmp.NewPusher()
err = pusher.GetPushJob().Init(pusher, &r.Plugin, req.StreamPath, req.RemoteURL).WaitStarted()
err = pusher.GetPushJob().Init(pusher, &r.Plugin, req.StreamPath, config.Push{URL: req.RemoteURL}).WaitStarted()
return &gpb.SuccessResponse{}, err
}

View File

@@ -3,6 +3,7 @@ package plugin_stress
import (
"context"
"fmt"
"m7s.live/m7s/v5/pkg/config"
"google.golang.org/protobuf/types/known/emptypb"
"m7s.live/m7s/v5"
@@ -18,7 +19,7 @@ func (r *StressPlugin) pull(count int, format, url string, puller m7s.Puller) (e
if i := r.pullers.Length; count > i {
for j := i; j < count; j++ {
p := puller()
ctx := p.GetPullJob().Init(p, &r.Plugin, fmt.Sprintf("stress/%d", j), fmt.Sprintf(format, url))
ctx := p.GetPullJob().Init(p, &r.Plugin, fmt.Sprintf("stress/%d", j), config.Pull{URL: fmt.Sprintf(format, url, j)})
if err = ctx.WaitStarted(); err != nil {
return
}
@@ -40,7 +41,7 @@ func (r *StressPlugin) push(count int, streamPath, format, remoteHost string, pu
if i := r.pushers.Length; count > i {
for j := i; j < count; j++ {
p := pusher()
ctx := p.GetPushJob().Init(p, &r.Plugin, streamPath, fmt.Sprintf(format, remoteHost, j))
ctx := p.GetPushJob().Init(p, &r.Plugin, streamPath, config.Push{URL: fmt.Sprintf(format, remoteHost, j)})
if err = ctx.WaitStarted(); err != nil {
return
}

16
plugin/transcode/index.go Normal file
View File

@@ -0,0 +1,16 @@
package plugin_transcode
import (
"m7s.live/m7s/v5"
transcode "m7s.live/m7s/v5/plugin/transcode/pkg"
)
var (
//_ m7s.IListenPublishPlugin = (*TranscodePlugin)(nil)
_ = m7s.InstallPlugin[TranscodePlugin](transcode.NewTransform)
)
type TranscodePlugin struct {
m7s.Plugin
Rules []transcode.TransRule
}

View File

@@ -0,0 +1,49 @@
package transcode
import "m7s.live/m7s/v5"
// / 定义传输模式的常量
const (
TRANS_MODE_PIPE TransMode = "pipe"
TRANS_MODE_RTSP TransMode = "rtsp"
TRANS_MODE_RTMP TransMode = "rtmp"
TRANS_MODE_LIB TransMode = "lib"
)
type (
TransMode string
DecodeConfig struct {
Codec string `json:"codec" desc:"解码器"`
Track string `json:"track" desc:"待解码的 track 名称"`
Args string `json:"args" desc:"解码参数"`
}
EncodeConfig struct {
Codec string `json:"codec" desc:"编码器"`
Track string `json:"track" desc:"待编码的 track 名称"`
Args string `json:"args" desc:"编码参数"`
Dest string `json:"dest" desc:"目标主机路径"`
}
TransRule struct {
From DecodeConfig `json:"from"`
To []EncodeConfig `json:"to" desc:"编码配置"` //目标
Mode TransMode `json:"mode" desc:"转码模式"` //转码模式
LogToFile bool `json:"logtofile" desc:"转码是否写入日志"` //转码日志写入文件
PreStart bool `json:"prestart" desc:"是否预转码"` //预转码
}
)
func NewTransform() m7s.ITransformer {
return &Transformer{}
}
type Transformer struct {
m7s.DefaultTransformer
}
func (t *Transformer) Start() (err error) {
err = t.TransformJob.Subscribe()
if err == nil {
}
return
}

View File

@@ -5,6 +5,7 @@ import (
_ "embed"
"github.com/pion/logging"
"io"
"m7s.live/m7s/v5/pkg/config"
"net"
"net/http"
"regexp"
@@ -147,8 +148,8 @@ func (p *WebRTCPlugin) testPage(w http.ResponseWriter, r *http.Request) {
io.Copy(w, f)
}
func (p *WebRTCPlugin) Pull(streamPath, url string) {
if strings.HasPrefix(url, "https://rtc.live.cloudflare.com") {
func (p *WebRTCPlugin) Pull(streamPath string, conf config.Pull) {
if strings.HasPrefix(conf.URL, "https://rtc.live.cloudflare.com") {
cfClient := NewCFClient(DIRECTION_PULL)
var err error
cfClient.PeerConnection, err = p.api.NewPeerConnection(Configuration{
@@ -159,6 +160,6 @@ func (p *WebRTCPlugin) Pull(streamPath, url string) {
p.Error("pull", "error", err)
return
}
cfClient.GetPullJob().Init(cfClient, &p.Plugin, streamPath, url)
cfClient.GetPullJob().Init(cfClient, &p.Plugin, streamPath, conf)
}
}

View File

@@ -2,12 +2,14 @@ package m7s
import (
"context"
"fmt"
"m7s.live/m7s/v5/pkg/task"
"math"
"os"
"path/filepath"
"reflect"
"slices"
"strings"
"sync"
"time"
@@ -147,9 +149,7 @@ func (p *Publisher) Start() (err error) {
s := p.Plugin.Server
if oldPublisher, ok := s.Streams.Get(p.StreamPath); ok {
if p.KickExist {
p.Warn("kick")
p.takeOver(oldPublisher)
oldPublisher.Stop(ErrKick)
} else {
return ErrStreamExist
}
@@ -173,16 +173,41 @@ func (p *Publisher) Start() (err error) {
if plugin.Disabled {
continue
}
if remoteURL := plugin.GetCommonConf().CheckPush(p.StreamPath); remoteURL != "" {
if plugin.Meta.Pusher != nil {
plugin.Push(p.StreamPath, remoteURL)
onPublish := plugin.GetCommonConf().OnPub
if plugin.Meta.Pusher != nil {
for r, pushConf := range onPublish.Push {
if group := r.FindStringSubmatch(p.StreamPath); group != nil {
for i, g := range group {
pushConf.URL = strings.Replace(pushConf.URL, fmt.Sprintf("$%d", i), g, -1)
}
plugin.Push(p.StreamPath, pushConf)
}
}
}
if filePath := plugin.GetCommonConf().CheckRecord(p.StreamPath); filePath != "" {
if plugin.Meta.Recorder != nil {
plugin.Record(p.StreamPath, filePath)
if plugin.Meta.Recorder != nil {
for r, recConf := range onPublish.Record {
if group := r.FindStringSubmatch(p.StreamPath); group != nil {
for i, g := range group {
recConf.FilePath = strings.Replace(recConf.FilePath, fmt.Sprintf("$%d", i), g, -1)
}
plugin.Record(p.StreamPath, recConf)
}
}
}
if plugin.Meta.Transformer != nil {
for r, tranConf := range onPublish.Transform {
if group := r.FindStringSubmatch(p.StreamPath); group != nil {
for i, g := range group {
tranConf.Target = strings.Replace(tranConf.Target, fmt.Sprintf("$%d", i), g, -1)
}
plugin.Transform(p.StreamPath, tranConf)
}
}
}
if v, ok := plugin.handler.(IListenPublishPlugin); ok {
v.OnPublish(p)
}
}
p.AddTask(&PublishTimeout{Publisher: p})
if p.PublishTimeout > 0 {
@@ -520,9 +545,11 @@ func (p *Publisher) HasVideoTrack() bool {
func (p *Publisher) Dispose() {
s := p.Plugin.Server
s.Streams.Remove(p)
if !p.StopReasonIs(ErrKick) {
s.Streams.Remove(p)
}
if p.Subscribers.Length > 0 {
w := p.Plugin.Server.createWait(p.StreamPath)
w := s.createWait(p.StreamPath)
w.baseTs = p.lastTs
w.Info("takeOver", "pId", p.ID)
for subscriber := range p.SubscriberRange {
@@ -542,6 +569,7 @@ func (p *Publisher) Dispose() {
func (p *Publisher) takeOver(old *Publisher) {
p.baseTs = old.lastTs
old.Stop(ErrKick)
p.Info("takeOver", "old", old.ID)
for subscriber := range old.SubscriberRange {
p.AddSubscriber(subscriber)

View File

@@ -20,6 +20,7 @@ type (
StreamPath string // 对应本地流
RemoteURL string // 远程服务器地址(用于推拉)
HTTPClient *http.Client
Header http.Header
}
IPuller interface {
@@ -33,8 +34,7 @@ type (
Connection
Publisher *Publisher
publishConfig *config.Publish
config.Pull
puller IPuller
puller IPuller
}
HTTPFilePuller struct {
@@ -44,10 +44,11 @@ type (
}
)
func (conn *Connection) Init(plugin *Plugin, streamPath string, href string, proxyConf string) {
func (conn *Connection) Init(plugin *Plugin, streamPath string, href string, proxyConf string, header http.Header) {
conn.RemoteURL = href
conn.StreamPath = streamPath
conn.Plugin = plugin
conn.Header = header
conn.HTTPClient = http.DefaultClient
if proxyConf != "" {
proxy, err := url.Parse(proxyConf)
@@ -63,19 +64,20 @@ func (p *PullJob) GetPullJob() *PullJob {
return p
}
func (p *PullJob) Init(puller IPuller, plugin *Plugin, streamPath string, url string) *PullJob {
func (p *PullJob) Init(puller IPuller, plugin *Plugin, streamPath string, conf config.Pull) *PullJob {
publishConfig := plugin.config.Publish
publishConfig.PublishTimeout = 0
p.Pull = plugin.config.Pull
p.publishConfig = &publishConfig
p.Connection.Init(plugin, streamPath, url, plugin.config.Pull.Proxy)
p.Logger = plugin.Logger.With("pullURL", url, "streamPath", streamPath)
if pullerTask := puller.GetTask(); pullerTask.Logger == nil {
pullerTask.Logger = p.Logger
}
p.Connection.Init(plugin, streamPath, conf.URL, conf.Proxy, conf.Header)
p.puller = puller
puller.SetRetry(plugin.config.Pull.RePull, time.Second*5)
plugin.Server.Pulls.Add(p)
p.Description = map[string]any{
"plugin": plugin.Meta.Name,
"streamPath": streamPath,
"url": conf.URL,
"maxRetry": conf.MaxRetry,
}
puller.SetRetry(conf.MaxRetry, time.Second*5)
plugin.Server.Pulls.Add(p, plugin.Logger.With("pullURL", conf.URL, "streamPath", streamPath))
return p
}
@@ -93,15 +95,10 @@ func (p *PullJob) Start() (err error) {
if _, ok := s.Pulls.Get(p.GetKey()); ok {
return pkg.ErrStreamExist
}
s.Pulls.Add(p)
s.AddTask(p.puller)
p.AddTask(p.puller, p.Logger)
return
}
func (p *PullJob) Dispose() {
p.Plugin.Server.Pulls.Remove(p)
}
func (p *HTTPFilePuller) Start() (err error) {
if err = p.PullJob.Publish(); err != nil {
return

View File

@@ -1,8 +1,6 @@
package m7s
import (
"time"
"m7s.live/m7s/v5/pkg"
"m7s.live/m7s/v5/pkg/task"
@@ -19,24 +17,24 @@ type Pusher = func() IPusher
type PushJob struct {
Connection
Subscriber *Subscriber
config.Push
pusher IPusher
pusher IPusher
}
func (p *PushJob) GetKey() string {
return p.RemoteURL
return p.Connection.RemoteURL
}
func (p *PushJob) Init(pusher IPusher, plugin *Plugin, streamPath string, url string) *PushJob {
p.Push = plugin.config.Push
p.Connection.Init(plugin, streamPath, url, plugin.config.Push.Proxy)
p.Logger = plugin.Logger.With("pushURL", url, "streamPath", streamPath)
if pusherTask := pusher.GetTask(); pusherTask.Logger == nil {
pusherTask.Logger = p.Logger
}
func (p *PushJob) Init(pusher IPusher, plugin *Plugin, streamPath string, conf config.Push) *PushJob {
p.Connection.Init(plugin, streamPath, conf.URL, conf.Proxy, conf.Header)
p.pusher = pusher
pusher.SetRetry(plugin.config.RePush, time.Second*5)
plugin.Server.Pushs.Add(p)
p.Description = map[string]any{
"plugin": plugin.Meta.Name,
"streamPath": streamPath,
"url": conf.URL,
"maxRetry": conf.MaxRetry,
}
pusher.SetRetry(conf.MaxRetry, conf.RetryInterval)
plugin.Server.Pushs.Add(p, plugin.Logger.With("pushURL", conf.URL, "streamPath", streamPath))
return p
}
@@ -50,11 +48,6 @@ func (p *PushJob) Start() (err error) {
if _, ok := s.Pushs.Get(p.GetKey()); ok {
return pkg.ErrPushRemoteURLExist
}
s.Pushs.Add(p)
p.AddTask(p.pusher)
p.AddTask(p.pusher, p.Logger)
return
}
func (p *PushJob) Dispose() {
p.Plugin.Server.Pushs.Remove(p)
}

View File

@@ -1,6 +1,7 @@
package m7s
import (
"m7s.live/m7s/v5/pkg/config"
"os"
"path/filepath"
"time"
@@ -49,18 +50,21 @@ func (p *RecordJob) Subscribe() (err error) {
return
}
func (p *RecordJob) Init(recorder IRecorder, plugin *Plugin, streamPath string, filePath string) *RecordJob {
func (p *RecordJob) Init(recorder IRecorder, plugin *Plugin, streamPath string, conf config.Record) *RecordJob {
p.Plugin = plugin
p.Fragment = plugin.config.Record.Fragment
p.Append = plugin.config.Record.Append
p.FilePath = filePath
p.Fragment = conf.Fragment
p.Append = conf.Append
p.FilePath = conf.FilePath
p.StreamPath = streamPath
p.Logger = plugin.Logger.With("filePath", filePath, "streamPath", streamPath)
if recorderTask := recorder.GetTask(); recorderTask.Logger == nil {
recorderTask.Logger = p.Logger
}
p.recorder = recorder
plugin.Server.Records.Add(p)
p.Description = map[string]any{
"plugin": plugin.Meta.Name,
"streamPath": streamPath,
"filePath": conf.FilePath,
"append": conf.Append,
"fragment": conf.Fragment,
}
plugin.Server.Records.Add(p, plugin.Logger.With("filePath", conf.FilePath, "streamPath", streamPath))
return p
}
@@ -76,12 +80,10 @@ func (p *RecordJob) Start() (err error) {
}
dir = filepath.Dir(p.FilePath)
}
p.Description = map[string]any{
"filePath": p.FilePath,
}
p.Description["filePath"] = p.FilePath
if err = os.MkdirAll(dir, 0755); err != nil {
return
}
p.AddTask(p.recorder)
p.AddTask(p.recorder, p.Logger)
return
}

View File

@@ -242,8 +242,8 @@ func (s *Server) Start() (err error) {
s.Post(func() error {
for plugin := range s.Plugins.Range {
if plugin.Meta.Puller != nil {
for streamPath, url := range plugin.config.PullOnStart {
plugin.handler.Pull(streamPath, url)
for streamPath, conf := range plugin.config.Pull {
plugin.handler.Pull(streamPath, conf)
}
}
}

View File

@@ -2,6 +2,7 @@ package m7s
import (
"errors"
"fmt"
"net/url"
"reflect"
"runtime"
@@ -88,9 +89,22 @@ func (s *Subscriber) Start() (err error) {
} else {
server.createWait(s.StreamPath).Add(s)
for plugin := range server.Plugins.Range {
if remoteURL := plugin.GetCommonConf().Pull.CheckPullOnSub(s.StreamPath); remoteURL != "" {
for reg, conf := range plugin.GetCommonConf().OnSub.Pull {
if plugin.Meta.Puller != nil {
plugin.handler.Pull(s.StreamPath, remoteURL)
if group := reg.FindStringSubmatch(s.StreamPath); group != nil {
for i, value := range group {
conf.URL = strings.Replace(conf.URL, fmt.Sprintf("$%d", i), value, -1)
}
}
plugin.handler.Pull(s.StreamPath, conf)
}
}
for reg, conf := range plugin.GetCommonConf().OnSub.Transform {
// TODO:
if plugin.Meta.Transformer != nil {
if reg.MatchString(s.StreamPath) {
plugin.handler.Transform(s.StreamPath, conf)
}
}
}
}

View File

@@ -2,6 +2,7 @@ package m7s
import (
"m7s.live/m7s/v5/pkg"
"m7s.live/m7s/v5/pkg/config"
"m7s.live/m7s/v5/pkg/task"
)
@@ -13,12 +14,12 @@ type (
Transformer = func() ITransformer
TransformJob struct {
task.Job
FromStreamPath string // 待转换的本地流
ToStreamPath string // 转换后的本地
Plugin *Plugin
Publisher *Publisher
Subscriber *Subscriber
transformer ITransformer
StreamPath string // 对应本地流
Target string // 对应目标
Plugin *Plugin
Publisher *Publisher
Subscriber *Subscriber
transformer ITransformer
}
DefaultTransformer struct {
task.Task
@@ -39,29 +40,30 @@ func (r *DefaultTransformer) Start() (err error) {
}
func (p *TransformJob) GetKey() string {
return p.ToStreamPath
return p.Target
}
func (p *TransformJob) Subscribe() (err error) {
p.Subscriber, err = p.Plugin.Subscribe(p.transformer.GetTask().Context, p.FromStreamPath)
p.Subscriber, err = p.Plugin.Subscribe(p.transformer, p.StreamPath)
return
}
func (p *TransformJob) Publish() (err error) {
p.Publisher, err = p.Plugin.Publish(p.transformer.GetTask().Context, p.ToStreamPath)
p.Publisher, err = p.Plugin.Publish(p.transformer, p.Target)
return
}
func (p *TransformJob) Init(transformer ITransformer, plugin *Plugin, fromStreamPath string, toStreamPath string) *TransformJob {
func (p *TransformJob) Init(transformer ITransformer, plugin *Plugin, streamPath string, conf config.Transform) *TransformJob {
p.Plugin = plugin
p.FromStreamPath = fromStreamPath
p.ToStreamPath = toStreamPath
p.Logger = plugin.Logger.With("fromStreamPath", fromStreamPath, "toStreamPath", toStreamPath)
if recorderTask := transformer.GetTask(); recorderTask.Logger == nil {
recorderTask.Logger = p.Logger
}
p.Target = conf.Target
p.StreamPath = streamPath
p.transformer = transformer
plugin.Server.Transforms.Add(p)
p.Description = map[string]any{
"streamPath": streamPath,
"target": conf.Target,
"conf": conf.Conf,
}
plugin.Server.Transforms.Add(p, plugin.Logger.With("streamPath", streamPath))
return p
}
@@ -70,11 +72,6 @@ func (p *TransformJob) Start() (err error) {
if _, ok := s.Transforms.Get(p.GetKey()); ok {
return pkg.ErrRecordSamePath
}
s.Transforms.Add(p)
s.AddTask(p.transformer)
p.AddTask(p.transformer, p.Logger)
return
}
func (p *TransformJob) Dispose() {
p.Plugin.Server.Transforms.Remove(p)
}