mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 09:52:06 +08:00
feat: dynamic buffer time
This commit is contained in:
6
api.go
6
api.go
@@ -65,7 +65,7 @@ func (s *Server) api_Stream_AnnexB_(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
rw.Header().Set("Content-Type", "application/octet-stream")
|
||||
reader := pkg.NewAVRingReader(publisher.VideoTrack.AVTrack)
|
||||
err = reader.StartRead(publisher.VideoTrack.IDRing.Load())
|
||||
err = reader.StartRead(publisher.VideoTrack.GetIDR())
|
||||
if err != nil {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -81,7 +81,7 @@ func (s *Server) api_Stream_AnnexB_(rw http.ResponseWriter, r *http.Request) {
|
||||
var annexb pkg.AnnexB
|
||||
var t pkg.AVTrack
|
||||
|
||||
annexb.DecodeConfig(&t, publisher.VideoTrack.ICodecCtx)
|
||||
err = annexb.DecodeConfig(&t, publisher.VideoTrack.ICodecCtx)
|
||||
if t.ICodecCtx == nil {
|
||||
http.Error(rw, "unsupported codec", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -91,7 +91,7 @@ func (s *Server) api_Stream_AnnexB_(rw http.ResponseWriter, r *http.Request) {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
frame.(*pkg.AnnexB).WriteTo(rw)
|
||||
_, err = frame.(*pkg.AnnexB).WriteTo(rw)
|
||||
}
|
||||
|
||||
func (s *Server) getStreamInfo(pub *Publisher) (res *pb.StreamInfoResponse, err error) {
|
||||
|
74
go.mod
74
go.mod
@@ -10,24 +10,60 @@ require (
|
||||
github.com/pion/interceptor v0.1.29
|
||||
github.com/pion/rtcp v1.2.14
|
||||
github.com/pion/rtp v1.8.6
|
||||
github.com/polarsignals/frostdb v0.0.0-20240613134636-1d823f7d7299
|
||||
github.com/q191201771/naza v0.30.48
|
||||
github.com/quic-go/quic-go v0.43.1
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de
|
||||
google.golang.org/grpc v1.63.2
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237
|
||||
google.golang.org/grpc v1.64.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.3 // 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.1 // 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/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/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // 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-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/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.10 // indirect
|
||||
github.com/pion/ice/v3 v3.0.7 // indirect
|
||||
@@ -41,15 +77,31 @@ require (
|
||||
github.com/pion/transport/v2 v2.2.4 // indirect
|
||||
github.com/pion/transport/v3 v3.0.2 // indirect
|
||||
github.com/pion/turn/v3 v3.0.3 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.0 // 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.5.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||
github.com/segmentio/encoding v0.3.6 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // 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/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.opentelemetry.io/otel v1.27.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.27.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -65,11 +117,11 @@ require (
|
||||
github.com/pion/webrtc/v4 v4.0.0-beta.13
|
||||
github.com/shirou/gopsutil/v3 v3.24.3
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/crypto v0.22.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/tools v0.9.1 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
172
go.sum
172
go.sum
@@ -1,8 +1,24 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/alchemy/rotoslog v0.2.2 h1:yzAOjaQBKgJvAdPi0sF5KSPMq5f2vNJZEnPr73CPDzQ=
|
||||
github.com/alchemy/rotoslog v0.2.2/go.mod h1:pOHF0DKryPLaQzjcUlidLVRTksvk9yW75YIu1yYiiEQ=
|
||||
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/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.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732 h1:XYUCaZrW8ckGWlCRJKCSoh/iFwlpX316a8yY9IFEzv8=
|
||||
github.com/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
|
||||
github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93rg=
|
||||
@@ -20,14 +36,30 @@ github.com/cnotch/queue v0.0.0-20200326024423-6e88bdbf2ad4/go.mod h1:zOssjAlNusO
|
||||
github.com/cnotch/queue v0.0.0-20201224060551-4191569ce8f6/go.mod h1:zOssjAlNusOxvtaqT+EMA+Iyi8rrtKr4/XfzN1Fgoeg=
|
||||
github.com/cnotch/scheduler v0.0.0-20200522024700-1d2da93eefc5/go.mod h1:F4GE3SZkJZ8an1Y0ZCqvSM3jeozNuKzoC67erG1PhIo=
|
||||
github.com/cnotch/xlog v0.0.0-20201208005456-cfda439cd3a0/go.mod h1:RW9oHsR79ffl3sR3yMGgxYupMn2btzdtJUwoxFPUE5E=
|
||||
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/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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/emitter-io/address v1.0.0/go.mod h1:GfZb5+S/o8694B1GMGK2imUYQyn2skszMvGNA5D84Ug=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
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.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
@@ -39,6 +71,8 @@ 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/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=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
@@ -50,6 +84,10 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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=
|
||||
@@ -58,6 +96,9 @@ 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/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -67,30 +108,59 @@ 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/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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
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/kelindar/process v0.0.0-20170730150328-69a29e249ec3/go.mod h1:+lTCLnZFXOkqwD8sLPl6u4erAc0cP8wFegQHfipz7KE=
|
||||
github.com/kelindar/rate v1.0.0/go.mod h1:AjT4G+hTItNwt30lucEGZIz8y7Uk5zPho6vurIZ+1Es=
|
||||
github.com/kelindar/tcp v1.0.0/go.mod h1:JB5hj1cshLU60XrLij2BBxW3JQ4hOye8vqbyvuKb52k=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
|
||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
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/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/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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@@ -106,8 +176,13 @@ 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=
|
||||
@@ -162,14 +237,35 @@ github.com/pion/turn/v3 v3.0.3/go.mod h1:vw0Dz420q7VYAF3J4wJKzReLHIo2LGp4ev8nXQe
|
||||
github.com/pion/webrtc/v4 v4.0.0-beta.13 h1:nIhz2viUhaFvKlbLDpF/XQqlsS+PhfYTxd8qcAo1pL8=
|
||||
github.com/pion/webrtc/v4 v4.0.0-beta.13/go.mod h1:ojwmbdrsIkmRXPumQf9OFIkTJVB9AV/Z9ItMpNvsuhM=
|
||||
github.com/pixelbender/go-sdp v1.1.0/go.mod h1:6IBlz9+BrUHoFTea7gcp4S54khtOhjCW/nVDLhmZBAs=
|
||||
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/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.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/q191201771/naza v0.30.48 h1:lbYUaa7A15kJKYwOiU4AbFS1Zo8oQwppl2tLEbJTqnw=
|
||||
github.com/q191201771/naza v0.30.48/go.mod h1:n+dpJjQSh90PxBwxBNuifOwQttywvSIN5TkWSSYCeBk=
|
||||
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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/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/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
@@ -179,6 +275,9 @@ github.com/samber/slog-formatter v1.0.0/go.mod h1:c7pRfwhCfZQNzJz+XirmTveElxXln7
|
||||
github.com/samber/slog-multi v1.0.0 h1:snvP/P5GLQ8TQh5WSqdRaxDANW8AAA3egwEoytLsqvc=
|
||||
github.com/samber/slog-multi v1.0.0/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo=
|
||||
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=
|
||||
@@ -190,8 +289,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
@@ -199,6 +300,8 @@ 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=
|
||||
@@ -207,6 +310,20 @@ 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.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
|
||||
go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
|
||||
go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
|
||||
go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
|
||||
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/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -219,15 +336,15 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -244,13 +361,15 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -261,12 +380,14 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/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=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -279,8 +400,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -300,8 +421,9 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -309,20 +431,22 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
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-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@@ -3,6 +3,7 @@ package pkg
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"m7s.live/m7s/v5/pkg/config"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,6 @@ const (
|
||||
|
||||
type AVRingReader struct {
|
||||
RingReader
|
||||
mode int
|
||||
Track *AVTrack
|
||||
State byte
|
||||
FirstSeq uint32
|
||||
@@ -40,22 +40,18 @@ func (r *AVRingReader) DecConfChanged() bool {
|
||||
|
||||
func NewAVRingReader(t *AVTrack) *AVRingReader {
|
||||
t.Debug("create reader")
|
||||
t.Ready.Await()
|
||||
t.Info("reader +1", "count", t.ReaderCount.Add(1))
|
||||
return &AVRingReader{
|
||||
Track: t,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *AVRingReader) readFrame() (err error) {
|
||||
err = r.ReadNext()
|
||||
if err != nil {
|
||||
return err
|
||||
func (r *AVRingReader) readFrame(mode int) (err error) {
|
||||
if err = r.ReadNext(); err != nil {
|
||||
return
|
||||
}
|
||||
// 超过一半的缓冲区大小,说明Reader太慢,需要丢帧
|
||||
if r.mode != SUBMODE_BUFFER && r.State == READSTATE_NORMAL && r.Track.LastValue.Sequence-r.Value.Sequence > uint32(r.Track.Size/2) {
|
||||
idr := r.Track.IDRing.Load()
|
||||
if idr != nil && idr.Value.Sequence > r.Value.Sequence {
|
||||
if mode != SUBMODE_BUFFER && r.State == READSTATE_NORMAL && r.Track.LastValue.Sequence-r.Value.Sequence > uint32(r.Track.Size/2) {
|
||||
if idr := r.Track.GetIDR(); idr != nil && idr.Value.Sequence > r.Value.Sequence {
|
||||
r.Warn("reader too slow", "lastSeq", r.Track.LastValue.Sequence, "seq", r.Value.Sequence)
|
||||
return r.Read(idr)
|
||||
}
|
||||
@@ -63,19 +59,18 @@ func (r *AVRingReader) readFrame() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (r *AVRingReader) ReadFrame(mode int) (err error) {
|
||||
r.mode = mode
|
||||
func (r *AVRingReader) ReadFrame(conf *config.Subscribe) (err error) {
|
||||
switch r.State {
|
||||
case READSTATE_INIT:
|
||||
r.Info("start read", "mode", mode)
|
||||
r.Info("start read", "mode", conf.SubMode)
|
||||
startRing := r.Track.Ring
|
||||
idr := r.Track.IDRing.Load()
|
||||
idr := r.Track.GetIDR()
|
||||
if idr != nil {
|
||||
startRing = idr
|
||||
} else {
|
||||
r.Warn("no IDRring", "track", r.Track.FourCC().String())
|
||||
}
|
||||
switch mode {
|
||||
switch conf.SubMode {
|
||||
case SUBMODE_REAL:
|
||||
if idr != nil {
|
||||
r.State = READSTATE_FIRST
|
||||
@@ -85,7 +80,16 @@ func (r *AVRingReader) ReadFrame(mode int) (err error) {
|
||||
case SUBMODE_NOJUMP:
|
||||
r.State = READSTATE_NORMAL
|
||||
case SUBMODE_BUFFER:
|
||||
if idr := r.Track.HistoryRing.Load(); idr != nil {
|
||||
for {
|
||||
currentBft := r.Track.CurrentBufferTime()
|
||||
if delta := conf.BufferTime - currentBft; delta > 0 {
|
||||
r.Info("wait buffer", "currentBft", currentBft, "delta", delta)
|
||||
time.Sleep(delta)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if idr := r.Track.GetHistoryIDR(conf.BufferTime); idr != nil {
|
||||
startRing = idr
|
||||
}
|
||||
r.State = READSTATE_NORMAL
|
||||
@@ -101,7 +105,7 @@ func (r *AVRingReader) ReadFrame(mode int) (err error) {
|
||||
r.FirstSeq = r.Value.Sequence
|
||||
r.Info("first frame read", "firstTs", r.FirstTs, "firstSeq", r.FirstSeq)
|
||||
case READSTATE_FIRST:
|
||||
if idr := r.Track.IDRing.Load(); idr.Value.Sequence != r.FirstSeq {
|
||||
if idr := r.Track.GetIDR(); idr.Value.Sequence != r.FirstSeq {
|
||||
if err = r.Read(idr); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -109,7 +113,7 @@ func (r *AVRingReader) ReadFrame(mode int) (err error) {
|
||||
r.Info("jump", "skipSeq", idr.Value.Sequence-r.FirstSeq, "skipTs", r.SkipTs)
|
||||
r.State = READSTATE_NORMAL
|
||||
} else {
|
||||
if err = r.readFrame(); err != nil {
|
||||
if err = r.readFrame(conf.SubMode); err != nil {
|
||||
return
|
||||
}
|
||||
r.beforeJump = r.Value.Timestamp - r.FirstTs
|
||||
@@ -119,7 +123,7 @@ func (r *AVRingReader) ReadFrame(mode int) (err error) {
|
||||
}
|
||||
}
|
||||
case READSTATE_NORMAL:
|
||||
if err = r.readFrame(); err != nil {
|
||||
if err = r.readFrame(conf.SubMode); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -85,7 +85,7 @@ func (config *Config) Get(key string) (v *Config) {
|
||||
}
|
||||
}
|
||||
|
||||
func (config Config) Has(key string) (ok bool) {
|
||||
func (config *Config) Has(key string) (ok bool) {
|
||||
if config.propsMap == nil {
|
||||
return false
|
||||
}
|
||||
@@ -116,19 +116,26 @@ func (config *Config) Parse(s any, prefix ...string) {
|
||||
if t.Kind() == reflect.Pointer {
|
||||
t, v = t.Elem(), v.Elem()
|
||||
}
|
||||
|
||||
config.Ptr = v
|
||||
config.Default = v.Interface()
|
||||
if len(prefix) > 0 { // 读取环境变量
|
||||
envKey := strings.Join(prefix, "_")
|
||||
if envValue := os.Getenv(envKey); envValue != "" {
|
||||
envv := config.assign(strings.ToLower(prefix[0]), envValue)
|
||||
config.Env = envv.Interface()
|
||||
config.Ptr.Set(envv)
|
||||
|
||||
if l := len(prefix); l > 0 { // 读取环境变量
|
||||
name := strings.ToLower(prefix[l-1])
|
||||
if tag := config.tag.Get("default"); tag != "" {
|
||||
v.Set(config.assign(name, tag))
|
||||
config.Default = v.Interface()
|
||||
}
|
||||
if envValue := os.Getenv(strings.Join(prefix, "_")); envValue != "" {
|
||||
v.Set(config.assign(name, envValue))
|
||||
config.Env = v.Interface()
|
||||
}
|
||||
}
|
||||
|
||||
if t.Kind() == reflect.Struct && t != regexpType {
|
||||
for i, j := 0, t.NumField(); i < j; i++ {
|
||||
ft, fv := t.Field(i), v.Field(i)
|
||||
|
||||
if !ft.IsExported() {
|
||||
continue
|
||||
}
|
||||
@@ -143,8 +150,9 @@ func (config *Config) Parse(s any, prefix ...string) {
|
||||
name, _, _ = strings.Cut(tag, ",")
|
||||
}
|
||||
prop := config.Get(name)
|
||||
prop.Parse(fv, append(prefix, strings.ToUpper(ft.Name))...)
|
||||
|
||||
prop.tag = ft.Tag
|
||||
prop.Parse(fv, append(prefix, strings.ToUpper(ft.Name))...)
|
||||
for _, kv := range strings.Split(ft.Tag.Get("enum"), ",") {
|
||||
kvs := strings.Split(kv, ":")
|
||||
if len(kvs) != 2 {
|
||||
@@ -340,8 +348,7 @@ func (config *Config) assign(k string, v any) (target reflect.Value) {
|
||||
},
|
||||
})
|
||||
tmpValue := reflect.New(tmpStruct)
|
||||
tmpByte, _ := yaml.Marshal(map[string]any{k: v})
|
||||
yaml.Unmarshal(tmpByte, tmpValue.Interface())
|
||||
yaml.Unmarshal([]byte(fmt.Sprintf("%s: %v", k, v)), tmpValue.Interface())
|
||||
target = tmpValue.Elem().Field(0)
|
||||
}
|
||||
return
|
||||
|
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"m7s.live/m7s/v5/pkg/util"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -31,13 +32,10 @@ type Publish struct {
|
||||
DelayCloseTimeout time.Duration `desc:"延迟自动关闭(无订阅时)"` // 延迟自动关闭(无订阅时)
|
||||
IdleTimeout time.Duration `desc:"空闲(无订阅)超时"` // 空闲(无订阅)超时
|
||||
PauseTimeout time.Duration `default:"30s" desc:"暂停超时时间"` // 暂停超时
|
||||
BufferTime time.Duration `desc:"缓冲长度(单位:秒),0代表取最近关键帧"` // 缓冲长度(单位:秒),0代表取最近关键帧
|
||||
BufferTime time.Duration `desc:"缓冲时长,0代表取最近关键帧"` // 缓冲长度(单位:秒),0代表取最近关键帧
|
||||
Speed float64 `default:"0" desc:"倍速"` // 倍速,0 为不限速
|
||||
Key string `desc:"发布鉴权key"` // 发布鉴权key
|
||||
SecretArgName string `default:"secret" desc:"发布鉴权参数名"` // 发布鉴权参数名
|
||||
ExpireArgName string `default:"expire" desc:"发布鉴权失效时间参数名"` // 发布鉴权失效时间参数名
|
||||
MinRingSize int `default:"100" desc:"最小 RingSize"` // 最小缓冲区大小
|
||||
MaxRingSize int `default:"1024" desc:"最大 RingSize"` // 最大缓冲区大小
|
||||
RingSize util.Range[int] `default:"20-1024" desc:"RingSize范围"` // 缓冲区大小范围
|
||||
}
|
||||
|
||||
func (c *Publish) GetPublishConfig() *Publish {
|
||||
@@ -47,21 +45,13 @@ func (c *Publish) GetPublishConfig() *Publish {
|
||||
type Subscribe struct {
|
||||
SubAudio bool `default:"true" desc:"是否订阅音频"`
|
||||
SubVideo bool `default:"true" desc:"是否订阅视频"`
|
||||
SubVideoArgName string `default:"vts" desc:"定订阅的视频轨道参数名"` // 指定订阅的视频轨道参数名
|
||||
SubAudioArgName string `default:"ats" desc:"指定订阅的音频轨道参数名"` // 指定订阅的音频轨道参数名
|
||||
SubDataArgName string `default:"dts" desc:"指定订阅的数据轨道参数名"` // 指定订阅的数据轨道参数名
|
||||
SubModeArgName string `desc:"指定订阅的模式参数名"` // 指定订阅的模式参数名
|
||||
SubAudioTracks []string `desc:"指定订阅的音频轨道"` // 指定订阅的音频轨道
|
||||
SubVideoTracks []string `desc:"指定订阅的视频轨道"` // 指定订阅的视频轨道
|
||||
SubDataTracks []string `desc:"指定订阅的数据轨道"` // 指定订阅的数据轨道
|
||||
SubMode int `desc:"订阅模式" enum:"0:实时模式,1:首屏后不进行追赶,2:从缓冲最大的关键帧开始播放"` // 0,实时模式:追赶发布者进度,在播放首屏后等待发布者的下一个关键帧,然后跳到该帧。1、首屏后不进行追赶。2、从缓冲最大的关键帧开始播放,也不追赶,需要发布者配置缓存长度
|
||||
BufferTime time.Duration `desc:"缓冲时长,submode=2时有效"`
|
||||
SubMode int `desc:"订阅模式" enum:"0:实时模式,1:首屏后不进行追赶,2:从缓冲时长的关键帧开始播放"` // 0,实时模式:追赶发布者进度,在播放首屏后等待发布者的下一个关键帧,然后跳到该帧。1、首屏后不进行追赶。2、从缓冲最大的关键帧开始播放,也不追赶,需要发布者配置缓存长度
|
||||
SyncMode int `desc:"同步模式" enum:"0:采用时间戳同步,1:采用写入时间同步"` // 0,采用时间戳同步,1,采用写入时间同步
|
||||
IFrameOnly bool `desc:"只要关键帧"` // 只要关键帧
|
||||
WaitTimeout time.Duration `default:"10s" desc:"等待流超时时间"` // 等待流超时
|
||||
WriteBufferSize int `desc:"写缓冲大小"` // 写缓冲大小
|
||||
Key string `desc:"订阅鉴权key"` // 订阅鉴权key
|
||||
SecretArgName string `default:"secret" desc:"订阅鉴权参数名"` // 订阅鉴权参数名
|
||||
ExpireArgName string `default:"expire" desc:"订阅鉴权失效时间参数名"` // 订阅鉴权失效时间参数名
|
||||
Internal bool `default:"false" desc:"是否内部订阅"` // 是否内部订阅
|
||||
}
|
||||
|
||||
|
@@ -1,40 +1,48 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"m7s.live/m7s/v5/pkg/util"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RingWriter struct {
|
||||
*util.Ring[AVFrame]
|
||||
IDRingList //最近的关键帧位置,首屏渲染
|
||||
ReaderCount atomic.Int32
|
||||
sync.RWMutex
|
||||
IDRingList util.List[*util.Ring[AVFrame]] // 关键帧链表
|
||||
BufferRange util.Range[time.Duration]
|
||||
SizeRange util.Range[int]
|
||||
pool *util.Ring[AVFrame]
|
||||
poolSize int
|
||||
Size int
|
||||
LastValue *AVFrame
|
||||
SLogger *slog.Logger
|
||||
}
|
||||
|
||||
func NewRingWriter(n int) (rb *RingWriter) {
|
||||
func NewRingWriter(sizeRange util.Range[int]) (rb *RingWriter) {
|
||||
rb = &RingWriter{
|
||||
Size: n,
|
||||
Ring: util.NewRing[AVFrame](n),
|
||||
Size: sizeRange[0],
|
||||
Ring: util.NewRing[AVFrame](sizeRange[0]),
|
||||
SizeRange: sizeRange,
|
||||
}
|
||||
rb.LastValue = &rb.Value
|
||||
rb.LastValue.StartWrite()
|
||||
rb.IDRingList.Init()
|
||||
return
|
||||
}
|
||||
|
||||
func (rb *RingWriter) Resize(size int) {
|
||||
if size > 0 {
|
||||
rb.Glow(size)
|
||||
rb.glow(size)
|
||||
} else {
|
||||
rb.Reduce(-size)
|
||||
rb.reduce(-size)
|
||||
}
|
||||
}
|
||||
|
||||
func (rb *RingWriter) Glow(size int) (newItem *util.Ring[AVFrame]) {
|
||||
func (rb *RingWriter) glow(size int) (newItem *util.Ring[AVFrame]) {
|
||||
before, poolBefore := rb.Size, rb.poolSize
|
||||
if newCount := size - rb.poolSize; newCount > 0 {
|
||||
newItem = util.NewRing[AVFrame](newCount).Link(rb.pool)
|
||||
rb.poolSize = 0
|
||||
@@ -47,50 +55,117 @@ func (rb *RingWriter) Glow(size int) (newItem *util.Ring[AVFrame]) {
|
||||
}
|
||||
rb.Link(newItem)
|
||||
rb.Size += size
|
||||
rb.SLogger.Debug("glow", "size", fmt.Sprintf("%d -> %d", before, rb.Size), "pool", fmt.Sprintf("%d -> %d", poolBefore, rb.poolSize))
|
||||
return
|
||||
}
|
||||
|
||||
func (rb *RingWriter) recycle(r *util.Ring[AVFrame]) {
|
||||
if rb.pool == nil {
|
||||
rb.pool = r
|
||||
} else {
|
||||
rb.pool.Link(r)
|
||||
}
|
||||
}
|
||||
|
||||
func (rb *RingWriter) Reduce(size int) (r *util.Ring[AVFrame]) {
|
||||
r = rb.Unlink(size)
|
||||
func (rb *RingWriter) reduce(size int) {
|
||||
before, poolBefore := rb.Size, rb.poolSize
|
||||
r := rb.Unlink(size)
|
||||
rb.Size -= size
|
||||
for range size {
|
||||
if r.Value.TryLock() {
|
||||
rb.poolSize++
|
||||
r.Value.Reset()
|
||||
r.Value.Unlock()
|
||||
} else {
|
||||
rb.SLogger.Debug("discard", "seq", r.Value.Sequence)
|
||||
r.Value.Discard()
|
||||
r = r.Prev()
|
||||
r.Unlink(1)
|
||||
}
|
||||
r = r.Next()
|
||||
}
|
||||
rb.recycle(r)
|
||||
rb.Size -= size
|
||||
return
|
||||
if poolBefore != rb.poolSize {
|
||||
if rb.pool == nil {
|
||||
rb.pool = r
|
||||
} else {
|
||||
rb.pool.Link(r)
|
||||
}
|
||||
}
|
||||
rb.SLogger.Debug("reduce", "size", fmt.Sprintf("%d -> %d", before, rb.Size), "pool", fmt.Sprintf("%d -> %d", poolBefore, rb.poolSize))
|
||||
}
|
||||
|
||||
func (rb *RingWriter) Dispose() {
|
||||
rb.SLogger.Debug("dispose")
|
||||
rb.Value.Ready()
|
||||
}
|
||||
|
||||
func (rb *RingWriter) GetIDR() *util.Ring[AVFrame] {
|
||||
rb.RLock()
|
||||
defer rb.RUnlock()
|
||||
return rb.IDRingList.Back().Value
|
||||
}
|
||||
|
||||
func (rb *RingWriter) GetHistoryIDR(bufTime time.Duration) *util.Ring[AVFrame] {
|
||||
rb.RLock()
|
||||
defer rb.RUnlock()
|
||||
for item := rb.IDRingList.Back(); item != nil; item = item.Prev() {
|
||||
if item.Value.Value.Timestamp-rb.LastValue.Timestamp > bufTime {
|
||||
return item.Value
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rb *RingWriter) durationFrom(from *util.Ring[AVFrame]) time.Duration {
|
||||
return rb.Value.Timestamp - from.Value.Timestamp
|
||||
}
|
||||
|
||||
func (rb *RingWriter) CurrentBufferTime() time.Duration {
|
||||
return rb.BufferRange[1]
|
||||
}
|
||||
|
||||
func (rb *RingWriter) Step() (normal bool) {
|
||||
isIDR := rb.Value.IDR
|
||||
next := rb.Next()
|
||||
if isIDR {
|
||||
rb.SLogger.Debug("add idr")
|
||||
rb.Lock()
|
||||
rb.IDRingList.PushBack(rb.Ring)
|
||||
rb.Unlock()
|
||||
}
|
||||
if rb.IDRingList.Len() > 0 {
|
||||
oldIDR := rb.IDRingList.Front()
|
||||
rb.BufferRange[1] = rb.durationFrom(oldIDR.Value)
|
||||
// do not remove only idr
|
||||
if next == rb.IDRingList.Back().Value {
|
||||
if rb.Size < rb.SizeRange[1] {
|
||||
rb.glow(5)
|
||||
next = rb.Next()
|
||||
}
|
||||
} else if next == oldIDR.Value {
|
||||
if nextOld := oldIDR.Next(); nextOld != nil && rb.durationFrom(nextOld.Value) > rb.BufferRange[0] {
|
||||
rb.SLogger.Debug("remove old idr")
|
||||
rb.Lock()
|
||||
rb.IDRingList.Remove(oldIDR)
|
||||
rb.Unlock()
|
||||
} else {
|
||||
rb.SLogger.Debug("not enough buffer")
|
||||
rb.glow(5)
|
||||
next = rb.Next()
|
||||
}
|
||||
} else if rb.BufferRange[1] > rb.BufferRange[0] {
|
||||
for tmpP, reduceCount := rb.Next(), 0; reduceCount < 5; reduceCount++ {
|
||||
if tmpP == oldIDR.Value {
|
||||
break
|
||||
}
|
||||
if tmpP = tmpP.Next(); reduceCount == 4 && rb.Size > rb.SizeRange[0] {
|
||||
rb.reduce(5)
|
||||
next = rb.Next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb.LastValue = &rb.Value
|
||||
nextSeq := rb.LastValue.Sequence + 1
|
||||
next := rb.Next()
|
||||
if normal = next.Value.StartWrite(); normal {
|
||||
next.Value.Reset()
|
||||
rb.Ring = next
|
||||
} else {
|
||||
rb.Reduce(1) //抛弃还有订阅者的节点
|
||||
rb.Ring = rb.Glow(1) //补充一个新节点
|
||||
rb.reduce(1) //抛弃还有订阅者的节点
|
||||
rb.Ring = rb.glow(1) //补充一个新节点
|
||||
normal = rb.Value.StartWrite()
|
||||
if !normal {
|
||||
panic("RingWriter.Step")
|
||||
|
25
pkg/track.go
25
pkg/track.go
@@ -3,9 +3,8 @@ package pkg
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"m7s.live/m7s/v5/pkg/config"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"m7s.live/m7s/v5/pkg/util"
|
||||
@@ -27,12 +26,6 @@ type (
|
||||
Track
|
||||
}
|
||||
|
||||
IDRingList struct {
|
||||
IDRList []*AVRing
|
||||
IDRing atomic.Pointer[AVRing]
|
||||
HistoryRing atomic.Pointer[AVRing]
|
||||
}
|
||||
|
||||
AVTrack struct {
|
||||
Track
|
||||
*RingWriter
|
||||
@@ -57,8 +50,10 @@ func NewAVTrack(args ...any) (t *AVTrack) {
|
||||
case *AVTrack:
|
||||
t.Logger = v.Logger.With("subtrack", t.FrameType.String())
|
||||
t.RingWriter = v.RingWriter
|
||||
case int:
|
||||
t.RingWriter = NewRingWriter(v)
|
||||
case *config.Publish:
|
||||
t.RingWriter = NewRingWriter(v.RingSize)
|
||||
t.BufferRange[0] = v.BufferTime
|
||||
t.RingWriter.SLogger = t.Logger
|
||||
}
|
||||
}
|
||||
t.Ready = util.NewPromise(struct{}{})
|
||||
@@ -85,13 +80,3 @@ func (t *Track) AddBytesIn(n int) {
|
||||
func (t *Track) Trace(msg string, fields ...any) {
|
||||
t.Log(context.TODO(), TraceLevel, msg, fields...)
|
||||
}
|
||||
|
||||
func (p *IDRingList) AddIDR(IDRing *AVRing) {
|
||||
p.IDRList = append(p.IDRList, IDRing)
|
||||
p.IDRing.Store(IDRing)
|
||||
}
|
||||
|
||||
func (p *IDRingList) ShiftIDR() {
|
||||
p.IDRList = slices.Delete(p.IDRList, 0, 1)
|
||||
p.HistoryRing.Store(p.IDRList[0])
|
||||
}
|
||||
|
@@ -94,14 +94,7 @@ func (r *BufReader) ReadBE32(n int) (num uint32, err error) {
|
||||
}
|
||||
|
||||
func (r *BufReader) Skip(n int) (err error) {
|
||||
r.recycleFront()
|
||||
for r.buf.Length < n {
|
||||
if err = r.eat(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
r.buf.RangeN(n, nil)
|
||||
return
|
||||
return r.ReadRange(n, nil)
|
||||
}
|
||||
|
||||
func (r *BufReader) ReadRange(n int, yield func([]byte)) (err error) {
|
||||
@@ -112,13 +105,24 @@ func (r *BufReader) ReadRange(n int, yield func([]byte)) (err error) {
|
||||
return
|
||||
}
|
||||
n -= r.buf.Length
|
||||
if yield != nil {
|
||||
r.buf.Range(yield)
|
||||
}
|
||||
r.buf.MoveToEnd()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (r *BufReader) ReadNto(n int, to []byte) (err error) {
|
||||
l := 0
|
||||
return r.ReadRange(n, func(buf []byte) {
|
||||
ll := len(buf)
|
||||
copy(to[l:l+ll], buf)
|
||||
l += ll
|
||||
})
|
||||
}
|
||||
|
||||
func (r *BufReader) ReadBytes(n int) (mem Memory, err error) {
|
||||
err = r.ReadRange(n, func(buf []byte) {
|
||||
mem.Buffers = append(mem.Buffers, buf)
|
||||
|
@@ -140,8 +140,8 @@ func (sma *ScalableMemoryAllocator) Recycle() {
|
||||
}
|
||||
|
||||
func (sma *ScalableMemoryAllocator) Malloc(size int) (memory []byte) {
|
||||
if sma == nil {
|
||||
return make([]byte, size)
|
||||
if sma == nil || size > MaxBlockSize {
|
||||
return
|
||||
}
|
||||
if EnableCheckSize {
|
||||
defer sma.checkSize()
|
||||
@@ -162,9 +162,6 @@ func (sma *ScalableMemoryAllocator) Malloc(size int) (memory []byte) {
|
||||
child = GetMemoryAllocator(sma.childSize)
|
||||
sma.size += child.Size
|
||||
memory = child.Malloc(size)
|
||||
if memory == nil {
|
||||
panic(fmt.Errorf("malloc faild %d", size))
|
||||
}
|
||||
sma.children = append(sma.children, child)
|
||||
return
|
||||
}
|
||||
@@ -204,7 +201,9 @@ type RecyclableMemory struct {
|
||||
|
||||
func (r *RecyclableMemory) NextN(size int) (memory []byte) {
|
||||
memory = r.ScalableMemoryAllocator.Malloc(size)
|
||||
if r.RecycleIndexes != nil {
|
||||
if memory == nil {
|
||||
memory = make([]byte, size)
|
||||
} else if r.RecycleIndexes != nil {
|
||||
r.RecycleIndexes = append(r.RecycleIndexes, r.Count())
|
||||
}
|
||||
r.Append(memory)
|
||||
|
37
pkg/util/range.go
Normal file
37
pkg/util/range.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Range[T ~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr] [2]T
|
||||
|
||||
func (r *Range[T]) Size() T {
|
||||
return r[1] - r[0]
|
||||
}
|
||||
|
||||
func (r *Range[T]) Within(x T) bool {
|
||||
return x >= r[0] && x <= r[1]
|
||||
}
|
||||
|
||||
func (r *Range[T]) Valid() bool {
|
||||
return r.Size() >= 0
|
||||
}
|
||||
|
||||
func (r *Range[T]) UnmarshalYAML(value *yaml.Node) error {
|
||||
ss := strings.Split(value.Value, "-")
|
||||
i64, err := strconv.ParseInt(ss[0], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r[0] = T(i64)
|
||||
i64, err = strconv.ParseInt(ss[1], 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r[1] = T(i64)
|
||||
return nil
|
||||
}
|
20
plugin.go
20
plugin.go
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
|
||||
gatewayRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/mcuadros/go-defaults"
|
||||
"google.golang.org/grpc"
|
||||
"gopkg.in/yaml.v3"
|
||||
. "m7s.live/m7s/v5/pkg"
|
||||
@@ -35,7 +34,6 @@ func (plugin *PluginMeta) Init(s *Server, userConfig map[string]any) {
|
||||
if !ok {
|
||||
panic("plugin must implement IPlugin")
|
||||
}
|
||||
defaults.SetDefaults(instance)
|
||||
p := reflect.ValueOf(instance).Elem().FieldByName("Plugin").Addr().Interface().(*Plugin)
|
||||
p.handler = instance
|
||||
p.Meta = plugin
|
||||
@@ -49,6 +47,7 @@ func (plugin *PluginMeta) Init(s *Server, userConfig map[string]any) {
|
||||
}
|
||||
p.Config.Parse(p.GetCommonConf())
|
||||
p.Config.Parse(instance, strings.ToUpper(plugin.Name))
|
||||
|
||||
for _, fname := range MergeConfigs {
|
||||
if name := strings.ToLower(fname); p.Config.Has(name) {
|
||||
p.Config.Get(name).ParseGlobal(s.Config.Get(name))
|
||||
@@ -62,8 +61,9 @@ func (plugin *PluginMeta) Init(s *Server, userConfig map[string]any) {
|
||||
p.Config.ParseDefaultYaml(defaultConf)
|
||||
}
|
||||
}
|
||||
|
||||
p.Config.ParseUserFile(userConfig)
|
||||
finalConfig, _ := yaml.Marshal(p.Config.GetMap())
|
||||
p.Debug("config", "detail", string(finalConfig))
|
||||
if s.DisableAll {
|
||||
p.Disabled = true
|
||||
}
|
||||
@@ -274,8 +274,7 @@ func (p *Plugin) Publish(streamPath string, options ...any) (publisher *Publishe
|
||||
if onAuthPub, ok := p.server.OnAuthPubs[p.Meta.Name]; ok {
|
||||
authPromise := util.NewPromise(publisher)
|
||||
onAuthPub(authPromise)
|
||||
<-authPromise.Done()
|
||||
if err = context.Cause(authPromise.Context); err != util.ErrResolve {
|
||||
if _, err = authPromise.Await(); err != nil {
|
||||
p.Warn("auth failed", "error", err)
|
||||
return
|
||||
}
|
||||
@@ -287,7 +286,7 @@ func (p *Plugin) Publish(streamPath string, options ...any) (publisher *Publishe
|
||||
v(&publisher.Publish)
|
||||
}
|
||||
}
|
||||
publisher.Init(p, streamPath, options...)
|
||||
publisher.Init(p, streamPath, &publisher.Publish, options...)
|
||||
_, err = p.server.Call(publisher)
|
||||
return
|
||||
}
|
||||
@@ -310,7 +309,7 @@ func (p *Plugin) Pull(streamPath string, url string, options ...any) (puller *Pu
|
||||
}()
|
||||
}
|
||||
}
|
||||
puller.Init(p, streamPath, options...)
|
||||
puller.Init(p, streamPath, &puller.Publish, options...)
|
||||
_, err = p.server.Call(puller)
|
||||
return
|
||||
}
|
||||
@@ -321,8 +320,7 @@ func (p *Plugin) Subscribe(streamPath string, options ...any) (subscriber *Subsc
|
||||
if onAuthSub, ok := p.server.OnAuthSubs[p.Meta.Name]; ok {
|
||||
authPromise := util.NewPromise(subscriber)
|
||||
onAuthSub(authPromise)
|
||||
<-authPromise.Done()
|
||||
if err = context.Cause(authPromise.Context); err != util.ErrResolve {
|
||||
if _, err = authPromise.Await(); err != nil {
|
||||
p.Warn("auth failed", "error", err)
|
||||
return
|
||||
}
|
||||
@@ -334,7 +332,7 @@ func (p *Plugin) Subscribe(streamPath string, options ...any) (subscriber *Subsc
|
||||
v(&subscriber.Subscribe)
|
||||
}
|
||||
}
|
||||
subscriber.Init(p, streamPath, options...)
|
||||
subscriber.Init(p, streamPath, &subscriber.Subscribe, options...)
|
||||
_, err = p.server.Call(subscriber)
|
||||
return
|
||||
}
|
||||
@@ -379,7 +377,7 @@ func (p *Plugin) Push(streamPath string, url string, options ...any) (pusher *Pu
|
||||
}()
|
||||
}
|
||||
}
|
||||
pusher.Init(p, streamPath, options...)
|
||||
pusher.Init(p, streamPath, &pusher.Subscribe, options...)
|
||||
_, err = p.server.Call(pusher)
|
||||
return
|
||||
}
|
||||
|
@@ -6,14 +6,13 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/quic-go/quic-go"
|
||||
"io"
|
||||
"m7s.live/m7s/v5"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
"m7s.live/m7s/v5"
|
||||
)
|
||||
|
||||
type myResponseWriter struct {
|
||||
@@ -59,12 +58,12 @@ type ConsolePlugin struct {
|
||||
|
||||
var _ = m7s.InstallPlugin[ConsolePlugin]()
|
||||
|
||||
func (cfg *ConsolePlugin) OnInit() error {
|
||||
func (cfg *ConsolePlugin) connect() (conn quic.Connection, err error) {
|
||||
tlsConf := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
NextProtos: []string{"monibuca"},
|
||||
}
|
||||
conn, err := quic.DialAddr(cfg.Context, cfg.Server, tlsConf, &quic.Config{
|
||||
conn, err = quic.DialAddr(cfg.Context, cfg.Server, tlsConf, &quic.Config{
|
||||
KeepAlivePeriod: time.Second * 10,
|
||||
EnableDatagrams: true,
|
||||
})
|
||||
@@ -77,7 +76,7 @@ func (cfg *ConsolePlugin) OnInit() error {
|
||||
if err = json.Unmarshal(msg[:len(msg)-1], &rMessage); err == nil {
|
||||
if rMessage["code"].(float64) != 0 {
|
||||
// cfg.Error("response from console server ", cfg.Server, rMessage["msg"])
|
||||
return fmt.Errorf("response from console server %s %s", cfg.Server, rMessage["msg"])
|
||||
return nil, fmt.Errorf("response from console server %s %s", cfg.Server, rMessage["msg"])
|
||||
} else {
|
||||
// cfg.reportStream = stream
|
||||
cfg.Info("response from console server ", cfg.Server, rMessage)
|
||||
@@ -93,16 +92,27 @@ func (cfg *ConsolePlugin) OnInit() error {
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (cfg *ConsolePlugin) OnInit() error {
|
||||
conn, err := cfg.connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
for !cfg.IsStopped() {
|
||||
for err == nil {
|
||||
var s quic.Stream
|
||||
if s, err = conn.AcceptStream(cfg.Context); err == nil {
|
||||
go cfg.ReceiveRequest(s, conn)
|
||||
}
|
||||
}
|
||||
if !cfg.IsStopped() {
|
||||
<-time.After(time.Second)
|
||||
cfg.OnInit()
|
||||
time.Sleep(time.Second)
|
||||
conn, err = cfg.connect()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
return err
|
||||
|
@@ -60,7 +60,7 @@ func (puller *HDLPuller) Connect(p *m7s.Client) (err error) {
|
||||
var flvHead [3]byte
|
||||
var version, flag byte
|
||||
var reader = head.NewReader()
|
||||
reader.ReadByteTo(&flvHead[0], &flvHead[1], &flvHead[2], &version, &flag)
|
||||
err = reader.ReadByteTo(&flvHead[0], &flvHead[1], &flvHead[2], &version, &flag)
|
||||
if flvHead != [...]byte{'F', 'L', 'V'} {
|
||||
err = errors.New("not flv file")
|
||||
} else {
|
||||
@@ -102,16 +102,19 @@ func (puller *HDLPuller) Pull(p *m7s.Puller) (err error) {
|
||||
if startTs == 0 {
|
||||
startTs = timestamp
|
||||
}
|
||||
puller.ReadBE(3) // stream id always 0
|
||||
var frame rtmp.RTMPData
|
||||
frame.ScalableMemoryAllocator = puller.ScalableMemoryAllocator
|
||||
mem, err := puller.ReadBytes(int(dataSize))
|
||||
if err != nil {
|
||||
if _, err = puller.ReadBE(3); err != nil { // stream id always 0
|
||||
return err
|
||||
}
|
||||
switch t {
|
||||
var frame rtmp.RTMPData
|
||||
switch ds := int(dataSize); t {
|
||||
case FLV_TAG_TYPE_AUDIO, FLV_TAG_TYPE_VIDEO:
|
||||
mem.CopyTo(frame.NextN(mem.Size))
|
||||
frame.ScalableMemoryAllocator = puller.ScalableMemoryAllocator
|
||||
err = puller.ReadNto(ds, frame.NextN(ds))
|
||||
default:
|
||||
err = puller.Skip(ds)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
puller.absTS = offsetTs + (timestamp - startTs)
|
||||
frame.Timestamp = puller.absTS
|
||||
|
22
plugin/monitor/index.go
Normal file
22
plugin/monitor/index.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package plugin_monitor
|
||||
|
||||
import (
|
||||
"github.com/polarsignals/frostdb"
|
||||
"m7s.live/m7s/v5"
|
||||
)
|
||||
|
||||
var _ = m7s.InstallPlugin[MonitorPlugin]()
|
||||
|
||||
type MonitorPlugin struct {
|
||||
m7s.Plugin
|
||||
columnstore *frostdb.ColumnStore
|
||||
}
|
||||
|
||||
func (cfg *MonitorPlugin) OnInit() (err error) {
|
||||
cfg.columnstore, err = frostdb.New()
|
||||
//database, _ := cfg.columnstore.DB(cfg, "monitor")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"runtime/debug"
|
||||
|
||||
"m7s.live/m7s/v5"
|
||||
"m7s.live/m7s/v5/plugin/rtmp/pb"
|
||||
@@ -47,6 +48,7 @@ func (p *RTMPPlugin) OnTCPConnect(conn *net.TCPConn) {
|
||||
nc.Destroy()
|
||||
if p := recover(); p != nil {
|
||||
err = p.(error)
|
||||
logger.Error(err.Error(), "stack", string(debug.Stack()))
|
||||
}
|
||||
if len(receivers) > 0 {
|
||||
for _, receiver := range receivers {
|
||||
|
@@ -115,13 +115,12 @@ func (nc *NetConnection) simple_handshake(C1 []byte, checkC2 bool) error {
|
||||
copy(S0S1[5:], "Monibuca")
|
||||
nc.Write(S0S1)
|
||||
nc.Write(C1) // S2
|
||||
C2, err := nc.ReadBytes(C1S1_SIZE)
|
||||
buf := nc.mediaDataPool.NextN(C1S1_SIZE)
|
||||
err := nc.ReadNto(C1S1_SIZE, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if checkC2 {
|
||||
buf := nc.mediaDataPool.NextN(C2.Size)
|
||||
C2.CopyTo(buf)
|
||||
if !bytes.Equal(buf[8:], S0S1[9:]) {
|
||||
return errors.New("C2 Error")
|
||||
}
|
||||
|
68
publisher.go
68
publisher.go
@@ -2,6 +2,7 @@ package m7s
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -128,6 +129,19 @@ func (p *Publisher) RemoveSubscriber(subscriber *Subscriber) {
|
||||
defer p.Unlock()
|
||||
p.Subscribers.Remove(subscriber)
|
||||
p.Info("subscriber -1", "count", p.Subscribers.Length)
|
||||
if subscriber.BufferTime == p.BufferTime && p.Subscribers.Length > 0 {
|
||||
p.BufferTime = slices.MaxFunc(p.Subscribers.Items, func(a, b *Subscriber) int {
|
||||
return int(a.BufferTime - b.BufferTime)
|
||||
}).BufferTime
|
||||
} else {
|
||||
p.BufferTime = p.Plugin.GetCommonConf().Publish.BufferTime
|
||||
}
|
||||
if !p.AudioTrack.IsEmpty() {
|
||||
p.AudioTrack.AVTrack.BufferRange[0] = p.BufferTime
|
||||
}
|
||||
if !p.VideoTrack.IsEmpty() {
|
||||
p.VideoTrack.AVTrack.BufferRange[0] = p.BufferTime
|
||||
}
|
||||
if p.State == PublisherStateSubscribed && p.Subscribers.Length == 0 {
|
||||
p.State = PublisherStateWaitSubscriber
|
||||
if p.DelayCloseTimeout > 0 {
|
||||
@@ -142,6 +156,15 @@ func (p *Publisher) AddSubscriber(subscriber *Subscriber) {
|
||||
subscriber.Publisher = p
|
||||
if p.Subscribers.AddUnique(subscriber) {
|
||||
p.Info("subscriber +1", "count", p.Subscribers.Length)
|
||||
if subscriber.BufferTime > p.BufferTime {
|
||||
p.BufferTime = subscriber.BufferTime
|
||||
if !p.AudioTrack.IsEmpty() {
|
||||
p.AudioTrack.AVTrack.BufferRange[0] = p.BufferTime
|
||||
}
|
||||
if !p.VideoTrack.IsEmpty() {
|
||||
p.VideoTrack.AVTrack.BufferRange[0] = p.BufferTime
|
||||
}
|
||||
}
|
||||
switch p.State {
|
||||
case PublisherStateTrackAdded, PublisherStateWaitSubscriber:
|
||||
p.State = PublisherStateSubscribed
|
||||
@@ -181,7 +204,7 @@ func (p *Publisher) WriteVideo(data IAVFrame) (err error) {
|
||||
}
|
||||
t := p.VideoTrack.AVTrack
|
||||
if t == nil {
|
||||
t = NewAVTrack(data, p.Logger.With("track", "video"), 20)
|
||||
t = NewAVTrack(data, p.Logger.With("track", "video"), &p.Publish)
|
||||
p.Lock()
|
||||
p.VideoTrack.AVTrack = t
|
||||
p.VideoTrack.Add(t)
|
||||
@@ -202,41 +225,18 @@ func (p *Publisher) WriteVideo(data IAVFrame) (err error) {
|
||||
if t.ICodecCtx == nil {
|
||||
return ErrUnsupportCodec
|
||||
}
|
||||
idr, hidr := t.IDRing.Load(), t.HistoryRing.Load()
|
||||
var idr *util.Ring[AVFrame]
|
||||
if t.IDRingList.Len() > 0 {
|
||||
idr = t.IDRingList.Back().Value
|
||||
}
|
||||
if t.Value.IDR {
|
||||
if t.Ring == idr {
|
||||
panic("idr ring is full")
|
||||
}
|
||||
if idr != nil {
|
||||
p.GOP = int(t.Value.Sequence - idr.Value.Sequence)
|
||||
if hidr == nil && p.GOP > 0 {
|
||||
if l := t.Size - p.GOP; l > p.GetPublishConfig().MinRingSize {
|
||||
t.Debug("reduce", "gop", p.GOP, "before", t.Size, "after", t.Size-5)
|
||||
t.Reduce(5) //缩小缓冲环节省内存
|
||||
t.Debug("check", "real", t.Len())
|
||||
}
|
||||
}
|
||||
}
|
||||
if p.BufferTime > 0 {
|
||||
t.IDRingList.AddIDR(t.Ring)
|
||||
if hidr == nil {
|
||||
t.HistoryRing.Store(t.Ring)
|
||||
}
|
||||
} else {
|
||||
t.IDRing.Store(t.Ring)
|
||||
}
|
||||
if idr == nil {
|
||||
if t.Ready.IsPending() {
|
||||
p.Info("ready")
|
||||
t.Ready.Fulfill(nil)
|
||||
}
|
||||
if !p.AudioTrack.IsEmpty() {
|
||||
p.AudioTrack.IDRing.Store(p.AudioTrack.Ring)
|
||||
}
|
||||
} else if nextValue := t.Next(); nextValue == idr || nextValue == hidr {
|
||||
if t.Size < p.Plugin.GetCommonConf().MaxRingSize {
|
||||
t.Debug("glow", "gop", p.GOP, "before", t.Size, "after", t.Size+5)
|
||||
t.Glow(5)
|
||||
t.Debug("check", "real", t.Len())
|
||||
} else if idr != nil {
|
||||
p.GOP = int(t.Value.Sequence - idr.Value.Sequence)
|
||||
} else {
|
||||
p.GOP = 0
|
||||
}
|
||||
}
|
||||
p.writeAV(t, data)
|
||||
@@ -298,7 +298,7 @@ func (p *Publisher) WriteAudio(data IAVFrame) (err error) {
|
||||
}
|
||||
t := p.AudioTrack.AVTrack
|
||||
if t == nil {
|
||||
t = NewAVTrack(data, p.Logger.With("track", "audio"), 20)
|
||||
t = NewAVTrack(data, p.Logger.With("track", "audio"), &p.Publish)
|
||||
p.Lock()
|
||||
p.AudioTrack.AVTrack = t
|
||||
p.AudioTrack.Add(t)
|
||||
|
@@ -15,7 +15,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/mcuadros/go-defaults"
|
||||
"github.com/phsym/console-slog"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
@@ -146,8 +145,6 @@ func (s *Server) run(ctx context.Context, conf any) (err error) {
|
||||
s.Error("parsing yml error:", err)
|
||||
}
|
||||
}
|
||||
defaults.SetDefaults(&s.Engine)
|
||||
defaults.SetDefaults(&s.config)
|
||||
s.Config.Parse(&s.config)
|
||||
s.Config.Parse(&s.Engine, "GLOBAL")
|
||||
if cg != nil {
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "m7s.live/m7s/v5/pkg"
|
||||
@@ -38,7 +38,7 @@ func (p *PubSubBase) GetKey() int {
|
||||
return p.ID
|
||||
}
|
||||
|
||||
func (ps *PubSubBase) Init(p *Plugin, streamPath string, options ...any) {
|
||||
func (ps *PubSubBase) Init(p *Plugin, streamPath string, conf any, options ...any) {
|
||||
ps.Plugin = p
|
||||
ctx := p.Context
|
||||
for _, option := range options {
|
||||
@@ -61,6 +61,23 @@ func (ps *PubSubBase) Init(p *Plugin, streamPath string, options ...any) {
|
||||
if u, err := url.Parse(streamPath); err == nil {
|
||||
ps.StreamPath, ps.Args = u.Path, u.Query()
|
||||
}
|
||||
// args to config
|
||||
if len(ps.Args) != 0 {
|
||||
var c config.Config
|
||||
c.Parse(conf)
|
||||
ignores, cc := make(map[string]struct{}), make(map[string]any)
|
||||
for key, value := range ps.Args {
|
||||
if strings.HasSuffix(key, "ArgName") {
|
||||
targetArgName := strings.TrimSuffix(key, "ArgName")
|
||||
cc[targetArgName] = ps.Args.Get(value[0])[0]
|
||||
ignores[value[0]] = struct{}{}
|
||||
delete(cc, value[0])
|
||||
} else if _, ok := ignores[key]; !ok {
|
||||
cc[key] = value[0]
|
||||
}
|
||||
}
|
||||
c.ParseModifyFile(cc)
|
||||
}
|
||||
ps.StartTime = time.Now()
|
||||
}
|
||||
|
||||
@@ -79,11 +96,7 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
var awi, vwi int
|
||||
var startAudioTs, startVideoTs time.Duration
|
||||
var initState = 0
|
||||
var prePublisher *Publisher
|
||||
var subMode = s.SubMode //订阅模式
|
||||
if s.Args.Has(s.SubModeArgName) {
|
||||
subMode, _ = strconv.Atoi(s.Args.Get(s.SubModeArgName))
|
||||
}
|
||||
prePublisher := s.Publisher
|
||||
var audioFrame, videoFrame *AVFrame
|
||||
if s.SubAudio {
|
||||
a1 = reflect.TypeOf(onAudio).In(0)
|
||||
@@ -105,6 +118,9 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
}
|
||||
}
|
||||
if at != nil {
|
||||
if _, err := at.Ready.Await(); err != nil {
|
||||
return
|
||||
}
|
||||
ar = NewAVRingReader(at)
|
||||
s.AudioReader = ar
|
||||
ar.StartTs = startAudioTs
|
||||
@@ -126,6 +142,9 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
}
|
||||
}
|
||||
if vt != nil {
|
||||
if _, err := vt.Ready.Await(); err != nil {
|
||||
return
|
||||
}
|
||||
vr = NewAVRingReader(vt)
|
||||
vr.StartTs = startVideoTs
|
||||
s.VideoReader = vr
|
||||
@@ -135,7 +154,6 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
}
|
||||
createAudioReader()
|
||||
createVideoReader()
|
||||
prePublisher = s.Publisher
|
||||
defer func() {
|
||||
if ar != nil {
|
||||
ar.StopRead()
|
||||
@@ -205,7 +223,7 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
err = s.Err()
|
||||
if vr != nil {
|
||||
for err == nil {
|
||||
err = vr.ReadFrame(subMode)
|
||||
err = vr.ReadFrame(&s.Subscribe)
|
||||
if err == nil {
|
||||
videoFrame = &vr.Value
|
||||
err = s.Err()
|
||||
@@ -259,8 +277,7 @@ func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(
|
||||
ar.SkipTs = vr.SkipTs
|
||||
}
|
||||
}
|
||||
err = ar.ReadFrame(subMode)
|
||||
if err == nil {
|
||||
if err = ar.ReadFrame(&s.Subscribe); err == nil {
|
||||
audioFrame = &ar.Value
|
||||
err = s.Err()
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user