mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 16:32:06 +08:00
feat: add change subscribe
This commit is contained in:
34
api.go
34
api.go
@@ -41,7 +41,7 @@ func (s *Server) SysInfo(context.Context, *emptypb.Empty) (res *pb.SysInfoRespon
|
|||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
Cpus: int32(runtime.NumCPU()),
|
Cpus: int32(runtime.NumCPU()),
|
||||||
}
|
}
|
||||||
for _, p := range s.Plugins.Items {
|
for p := range s.Plugins.Range {
|
||||||
res.Plugins = append(res.Plugins, &pb.PluginInfo{
|
res.Plugins = append(res.Plugins, &pb.PluginInfo{
|
||||||
Name: p.Meta.Name,
|
Name: p.Meta.Name,
|
||||||
Version: p.Meta.Version,
|
Version: p.Meta.Version,
|
||||||
@@ -101,7 +101,7 @@ func (s *Server) getStreamInfo(pub *Publisher) (res *pb.StreamInfoResponse, err
|
|||||||
Path: pub.StreamPath,
|
Path: pub.StreamPath,
|
||||||
State: int32(pub.State),
|
State: int32(pub.State),
|
||||||
StartTime: timestamppb.New(pub.StartTime),
|
StartTime: timestamppb.New(pub.StartTime),
|
||||||
Subscribers: int32(len(pub.Subscribers)),
|
Subscribers: int32(pub.Subscribers.Length),
|
||||||
Type: pub.Plugin.Meta.Name,
|
Type: pub.Plugin.Meta.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ func (s *Server) StreamInfo(ctx context.Context, req *pb.StreamSnapRequest) (res
|
|||||||
func (s *Server) GetSubscribers(ctx context.Context, req *pb.SubscribersRequest) (res *pb.SubscribersResponse, err error) {
|
func (s *Server) GetSubscribers(ctx context.Context, req *pb.SubscribersRequest) (res *pb.SubscribersResponse, err error) {
|
||||||
s.Call(func() {
|
s.Call(func() {
|
||||||
var subscribers []*pb.SubscriberSnapShot
|
var subscribers []*pb.SubscriberSnapShot
|
||||||
for _, subscriber := range s.Subscribers.Items {
|
for subscriber := range s.Subscribers.Range {
|
||||||
meta, _ := json.Marshal(subscriber.MetaData)
|
meta, _ := json.Marshal(subscriber.MetaData)
|
||||||
snap := &pb.SubscriberSnapShot{
|
snap := &pb.SubscriberSnapShot{
|
||||||
Id: uint32(subscriber.ID),
|
Id: uint32(subscriber.ID),
|
||||||
@@ -195,7 +195,7 @@ func (s *Server) AudioTrackSnap(ctx context.Context, req *pb.StreamSnapRequest)
|
|||||||
res.Memory = append(res.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
res.Memory = append(res.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||||
}
|
}
|
||||||
res.Reader = make(map[uint32]uint32)
|
res.Reader = make(map[uint32]uint32)
|
||||||
for sub := range pub.Subscribers {
|
for sub := range pub.SubscriberRange {
|
||||||
if sub.AudioReader == nil {
|
if sub.AudioReader == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -259,6 +259,7 @@ func (s *Server) api_VideoTrack_SSE(rw http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) VideoTrackSnap(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.TrackSnapShotResponse, err error) {
|
func (s *Server) VideoTrackSnap(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.TrackSnapShotResponse, err error) {
|
||||||
s.Call(func() {
|
s.Call(func() {
|
||||||
if pub, ok := s.Streams.Get(req.StreamPath); ok && !pub.VideoTrack.IsEmpty() {
|
if pub, ok := s.Streams.Get(req.StreamPath); ok && !pub.VideoTrack.IsEmpty() {
|
||||||
@@ -274,7 +275,7 @@ func (s *Server) VideoTrackSnap(ctx context.Context, req *pb.StreamSnapRequest)
|
|||||||
res.Memory = append(res.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
res.Memory = append(res.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||||
}
|
}
|
||||||
res.Reader = make(map[uint32]uint32)
|
res.Reader = make(map[uint32]uint32)
|
||||||
for sub := range pub.Subscribers {
|
for sub := range pub.SubscriberRange {
|
||||||
if sub.VideoReader == nil {
|
if sub.VideoReader == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -325,6 +326,23 @@ func (s *Server) Shutdown(ctx context.Context, req *pb.RequestWithId) (res *empt
|
|||||||
return empty, err
|
return empty, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) ChangeSubscribe(ctx context.Context, req *pb.ChangeSubscribeRequest) (res *pb.SuccessResponse, err error) {
|
||||||
|
s.Call(func() {
|
||||||
|
if subscriber, ok := s.Subscribers.Get(int(req.Id)); ok {
|
||||||
|
if pub, ok := s.Streams.Get(req.StreamPath); ok {
|
||||||
|
subscriber.Publisher.RemoveSubscriber(subscriber)
|
||||||
|
subscriber.StreamPath = req.StreamPath
|
||||||
|
pub.AddSubscriber(subscriber)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = pkg.ErrNotFound
|
||||||
|
})
|
||||||
|
return &pb.SuccessResponse{
|
||||||
|
Success: err == nil,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) StopSubscribe(ctx context.Context, req *pb.RequestWithId) (res *pb.SuccessResponse, err error) {
|
func (s *Server) StopSubscribe(ctx context.Context, req *pb.RequestWithId) (res *pb.SuccessResponse, err error) {
|
||||||
s.Call(func() {
|
s.Call(func() {
|
||||||
if subscriber, ok := s.Subscribers.Get(int(req.Id)); ok {
|
if subscriber, ok := s.Subscribers.Get(int(req.Id)); ok {
|
||||||
@@ -342,7 +360,7 @@ func (s *Server) StopSubscribe(ctx context.Context, req *pb.RequestWithId) (res
|
|||||||
func (s *Server) StreamList(_ context.Context, req *pb.StreamListRequest) (res *pb.StreamListResponse, err error) {
|
func (s *Server) StreamList(_ context.Context, req *pb.StreamListRequest) (res *pb.StreamListResponse, err error) {
|
||||||
s.Call(func() {
|
s.Call(func() {
|
||||||
var streams []*pb.StreamInfoResponse
|
var streams []*pb.StreamInfoResponse
|
||||||
for _, publisher := range s.Streams.Items {
|
for publisher := range s.Streams.Range {
|
||||||
info, err := s.getStreamInfo(publisher)
|
info, err := s.getStreamInfo(publisher)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@@ -359,8 +377,8 @@ func (s *Server) WaitList(context.Context, *emptypb.Empty) (res *pb.StreamWaitLi
|
|||||||
res = &pb.StreamWaitListResponse{
|
res = &pb.StreamWaitListResponse{
|
||||||
List: make(map[string]int32),
|
List: make(map[string]int32),
|
||||||
}
|
}
|
||||||
for streamPath, subs := range s.Waiting {
|
for subs := range s.Waiting.Range {
|
||||||
res.List[streamPath] = int32(len(subs))
|
res.List[subs.StreamPath] = int32(subs.Subscribers.Length)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
466
pb/global.pb.go
466
pb/global.pb.go
@@ -1680,6 +1680,61 @@ func (x *RequestWithId) GetId() uint32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ChangeSubscribeRequest struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
|
StreamPath string `protobuf:"bytes,2,opt,name=streamPath,proto3" json:"streamPath,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ChangeSubscribeRequest) Reset() {
|
||||||
|
*x = ChangeSubscribeRequest{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_global_proto_msgTypes[24]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ChangeSubscribeRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ChangeSubscribeRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ChangeSubscribeRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_global_proto_msgTypes[24]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use ChangeSubscribeRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*ChangeSubscribeRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_global_proto_rawDescGZIP(), []int{24}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ChangeSubscribeRequest) GetId() uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ChangeSubscribeRequest) GetStreamPath() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.StreamPath
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type SubscribersRequest struct {
|
type SubscribersRequest struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -1693,7 +1748,7 @@ type SubscribersRequest struct {
|
|||||||
func (x *SubscribersRequest) Reset() {
|
func (x *SubscribersRequest) Reset() {
|
||||||
*x = SubscribersRequest{}
|
*x = SubscribersRequest{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_global_proto_msgTypes[24]
|
mi := &file_global_proto_msgTypes[25]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1706,7 +1761,7 @@ func (x *SubscribersRequest) String() string {
|
|||||||
func (*SubscribersRequest) ProtoMessage() {}
|
func (*SubscribersRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *SubscribersRequest) ProtoReflect() protoreflect.Message {
|
func (x *SubscribersRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_global_proto_msgTypes[24]
|
mi := &file_global_proto_msgTypes[25]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1719,7 +1774,7 @@ func (x *SubscribersRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use SubscribersRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use SubscribersRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*SubscribersRequest) Descriptor() ([]byte, []int) {
|
func (*SubscribersRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_global_proto_rawDescGZIP(), []int{24}
|
return file_global_proto_rawDescGZIP(), []int{25}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SubscribersRequest) GetStreamPath() string {
|
func (x *SubscribersRequest) GetStreamPath() string {
|
||||||
@@ -1757,7 +1812,7 @@ type RingReaderSnapShot struct {
|
|||||||
func (x *RingReaderSnapShot) Reset() {
|
func (x *RingReaderSnapShot) Reset() {
|
||||||
*x = RingReaderSnapShot{}
|
*x = RingReaderSnapShot{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_global_proto_msgTypes[25]
|
mi := &file_global_proto_msgTypes[26]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1770,7 +1825,7 @@ func (x *RingReaderSnapShot) String() string {
|
|||||||
func (*RingReaderSnapShot) ProtoMessage() {}
|
func (*RingReaderSnapShot) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *RingReaderSnapShot) ProtoReflect() protoreflect.Message {
|
func (x *RingReaderSnapShot) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_global_proto_msgTypes[25]
|
mi := &file_global_proto_msgTypes[26]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1783,7 +1838,7 @@ func (x *RingReaderSnapShot) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use RingReaderSnapShot.ProtoReflect.Descriptor instead.
|
// Deprecated: Use RingReaderSnapShot.ProtoReflect.Descriptor instead.
|
||||||
func (*RingReaderSnapShot) Descriptor() ([]byte, []int) {
|
func (*RingReaderSnapShot) Descriptor() ([]byte, []int) {
|
||||||
return file_global_proto_rawDescGZIP(), []int{25}
|
return file_global_proto_rawDescGZIP(), []int{26}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *RingReaderSnapShot) GetSequence() uint32 {
|
func (x *RingReaderSnapShot) GetSequence() uint32 {
|
||||||
@@ -1829,7 +1884,7 @@ type SubscriberSnapShot struct {
|
|||||||
func (x *SubscriberSnapShot) Reset() {
|
func (x *SubscriberSnapShot) Reset() {
|
||||||
*x = SubscriberSnapShot{}
|
*x = SubscriberSnapShot{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_global_proto_msgTypes[26]
|
mi := &file_global_proto_msgTypes[27]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1842,7 +1897,7 @@ func (x *SubscriberSnapShot) String() string {
|
|||||||
func (*SubscriberSnapShot) ProtoMessage() {}
|
func (*SubscriberSnapShot) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *SubscriberSnapShot) ProtoReflect() protoreflect.Message {
|
func (x *SubscriberSnapShot) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_global_proto_msgTypes[26]
|
mi := &file_global_proto_msgTypes[27]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1855,7 +1910,7 @@ func (x *SubscriberSnapShot) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use SubscriberSnapShot.ProtoReflect.Descriptor instead.
|
// Deprecated: Use SubscriberSnapShot.ProtoReflect.Descriptor instead.
|
||||||
func (*SubscriberSnapShot) Descriptor() ([]byte, []int) {
|
func (*SubscriberSnapShot) Descriptor() ([]byte, []int) {
|
||||||
return file_global_proto_rawDescGZIP(), []int{26}
|
return file_global_proto_rawDescGZIP(), []int{27}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SubscriberSnapShot) GetId() uint32 {
|
func (x *SubscriberSnapShot) GetId() uint32 {
|
||||||
@@ -1907,7 +1962,7 @@ type SubscribersResponse struct {
|
|||||||
func (x *SubscribersResponse) Reset() {
|
func (x *SubscribersResponse) Reset() {
|
||||||
*x = SubscribersResponse{}
|
*x = SubscribersResponse{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_global_proto_msgTypes[27]
|
mi := &file_global_proto_msgTypes[28]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -1920,7 +1975,7 @@ func (x *SubscribersResponse) String() string {
|
|||||||
func (*SubscribersResponse) ProtoMessage() {}
|
func (*SubscribersResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *SubscribersResponse) ProtoReflect() protoreflect.Message {
|
func (x *SubscribersResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_global_proto_msgTypes[27]
|
mi := &file_global_proto_msgTypes[28]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -1933,7 +1988,7 @@ func (x *SubscribersResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use SubscribersResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use SubscribersResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*SubscribersResponse) Descriptor() ([]byte, []int) {
|
func (*SubscribersResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_global_proto_rawDescGZIP(), []int{27}
|
return file_global_proto_rawDescGZIP(), []int{28}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SubscribersResponse) GetTotal() int32 {
|
func (x *SubscribersResponse) GetTotal() int32 {
|
||||||
@@ -2193,132 +2248,144 @@ var file_global_proto_rawDesc = []byte{
|
|||||||
0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73,
|
0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73,
|
||||||
0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x1f, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x1f, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||||
0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||||
0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x6a, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63,
|
0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x48, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6e, 0x67,
|
||||||
0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a,
|
0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||||
0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69,
|
||||||
0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a,
|
0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x18,
|
||||||
0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07,
|
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74,
|
||||||
0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53,
|
0x68, 0x22, 0x6a, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73,
|
||||||
0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53,
|
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61,
|
||||||
0x69, 0x7a, 0x65, 0x22, 0x7a, 0x0a, 0x12, 0x52, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x65,
|
0x6d, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72,
|
||||||
0x72, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71,
|
0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e,
|
||||||
0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x65, 0x71,
|
0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75,
|
||||||
0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
|
0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20,
|
||||||
0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x7a, 0x0a,
|
||||||
0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01,
|
0x12, 0x52, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x53,
|
||||||
0x28, 0x0d, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
|
0x68, 0x6f, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18,
|
||||||
0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22,
|
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12,
|
||||||
0xe8, 0x01, 0x0a, 0x12, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x53, 0x6e,
|
0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
0x28, 0x0d, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a,
|
||||||
0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54,
|
0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x65,
|
||||||
0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
0x6c, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
|
0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xe8, 0x01, 0x0a, 0x12, 0x53, 0x75,
|
||||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65,
|
0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74,
|
||||||
0x12, 0x39, 0x0a, 0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
|
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64,
|
||||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x69, 0x6e, 0x67,
|
0x12, 0x38, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20,
|
||||||
0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x0b,
|
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
0x61, 0x75, 0x64, 0x69, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0b, 0x76,
|
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
|
||||||
0x69, 0x64, 0x65, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x75,
|
||||||
0x32, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x65,
|
0x64, 0x69, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
0x72, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f,
|
0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||||
0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05,
|
0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x0b, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x52,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x8e, 0x01, 0x0a, 0x13, 0x53,
|
0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x52, 0x65,
|
||||||
0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28,
|
0x2e, 0x52, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x53,
|
||||||
0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x67, 0x65,
|
0x68, 0x6f, 0x74, 0x52, 0x0b, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72,
|
||||||
0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e,
|
0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||||
0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03,
|
0x6d, 0x65, 0x74, 0x61, 0x22, 0x8e, 0x01, 0x0a, 0x13, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2b,
|
0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||||
0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d,
|
0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74,
|
||||||
0x37, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x53, 0x6e, 0x61,
|
0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20,
|
||||||
0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x32, 0xca, 0x0a, 0x0a, 0x06,
|
0x01, 0x28, 0x05, 0x52, 0x07, 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x08,
|
||||||
0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x12, 0x4d, 0x0a, 0x07, 0x53, 0x79, 0x73, 0x49, 0x6e, 0x66,
|
0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
|
||||||
0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74,
|
||||||
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e,
|
0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x62,
|
||||||
0x53, 0x79, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52,
|
||||||
0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79,
|
0x04, 0x6c, 0x69, 0x73, 0x74, 0x32, 0xc7, 0x0b, 0x0a, 0x06, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
|
||||||
0x73, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x4d, 0x0a, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,
|
0x12, 0x4d, 0x0a, 0x07, 0x53, 0x79, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x67, 0x6f,
|
||||||
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
||||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53,
|
0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x79, 0x73, 0x49, 0x6e, 0x66,
|
||||||
0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14,
|
0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x75, 0x6d,
|
0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x69, 0x6e, 0x66, 0x6f, 0x12,
|
||||||
0x6d, 0x61, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e,
|
0x4d, 0x0a, 0x07, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
0x12, 0x12, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69,
|
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
|
||||||
0x74, 0x68, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
0x74, 0x79, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79,
|
||||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1a, 0x82, 0xd3,
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e,
|
||||||
0xe4, 0x93, 0x02, 0x14, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64,
|
0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x52,
|
||||||
0x6f, 0x77, 0x6e, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x50, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74,
|
0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x12, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x61, 0x72, 0x74, 0x12, 0x12, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x1a, 0x16,
|
||||||
0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
|
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x22, 0x12,
|
||||||
0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65,
|
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x2f, 0x7b, 0x69,
|
||||||
0x73, 0x74, 0x61, 0x72, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x53, 0x74,
|
0x64, 0x7d, 0x12, 0x50, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x12, 0x2e,
|
||||||
0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53,
|
0x6d, 0x37, 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49,
|
||||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
0x64, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
0x1a, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x73,
|
0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
0x13, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2f,
|
||||||
0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x6c,
|
0x7b, 0x69, 0x64, 0x7d, 0x12, 0x57, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69,
|
||||||
0x69, 0x73, 0x74, 0x12, 0x5d, 0x0a, 0x08, 0x57, 0x61, 0x69, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12,
|
0x73, 0x74, 0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c,
|
||||||
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74,
|
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||||
0x72, 0x65, 0x61, 0x6d, 0x57, 0x61, 0x69, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
|
0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61,
|
0x69, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x5d, 0x0a,
|
||||||
0x70, 0x69, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x6c, 0x69,
|
0x08, 0x57, 0x61, 0x69, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||||
0x73, 0x74, 0x12, 0x67, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x66, 0x6f,
|
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||||
0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61,
|
0x79, 0x1a, 0x1b, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x57, 0x61,
|
||||||
0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53,
|
0x69, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c,
|
||||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x74, 0x72,
|
||||||
0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
0x65, 0x61, 0x6d, 0x2f, 0x77, 0x61, 0x69, 0x74, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x67, 0x0a, 0x0a,
|
||||||
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x7b, 0x73, 0x74, 0x72,
|
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x6d, 0x0a, 0x0e, 0x47,
|
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x65, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e,
|
0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49,
|
||||||
0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x52,
|
0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x62,
|
0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||||
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74,
|
||||||
0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73,
|
0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x6d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x75, 0x62, 0x73,
|
||||||
0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65,
|
0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75,
|
||||||
0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x72, 0x0a, 0x0e, 0x41, 0x75,
|
0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
0x64, 0x69, 0x6f, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x6d,
|
0x1a, 0x18, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
|
||||||
0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x52, 0x65, 0x71,
|
0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93,
|
||||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b,
|
0x02, 0x22, 0x12, 0x20, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
|
||||||
0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
0x62, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68,
|
||||||
0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61,
|
0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x72, 0x0a, 0x0e, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x54, 0x72, 0x61,
|
||||||
0x75, 0x64, 0x69, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2f, 0x7b,
|
0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72,
|
||||||
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x72,
|
0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
|
||||||
0x0a, 0x0e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70,
|
0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68,
|
||||||
0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61,
|
0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93,
|
||||||
0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x54,
|
0x02, 0x26, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x74, 0x72,
|
||||||
0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70,
|
0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x61,
|
0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x72, 0x0a, 0x0e, 0x56, 0x69, 0x64, 0x65,
|
||||||
0x70, 0x69, 0x2f, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6e,
|
0x6f, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x61, 0x70, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a,
|
0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6e, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
0x2a, 0x7d, 0x12, 0x5e, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
|
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x53, 0x6e,
|
||||||
0x69, 0x62, 0x65, 0x12, 0x12, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
0x61, 0x70, 0x53, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c,
|
||||||
0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75,
|
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x69, 0x64,
|
||||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82,
|
0x65, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x2f, 0x7b, 0x73, 0x74,
|
||||||
0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x74, 0x6f, 0x70,
|
0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x12, 0x7b, 0x0a, 0x0f,
|
||||||
0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a,
|
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12,
|
||||||
0x01, 0x2a, 0x12, 0x5a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
0x1b, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x75, 0x62, 0x73,
|
||||||
0x15, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
|
0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d,
|
||||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74,
|
0x37, 0x73, 0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e,
|
0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x22, 0x2a, 0x2f, 0x61, 0x70, 0x69,
|
||||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e,
|
0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||||
0x66, 0x69, 0x67, 0x2f, 0x67, 0x65, 0x74, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x5f,
|
0x65, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61,
|
||||||
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x15, 0x2e, 0x6d,
|
0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x5e, 0x0a, 0x0d, 0x53, 0x74, 0x6f,
|
||||||
0x37, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
|
0x70, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x12, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e,
|
0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x69, 0x74, 0x68, 0x49, 0x64, 0x1a, 0x14,
|
||||||
0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4,
|
0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||||
0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x18, 0x2f, 0x61,
|
||||||
0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6c, 0x79, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12,
|
0x70, 0x69, 0x2f, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x2f, 0x73, 0x74, 0x6f,
|
||||||
0x67, 0x0a, 0x0c, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
0x70, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x3a, 0x01, 0x2a, 0x12, 0x5a, 0x0a, 0x09, 0x47, 0x65, 0x74,
|
||||||
0x18, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x43, 0x6f, 0x6e, 0x66,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x15, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74,
|
||||||
0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||||
0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73,
|
||||||
0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x22, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f,
|
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f,
|
||||||
0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x2f, 0x7b, 0x6e, 0x61, 0x6d,
|
0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x67, 0x65, 0x74, 0x2f, 0x7b,
|
||||||
0x65, 0x7d, 0x3a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42, 0x14, 0x5a, 0x12, 0x6d, 0x37, 0x73, 0x2e,
|
0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x5f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x46, 0x6f, 0x72, 0x6d,
|
||||||
0x6c, 0x69, 0x76, 0x65, 0x2f, 0x6d, 0x37, 0x73, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x62, 0x62, 0x06,
|
0x69, 0x6c, 0x79, 0x12, 0x15, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e,
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6d, 0x37, 0x73,
|
||||||
|
0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||||
|
0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69,
|
||||||
|
0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x6c, 0x79, 0x2f,
|
||||||
|
0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x67, 0x0a, 0x0c, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79,
|
||||||
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x4d, 0x6f, 0x64,
|
||||||
|
0x69, 0x66, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||||
|
0x1a, 0x14, 0x2e, 0x6d, 0x37, 0x73, 0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65,
|
||||||
|
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x22, 0x19,
|
||||||
|
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x6f, 0x64, 0x69,
|
||||||
|
0x66, 0x79, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x3a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42,
|
||||||
|
0x14, 0x5a, 0x12, 0x6d, 0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x6d, 0x37, 0x73, 0x2f,
|
||||||
|
0x76, 0x35, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -2333,7 +2400,7 @@ func file_global_proto_rawDescGZIP() []byte {
|
|||||||
return file_global_proto_rawDescData
|
return file_global_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_global_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
|
var file_global_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
|
||||||
var file_global_proto_goTypes = []interface{}{
|
var file_global_proto_goTypes = []interface{}{
|
||||||
(*GetConfigRequest)(nil), // 0: m7s.GetConfigRequest
|
(*GetConfigRequest)(nil), // 0: m7s.GetConfigRequest
|
||||||
(*Formily)(nil), // 1: m7s.Formily
|
(*Formily)(nil), // 1: m7s.Formily
|
||||||
@@ -2359,76 +2426,79 @@ var file_global_proto_goTypes = []interface{}{
|
|||||||
(*VideoTrackInfo)(nil), // 21: m7s.VideoTrackInfo
|
(*VideoTrackInfo)(nil), // 21: m7s.VideoTrackInfo
|
||||||
(*SuccessResponse)(nil), // 22: m7s.SuccessResponse
|
(*SuccessResponse)(nil), // 22: m7s.SuccessResponse
|
||||||
(*RequestWithId)(nil), // 23: m7s.RequestWithId
|
(*RequestWithId)(nil), // 23: m7s.RequestWithId
|
||||||
(*SubscribersRequest)(nil), // 24: m7s.SubscribersRequest
|
(*ChangeSubscribeRequest)(nil), // 24: m7s.ChangeSubscribeRequest
|
||||||
(*RingReaderSnapShot)(nil), // 25: m7s.RingReaderSnapShot
|
(*SubscribersRequest)(nil), // 25: m7s.SubscribersRequest
|
||||||
(*SubscriberSnapShot)(nil), // 26: m7s.SubscriberSnapShot
|
(*RingReaderSnapShot)(nil), // 26: m7s.RingReaderSnapShot
|
||||||
(*SubscribersResponse)(nil), // 27: m7s.SubscribersResponse
|
(*SubscriberSnapShot)(nil), // 27: m7s.SubscriberSnapShot
|
||||||
nil, // 28: m7s.Formily.PropertiesEntry
|
(*SubscribersResponse)(nil), // 28: m7s.SubscribersResponse
|
||||||
nil, // 29: m7s.Formily.ComponentPropsEntry
|
nil, // 29: m7s.Formily.PropertiesEntry
|
||||||
nil, // 30: m7s.FormilyResponse.PropertiesEntry
|
nil, // 30: m7s.Formily.ComponentPropsEntry
|
||||||
nil, // 31: m7s.StreamWaitListResponse.ListEntry
|
nil, // 31: m7s.FormilyResponse.PropertiesEntry
|
||||||
nil, // 32: m7s.TrackSnapShotResponse.ReaderEntry
|
nil, // 32: m7s.StreamWaitListResponse.ListEntry
|
||||||
(*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp
|
nil, // 33: m7s.TrackSnapShotResponse.ReaderEntry
|
||||||
(*anypb.Any)(nil), // 34: google.protobuf.Any
|
(*timestamppb.Timestamp)(nil), // 34: google.protobuf.Timestamp
|
||||||
(*emptypb.Empty)(nil), // 35: google.protobuf.Empty
|
(*anypb.Any)(nil), // 35: google.protobuf.Any
|
||||||
|
(*emptypb.Empty)(nil), // 36: google.protobuf.Empty
|
||||||
}
|
}
|
||||||
var file_global_proto_depIdxs = []int32{
|
var file_global_proto_depIdxs = []int32{
|
||||||
28, // 0: m7s.Formily.properties:type_name -> m7s.Formily.PropertiesEntry
|
29, // 0: m7s.Formily.properties:type_name -> m7s.Formily.PropertiesEntry
|
||||||
29, // 1: m7s.Formily.componentProps:type_name -> m7s.Formily.ComponentPropsEntry
|
30, // 1: m7s.Formily.componentProps:type_name -> m7s.Formily.ComponentPropsEntry
|
||||||
30, // 2: m7s.FormilyResponse.properties:type_name -> m7s.FormilyResponse.PropertiesEntry
|
31, // 2: m7s.FormilyResponse.properties:type_name -> m7s.FormilyResponse.PropertiesEntry
|
||||||
6, // 3: m7s.SummaryResponse.memory:type_name -> m7s.Usage
|
6, // 3: m7s.SummaryResponse.memory:type_name -> m7s.Usage
|
||||||
6, // 4: m7s.SummaryResponse.hardDisk:type_name -> m7s.Usage
|
6, // 4: m7s.SummaryResponse.hardDisk:type_name -> m7s.Usage
|
||||||
5, // 5: m7s.SummaryResponse.netWork:type_name -> m7s.NetWorkInfo
|
5, // 5: m7s.SummaryResponse.netWork:type_name -> m7s.NetWorkInfo
|
||||||
33, // 6: m7s.SysInfoResponse.startTime:type_name -> google.protobuf.Timestamp
|
34, // 6: m7s.SysInfoResponse.startTime:type_name -> google.protobuf.Timestamp
|
||||||
8, // 7: m7s.SysInfoResponse.plugins:type_name -> m7s.PluginInfo
|
8, // 7: m7s.SysInfoResponse.plugins:type_name -> m7s.PluginInfo
|
||||||
14, // 8: m7s.StreamListResponse.list:type_name -> m7s.StreamInfoResponse
|
14, // 8: m7s.StreamListResponse.list:type_name -> m7s.StreamInfoResponse
|
||||||
31, // 9: m7s.StreamWaitListResponse.list:type_name -> m7s.StreamWaitListResponse.ListEntry
|
32, // 9: m7s.StreamWaitListResponse.list:type_name -> m7s.StreamWaitListResponse.ListEntry
|
||||||
19, // 10: m7s.StreamInfoResponse.audioTrack:type_name -> m7s.AudioTrackInfo
|
19, // 10: m7s.StreamInfoResponse.audioTrack:type_name -> m7s.AudioTrackInfo
|
||||||
21, // 11: m7s.StreamInfoResponse.videoTrack:type_name -> m7s.VideoTrackInfo
|
21, // 11: m7s.StreamInfoResponse.videoTrack:type_name -> m7s.VideoTrackInfo
|
||||||
33, // 12: m7s.StreamInfoResponse.startTime:type_name -> google.protobuf.Timestamp
|
34, // 12: m7s.StreamInfoResponse.startTime:type_name -> google.protobuf.Timestamp
|
||||||
33, // 13: m7s.TrackSnapShot.writeTime:type_name -> google.protobuf.Timestamp
|
34, // 13: m7s.TrackSnapShot.writeTime:type_name -> google.protobuf.Timestamp
|
||||||
15, // 14: m7s.TrackSnapShot.wrap:type_name -> m7s.Wrap
|
15, // 14: m7s.TrackSnapShot.wrap:type_name -> m7s.Wrap
|
||||||
17, // 15: m7s.MemoryBlockGroup.list:type_name -> m7s.MemoryBlock
|
17, // 15: m7s.MemoryBlockGroup.list:type_name -> m7s.MemoryBlock
|
||||||
16, // 16: m7s.TrackSnapShotResponse.ring:type_name -> m7s.TrackSnapShot
|
16, // 16: m7s.TrackSnapShotResponse.ring:type_name -> m7s.TrackSnapShot
|
||||||
32, // 17: m7s.TrackSnapShotResponse.reader:type_name -> m7s.TrackSnapShotResponse.ReaderEntry
|
33, // 17: m7s.TrackSnapShotResponse.reader:type_name -> m7s.TrackSnapShotResponse.ReaderEntry
|
||||||
18, // 18: m7s.TrackSnapShotResponse.memory:type_name -> m7s.MemoryBlockGroup
|
18, // 18: m7s.TrackSnapShotResponse.memory:type_name -> m7s.MemoryBlockGroup
|
||||||
33, // 19: m7s.SubscriberSnapShot.startTime:type_name -> google.protobuf.Timestamp
|
34, // 19: m7s.SubscriberSnapShot.startTime:type_name -> google.protobuf.Timestamp
|
||||||
25, // 20: m7s.SubscriberSnapShot.audioReader:type_name -> m7s.RingReaderSnapShot
|
26, // 20: m7s.SubscriberSnapShot.audioReader:type_name -> m7s.RingReaderSnapShot
|
||||||
25, // 21: m7s.SubscriberSnapShot.videoReader:type_name -> m7s.RingReaderSnapShot
|
26, // 21: m7s.SubscriberSnapShot.videoReader:type_name -> m7s.RingReaderSnapShot
|
||||||
26, // 22: m7s.SubscribersResponse.list:type_name -> m7s.SubscriberSnapShot
|
27, // 22: m7s.SubscribersResponse.list:type_name -> m7s.SubscriberSnapShot
|
||||||
1, // 23: m7s.Formily.PropertiesEntry.value:type_name -> m7s.Formily
|
1, // 23: m7s.Formily.PropertiesEntry.value:type_name -> m7s.Formily
|
||||||
34, // 24: m7s.Formily.ComponentPropsEntry.value:type_name -> google.protobuf.Any
|
35, // 24: m7s.Formily.ComponentPropsEntry.value:type_name -> google.protobuf.Any
|
||||||
1, // 25: m7s.FormilyResponse.PropertiesEntry.value:type_name -> m7s.Formily
|
1, // 25: m7s.FormilyResponse.PropertiesEntry.value:type_name -> m7s.Formily
|
||||||
35, // 26: m7s.Global.SysInfo:input_type -> google.protobuf.Empty
|
36, // 26: m7s.Global.SysInfo:input_type -> google.protobuf.Empty
|
||||||
35, // 27: m7s.Global.Summary:input_type -> google.protobuf.Empty
|
36, // 27: m7s.Global.Summary:input_type -> google.protobuf.Empty
|
||||||
23, // 28: m7s.Global.Shutdown:input_type -> m7s.RequestWithId
|
23, // 28: m7s.Global.Shutdown:input_type -> m7s.RequestWithId
|
||||||
23, // 29: m7s.Global.Restart:input_type -> m7s.RequestWithId
|
23, // 29: m7s.Global.Restart:input_type -> m7s.RequestWithId
|
||||||
10, // 30: m7s.Global.StreamList:input_type -> m7s.StreamListRequest
|
10, // 30: m7s.Global.StreamList:input_type -> m7s.StreamListRequest
|
||||||
35, // 31: m7s.Global.WaitList:input_type -> google.protobuf.Empty
|
36, // 31: m7s.Global.WaitList:input_type -> google.protobuf.Empty
|
||||||
13, // 32: m7s.Global.StreamInfo:input_type -> m7s.StreamSnapRequest
|
13, // 32: m7s.Global.StreamInfo:input_type -> m7s.StreamSnapRequest
|
||||||
24, // 33: m7s.Global.GetSubscribers:input_type -> m7s.SubscribersRequest
|
25, // 33: m7s.Global.GetSubscribers:input_type -> m7s.SubscribersRequest
|
||||||
13, // 34: m7s.Global.AudioTrackSnap:input_type -> m7s.StreamSnapRequest
|
13, // 34: m7s.Global.AudioTrackSnap:input_type -> m7s.StreamSnapRequest
|
||||||
13, // 35: m7s.Global.VideoTrackSnap:input_type -> m7s.StreamSnapRequest
|
13, // 35: m7s.Global.VideoTrackSnap:input_type -> m7s.StreamSnapRequest
|
||||||
23, // 36: m7s.Global.StopSubscribe:input_type -> m7s.RequestWithId
|
24, // 36: m7s.Global.ChangeSubscribe:input_type -> m7s.ChangeSubscribeRequest
|
||||||
0, // 37: m7s.Global.GetConfig:input_type -> m7s.GetConfigRequest
|
23, // 37: m7s.Global.StopSubscribe:input_type -> m7s.RequestWithId
|
||||||
0, // 38: m7s.Global.GetFormily:input_type -> m7s.GetConfigRequest
|
0, // 38: m7s.Global.GetConfig:input_type -> m7s.GetConfigRequest
|
||||||
4, // 39: m7s.Global.ModifyConfig:input_type -> m7s.ModifyConfigRequest
|
0, // 39: m7s.Global.GetFormily:input_type -> m7s.GetConfigRequest
|
||||||
9, // 40: m7s.Global.SysInfo:output_type -> m7s.SysInfoResponse
|
4, // 40: m7s.Global.ModifyConfig:input_type -> m7s.ModifyConfigRequest
|
||||||
7, // 41: m7s.Global.Summary:output_type -> m7s.SummaryResponse
|
9, // 41: m7s.Global.SysInfo:output_type -> m7s.SysInfoResponse
|
||||||
35, // 42: m7s.Global.Shutdown:output_type -> google.protobuf.Empty
|
7, // 42: m7s.Global.Summary:output_type -> m7s.SummaryResponse
|
||||||
35, // 43: m7s.Global.Restart:output_type -> google.protobuf.Empty
|
36, // 43: m7s.Global.Shutdown:output_type -> google.protobuf.Empty
|
||||||
11, // 44: m7s.Global.StreamList:output_type -> m7s.StreamListResponse
|
36, // 44: m7s.Global.Restart:output_type -> google.protobuf.Empty
|
||||||
12, // 45: m7s.Global.WaitList:output_type -> m7s.StreamWaitListResponse
|
11, // 45: m7s.Global.StreamList:output_type -> m7s.StreamListResponse
|
||||||
14, // 46: m7s.Global.StreamInfo:output_type -> m7s.StreamInfoResponse
|
12, // 46: m7s.Global.WaitList:output_type -> m7s.StreamWaitListResponse
|
||||||
27, // 47: m7s.Global.GetSubscribers:output_type -> m7s.SubscribersResponse
|
14, // 47: m7s.Global.StreamInfo:output_type -> m7s.StreamInfoResponse
|
||||||
20, // 48: m7s.Global.AudioTrackSnap:output_type -> m7s.TrackSnapShotResponse
|
28, // 48: m7s.Global.GetSubscribers:output_type -> m7s.SubscribersResponse
|
||||||
20, // 49: m7s.Global.VideoTrackSnap:output_type -> m7s.TrackSnapShotResponse
|
20, // 49: m7s.Global.AudioTrackSnap:output_type -> m7s.TrackSnapShotResponse
|
||||||
22, // 50: m7s.Global.StopSubscribe:output_type -> m7s.SuccessResponse
|
20, // 50: m7s.Global.VideoTrackSnap:output_type -> m7s.TrackSnapShotResponse
|
||||||
3, // 51: m7s.Global.GetConfig:output_type -> m7s.GetConfigResponse
|
22, // 51: m7s.Global.ChangeSubscribe:output_type -> m7s.SuccessResponse
|
||||||
3, // 52: m7s.Global.GetFormily:output_type -> m7s.GetConfigResponse
|
22, // 52: m7s.Global.StopSubscribe:output_type -> m7s.SuccessResponse
|
||||||
22, // 53: m7s.Global.ModifyConfig:output_type -> m7s.SuccessResponse
|
3, // 53: m7s.Global.GetConfig:output_type -> m7s.GetConfigResponse
|
||||||
40, // [40:54] is the sub-list for method output_type
|
3, // 54: m7s.Global.GetFormily:output_type -> m7s.GetConfigResponse
|
||||||
26, // [26:40] is the sub-list for method input_type
|
22, // 55: m7s.Global.ModifyConfig:output_type -> m7s.SuccessResponse
|
||||||
|
41, // [41:56] is the sub-list for method output_type
|
||||||
|
26, // [26:41] is the sub-list for method input_type
|
||||||
26, // [26:26] is the sub-list for extension type_name
|
26, // [26:26] is the sub-list for extension type_name
|
||||||
26, // [26:26] is the sub-list for extension extendee
|
26, // [26:26] is the sub-list for extension extendee
|
||||||
0, // [0:26] is the sub-list for field type_name
|
0, // [0:26] is the sub-list for field type_name
|
||||||
@@ -2729,7 +2799,7 @@ func file_global_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_global_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
|
file_global_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*SubscribersRequest); i {
|
switch v := v.(*ChangeSubscribeRequest); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2741,7 +2811,7 @@ func file_global_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_global_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
|
file_global_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*RingReaderSnapShot); i {
|
switch v := v.(*SubscribersRequest); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2753,7 +2823,7 @@ func file_global_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_global_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
|
file_global_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*SubscriberSnapShot); i {
|
switch v := v.(*RingReaderSnapShot); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2765,6 +2835,18 @@ func file_global_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_global_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
|
file_global_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*SubscriberSnapShot); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_global_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*SubscribersResponse); i {
|
switch v := v.(*SubscribersResponse); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@@ -2783,7 +2865,7 @@ func file_global_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_global_proto_rawDesc,
|
RawDescriptor: file_global_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 33,
|
NumMessages: 34,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
@@ -452,6 +452,86 @@ func local_request_Global_VideoTrackSnap_0(ctx context.Context, marshaler runtim
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_Global_ChangeSubscribe_0(ctx context.Context, marshaler runtime.Marshaler, client GlobalClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ChangeSubscribeRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.Id, err = runtime.Uint32(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["streamPath"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "streamPath")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.StreamPath, err = runtime.String(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "streamPath", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ChangeSubscribe(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Global_ChangeSubscribe_0(ctx context.Context, marshaler runtime.Marshaler, server GlobalServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ChangeSubscribeRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.Id, err = runtime.Uint32(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["streamPath"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "streamPath")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.StreamPath, err = runtime.String(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "streamPath", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.ChangeSubscribe(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_Global_StopSubscribe_0(ctx context.Context, marshaler runtime.Marshaler, client GlobalClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_Global_StopSubscribe_0(ctx context.Context, marshaler runtime.Marshaler, client GlobalClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq RequestWithId
|
var protoReq RequestWithId
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
@@ -932,6 +1012,31 @@ func RegisterGlobalHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Global_ChangeSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/m7s.Global/ChangeSubscribe", runtime.WithHTTPPathPattern("/api/subscribe/change/{id}/{streamPath=**}"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Global_ChangeSubscribe_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Global_ChangeSubscribe_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("POST", pattern_Global_StopSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("POST", pattern_Global_StopSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -940,7 +1045,7 @@ func RegisterGlobalHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
|
|||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
var err error
|
var err error
|
||||||
var annotatedContext context.Context
|
var annotatedContext context.Context
|
||||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/m7s.Global/StopSubscribe", runtime.WithHTTPPathPattern("/api/stop/subscribe/{id}"))
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/m7s.Global/StopSubscribe", runtime.WithHTTPPathPattern("/api/subscribe/stop/{id}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
@@ -1293,13 +1398,35 @@ func RegisterGlobalHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Global_ChangeSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/m7s.Global/ChangeSubscribe", runtime.WithHTTPPathPattern("/api/subscribe/change/{id}/{streamPath=**}"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Global_ChangeSubscribe_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Global_ChangeSubscribe_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("POST", pattern_Global_StopSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("POST", pattern_Global_StopSubscribe_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
var err error
|
var err error
|
||||||
var annotatedContext context.Context
|
var annotatedContext context.Context
|
||||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/m7s.Global/StopSubscribe", runtime.WithHTTPPathPattern("/api/stop/subscribe/{id}"))
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/m7s.Global/StopSubscribe", runtime.WithHTTPPathPattern("/api/subscribe/stop/{id}"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
return
|
return
|
||||||
@@ -1405,7 +1532,9 @@ var (
|
|||||||
|
|
||||||
pattern_Global_VideoTrackSnap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 3, 0, 4, 1, 5, 3}, []string{"api", "videotrack", "snap", "streamPath"}, ""))
|
pattern_Global_VideoTrackSnap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 3, 0, 4, 1, 5, 3}, []string{"api", "videotrack", "snap", "streamPath"}, ""))
|
||||||
|
|
||||||
pattern_Global_StopSubscribe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "stop", "subscribe", "id"}, ""))
|
pattern_Global_ChangeSubscribe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 3, 0, 4, 1, 5, 4}, []string{"api", "subscribe", "change", "id", "streamPath"}, ""))
|
||||||
|
|
||||||
|
pattern_Global_StopSubscribe_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "subscribe", "stop", "id"}, ""))
|
||||||
|
|
||||||
pattern_Global_GetConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "config", "get", "name"}, ""))
|
pattern_Global_GetConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "config", "get", "name"}, ""))
|
||||||
|
|
||||||
@@ -1435,6 +1564,8 @@ var (
|
|||||||
|
|
||||||
forward_Global_VideoTrackSnap_0 = runtime.ForwardResponseMessage
|
forward_Global_VideoTrackSnap_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Global_ChangeSubscribe_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Global_StopSubscribe_0 = runtime.ForwardResponseMessage
|
forward_Global_StopSubscribe_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_Global_GetConfig_0 = runtime.ForwardResponseMessage
|
forward_Global_GetConfig_0 = runtime.ForwardResponseMessage
|
||||||
|
@@ -57,9 +57,16 @@ service Global {
|
|||||||
get: "/api/videotrack/snap/{streamPath=**}"
|
get: "/api/videotrack/snap/{streamPath=**}"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
rpc ChangeSubscribe (ChangeSubscribeRequest) returns (SuccessResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
post: "/api/subscribe/change/{id}/{streamPath=**}"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc StopSubscribe (RequestWithId) returns (SuccessResponse) {
|
rpc StopSubscribe (RequestWithId) returns (SuccessResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/api/stop/subscribe/{id}"
|
post: "/api/subscribe/stop/{id}"
|
||||||
body: "*"
|
body: "*"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -243,6 +250,11 @@ message RequestWithId {
|
|||||||
uint32 id = 1;
|
uint32 id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ChangeSubscribeRequest {
|
||||||
|
uint32 id = 1;
|
||||||
|
string streamPath = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message SubscribersRequest {
|
message SubscribersRequest {
|
||||||
string streamPath = 1;
|
string streamPath = 1;
|
||||||
int32 pageNum = 2;
|
int32 pageNum = 2;
|
||||||
|
@@ -33,6 +33,7 @@ type GlobalClient interface {
|
|||||||
GetSubscribers(ctx context.Context, in *SubscribersRequest, opts ...grpc.CallOption) (*SubscribersResponse, error)
|
GetSubscribers(ctx context.Context, in *SubscribersRequest, opts ...grpc.CallOption) (*SubscribersResponse, error)
|
||||||
AudioTrackSnap(ctx context.Context, in *StreamSnapRequest, opts ...grpc.CallOption) (*TrackSnapShotResponse, error)
|
AudioTrackSnap(ctx context.Context, in *StreamSnapRequest, opts ...grpc.CallOption) (*TrackSnapShotResponse, error)
|
||||||
VideoTrackSnap(ctx context.Context, in *StreamSnapRequest, opts ...grpc.CallOption) (*TrackSnapShotResponse, error)
|
VideoTrackSnap(ctx context.Context, in *StreamSnapRequest, opts ...grpc.CallOption) (*TrackSnapShotResponse, error)
|
||||||
|
ChangeSubscribe(ctx context.Context, in *ChangeSubscribeRequest, opts ...grpc.CallOption) (*SuccessResponse, error)
|
||||||
StopSubscribe(ctx context.Context, in *RequestWithId, opts ...grpc.CallOption) (*SuccessResponse, error)
|
StopSubscribe(ctx context.Context, in *RequestWithId, opts ...grpc.CallOption) (*SuccessResponse, error)
|
||||||
GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error)
|
GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error)
|
||||||
GetFormily(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error)
|
GetFormily(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error)
|
||||||
@@ -137,6 +138,15 @@ func (c *globalClient) VideoTrackSnap(ctx context.Context, in *StreamSnapRequest
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *globalClient) ChangeSubscribe(ctx context.Context, in *ChangeSubscribeRequest, opts ...grpc.CallOption) (*SuccessResponse, error) {
|
||||||
|
out := new(SuccessResponse)
|
||||||
|
err := c.cc.Invoke(ctx, "/m7s.Global/ChangeSubscribe", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *globalClient) StopSubscribe(ctx context.Context, in *RequestWithId, opts ...grpc.CallOption) (*SuccessResponse, error) {
|
func (c *globalClient) StopSubscribe(ctx context.Context, in *RequestWithId, opts ...grpc.CallOption) (*SuccessResponse, error) {
|
||||||
out := new(SuccessResponse)
|
out := new(SuccessResponse)
|
||||||
err := c.cc.Invoke(ctx, "/m7s.Global/StopSubscribe", in, out, opts...)
|
err := c.cc.Invoke(ctx, "/m7s.Global/StopSubscribe", in, out, opts...)
|
||||||
@@ -187,6 +197,7 @@ type GlobalServer interface {
|
|||||||
GetSubscribers(context.Context, *SubscribersRequest) (*SubscribersResponse, error)
|
GetSubscribers(context.Context, *SubscribersRequest) (*SubscribersResponse, error)
|
||||||
AudioTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error)
|
AudioTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error)
|
||||||
VideoTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error)
|
VideoTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error)
|
||||||
|
ChangeSubscribe(context.Context, *ChangeSubscribeRequest) (*SuccessResponse, error)
|
||||||
StopSubscribe(context.Context, *RequestWithId) (*SuccessResponse, error)
|
StopSubscribe(context.Context, *RequestWithId) (*SuccessResponse, error)
|
||||||
GetConfig(context.Context, *GetConfigRequest) (*GetConfigResponse, error)
|
GetConfig(context.Context, *GetConfigRequest) (*GetConfigResponse, error)
|
||||||
GetFormily(context.Context, *GetConfigRequest) (*GetConfigResponse, error)
|
GetFormily(context.Context, *GetConfigRequest) (*GetConfigResponse, error)
|
||||||
@@ -228,6 +239,9 @@ func (UnimplementedGlobalServer) AudioTrackSnap(context.Context, *StreamSnapRequ
|
|||||||
func (UnimplementedGlobalServer) VideoTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error) {
|
func (UnimplementedGlobalServer) VideoTrackSnap(context.Context, *StreamSnapRequest) (*TrackSnapShotResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method VideoTrackSnap not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method VideoTrackSnap not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedGlobalServer) ChangeSubscribe(context.Context, *ChangeSubscribeRequest) (*SuccessResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ChangeSubscribe not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedGlobalServer) StopSubscribe(context.Context, *RequestWithId) (*SuccessResponse, error) {
|
func (UnimplementedGlobalServer) StopSubscribe(context.Context, *RequestWithId) (*SuccessResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method StopSubscribe not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method StopSubscribe not implemented")
|
||||||
}
|
}
|
||||||
@@ -433,6 +447,24 @@ func _Global_VideoTrackSnap_Handler(srv interface{}, ctx context.Context, dec fu
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Global_ChangeSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(ChangeSubscribeRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(GlobalServer).ChangeSubscribe(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/m7s.Global/ChangeSubscribe",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(GlobalServer).ChangeSubscribe(ctx, req.(*ChangeSubscribeRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
func _Global_StopSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _Global_StopSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(RequestWithId)
|
in := new(RequestWithId)
|
||||||
if err := dec(in); err != nil {
|
if err := dec(in); err != nil {
|
||||||
@@ -552,6 +584,10 @@ var Global_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "VideoTrackSnap",
|
MethodName: "VideoTrackSnap",
|
||||||
Handler: _Global_VideoTrackSnap_Handler,
|
Handler: _Global_VideoTrackSnap_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ChangeSubscribe",
|
||||||
|
Handler: _Global_ChangeSubscribe_Handler,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
MethodName: "StopSubscribe",
|
MethodName: "StopSubscribe",
|
||||||
Handler: _Global_StopSubscribe_Handler,
|
Handler: _Global_StopSubscribe_Handler,
|
||||||
|
@@ -16,4 +16,5 @@ var (
|
|||||||
ErrInterrupt = errors.New("interrupt")
|
ErrInterrupt = errors.New("interrupt")
|
||||||
ErrUnsupportCodec = errors.New("unsupport codec")
|
ErrUnsupportCodec = errors.New("unsupport codec")
|
||||||
ErrMuted = errors.New("muted")
|
ErrMuted = errors.New("muted")
|
||||||
|
ErrorLost = errors.New("lost")
|
||||||
)
|
)
|
||||||
|
@@ -80,8 +80,11 @@ func (rb *RingWriter) Reduce(size int) (r *util.Ring[AVFrame]) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rb *RingWriter) Dispose() {
|
||||||
|
rb.Value.Ready()
|
||||||
|
}
|
||||||
|
|
||||||
func (rb *RingWriter) Step() (normal bool) {
|
func (rb *RingWriter) Step() (normal bool) {
|
||||||
// rb.LastValue.Broadcast() // 防止订阅者还在等待
|
|
||||||
rb.LastValue = &rb.Value
|
rb.LastValue = &rb.Value
|
||||||
nextSeq := rb.LastValue.Sequence + 1
|
nextSeq := rb.LastValue.Sequence + 1
|
||||||
next := rb.Next()
|
next := rb.Next()
|
||||||
@@ -91,7 +94,10 @@ func (rb *RingWriter) Step() (normal bool) {
|
|||||||
} else {
|
} else {
|
||||||
rb.Reduce(1) //抛弃还有订阅者的节点
|
rb.Reduce(1) //抛弃还有订阅者的节点
|
||||||
rb.Ring = rb.Glow(1) //补充一个新节点
|
rb.Ring = rb.Glow(1) //补充一个新节点
|
||||||
rb.Value.StartWrite()
|
normal = rb.Value.StartWrite()
|
||||||
|
if !normal {
|
||||||
|
panic("RingWriter.Step")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rb.Value.Sequence = nextSeq
|
rb.Value.Sequence = nextSeq
|
||||||
rb.LastValue.Ready()
|
rb.LastValue.Ready()
|
||||||
|
11
pkg/unit.go
11
pkg/unit.go
@@ -20,12 +20,11 @@ func (unit *Unit) Trace(msg string, fields ...any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (unit *Unit) IsStopped() bool {
|
func (unit *Unit) IsStopped() bool {
|
||||||
select {
|
return unit.StopReason() != nil
|
||||||
case <-unit.Done():
|
}
|
||||||
return true
|
|
||||||
default:
|
func (unit *Unit) StopReason() error {
|
||||||
}
|
return context.Cause(unit.Context)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (unit *Unit) Stop(err error) {
|
func (unit *Unit) Stop(err error) {
|
||||||
|
@@ -9,17 +9,17 @@ type (
|
|||||||
Start, End int
|
Start, End int
|
||||||
trees [2]Tree
|
trees [2]Tree
|
||||||
}
|
}
|
||||||
// History struct {
|
History struct {
|
||||||
// Malloc bool
|
Malloc bool
|
||||||
// Offset int
|
Offset int
|
||||||
// Size int
|
Size int
|
||||||
// }
|
}
|
||||||
Allocator struct {
|
Allocator struct {
|
||||||
pool []*Block
|
pool []*Block
|
||||||
sizeTree *Block
|
sizeTree *Block
|
||||||
offsetTree *Block
|
offsetTree *Block
|
||||||
Size int
|
Size int
|
||||||
// history []History
|
//history []History
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ func (b *Block) delete(block *Block, treeIndex int) *Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) Allocate(size int) (offset int) {
|
func (a *Allocator) Allocate(size int) (offset int) {
|
||||||
// a.history = append(a.history, History{Malloc: true, Size: size})
|
//a.history = append(a.history, History{Malloc: true, Size: size})
|
||||||
block := a.findAvailableBlock(a.sizeTree, size)
|
block := a.findAvailableBlock(a.sizeTree, size)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return -1
|
return -1
|
||||||
@@ -207,7 +207,7 @@ func (a *Allocator) putBlock(b *Block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) Free(offset, size int) {
|
func (a *Allocator) Free(offset, size int) {
|
||||||
// a.history = append(a.history, History{Malloc: false, Offset: offset, Size: size})
|
//a.history = append(a.history, History{Malloc: false, Offset: offset, Size: size})
|
||||||
block := a.getBlock(offset, offset+size)
|
block := a.getBlock(offset, offset+size)
|
||||||
a.sizeTree, a.offsetTree = a.sizeTree.insert(block, 0), a.offsetTree.insert(block, 1)
|
a.sizeTree, a.offsetTree = a.sizeTree.insert(block, 0), a.offsetTree.insert(block, 1)
|
||||||
a.mergeAdjacentBlocks(block)
|
a.mergeAdjacentBlocks(block)
|
||||||
|
122
pkg/util/buddy.go
Normal file
122
pkg/util/buddy.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Buddy struct {
|
||||||
|
size int
|
||||||
|
longests []int
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
InValidParameterErr = errors.New("buddy: invalid parameter")
|
||||||
|
NotFoundErr = errors.New("buddy: can't find block")
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewBuddy creates a buddy instance.
|
||||||
|
// If the parameter isn't valid, return the nil and error as well
|
||||||
|
func NewBuddy(size int) *Buddy {
|
||||||
|
if !isPowerOf2(size) {
|
||||||
|
size = fixSize(size)
|
||||||
|
}
|
||||||
|
nodeCount := 2*size - 1
|
||||||
|
longests := make([]int, nodeCount)
|
||||||
|
for nodeSize, i := 2*size, 0; i < nodeCount; i++ {
|
||||||
|
if isPowerOf2(i + 1) {
|
||||||
|
nodeSize /= 2
|
||||||
|
}
|
||||||
|
longests[i] = nodeSize
|
||||||
|
}
|
||||||
|
return &Buddy{size, longests}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alloc find a unused block according to the size
|
||||||
|
// return the offset of the block(regard 0 as the beginning)
|
||||||
|
// and parameter error if any
|
||||||
|
func (b *Buddy) Alloc(size int) (offset int, err error) {
|
||||||
|
if size <= 0 {
|
||||||
|
err = InValidParameterErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !isPowerOf2(size) {
|
||||||
|
size = fixSize(size)
|
||||||
|
}
|
||||||
|
if size > b.longests[0] {
|
||||||
|
err = NotFoundErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
index := 0
|
||||||
|
for nodeSize := b.size; nodeSize != size; nodeSize /= 2 {
|
||||||
|
if left := leftChild(index); b.longests[left] >= size {
|
||||||
|
index = left
|
||||||
|
} else {
|
||||||
|
index = rightChild(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.longests[index] = 0 // mark zero as used
|
||||||
|
offset = (index+1)*size - b.size
|
||||||
|
// update the parent node's size
|
||||||
|
for index != 0 {
|
||||||
|
index = parent(index)
|
||||||
|
b.longests[index] = max(b.longests[leftChild(index)], b.longests[rightChild(index)])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free find a block according to the offset and mark it as unused
|
||||||
|
// return error if not found or parameter invalid
|
||||||
|
func (b *Buddy) Free(offset int) error {
|
||||||
|
if offset < 0 || offset >= b.size {
|
||||||
|
return InValidParameterErr
|
||||||
|
}
|
||||||
|
nodeSize := 1
|
||||||
|
index := offset + b.size - 1
|
||||||
|
for ; b.longests[index] != 0; index = parent(index) {
|
||||||
|
nodeSize *= 2
|
||||||
|
if index == 0 {
|
||||||
|
return NotFoundErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.longests[index] = nodeSize
|
||||||
|
// update parent node's size
|
||||||
|
for index != 0 {
|
||||||
|
index = parent(index)
|
||||||
|
nodeSize *= 2
|
||||||
|
|
||||||
|
leftSize := b.longests[leftChild(index)]
|
||||||
|
rightSize := b.longests[rightChild(index)]
|
||||||
|
if leftSize+rightSize == nodeSize {
|
||||||
|
b.longests[index] = nodeSize
|
||||||
|
} else {
|
||||||
|
b.longests[index] = max(leftSize, rightSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
func isPowerOf2(size int) bool {
|
||||||
|
return size&(size-1) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func fixSize(size int) int {
|
||||||
|
size |= size >> 1
|
||||||
|
size |= size >> 2
|
||||||
|
size |= size >> 4
|
||||||
|
size |= size >> 8
|
||||||
|
size |= size >> 16
|
||||||
|
return size + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func leftChild(index int) int {
|
||||||
|
return 2*index + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func rightChild(index int) int {
|
||||||
|
return 2*index + 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func parent(index int) int {
|
||||||
|
return (index+1)/2 - 1
|
||||||
|
}
|
@@ -4,7 +4,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultBufSize = 65536
|
const defaultBufSize = 1 << 16
|
||||||
|
|
||||||
type BufReader struct {
|
type BufReader struct {
|
||||||
reader io.Reader
|
reader io.Reader
|
||||||
@@ -95,6 +95,12 @@ func (r *BufReader) ReadBE32(n int) (num uint32, err error) {
|
|||||||
|
|
||||||
func (r *BufReader) ReadBytes(n int) (mem RecyclableMemory, err error) {
|
func (r *BufReader) ReadBytes(n int) (mem RecyclableMemory, err error) {
|
||||||
mem.ScalableMemoryAllocator = r.allocator
|
mem.ScalableMemoryAllocator = r.allocator
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
mem.Recycle()
|
||||||
|
mem = RecyclableMemory{}
|
||||||
|
}
|
||||||
|
}()
|
||||||
for r.recycleFront(); n > 0 && err == nil; err = r.eat() {
|
for r.recycleFront(); n > 0 && err == nil; err = r.eat() {
|
||||||
if r.buf.Length > 0 {
|
if r.buf.Length > 0 {
|
||||||
if r.buf.Length >= n {
|
if r.buf.Length >= n {
|
||||||
|
@@ -30,10 +30,11 @@ func (c *Collection[K, T]) Add(item T) {
|
|||||||
c.Length++
|
c.Length++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection[K, T]) AddUnique(item T) {
|
func (c *Collection[K, T]) AddUnique(item T) (ok bool) {
|
||||||
if _, ok := c.Get(item.GetKey()); !ok {
|
if _, ok = c.Get(item.GetKey()); !ok {
|
||||||
c.Add(item)
|
c.Add(item)
|
||||||
}
|
}
|
||||||
|
return !ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection[K, T]) Set(item T) {
|
func (c *Collection[K, T]) Set(item T) {
|
||||||
@@ -50,6 +51,18 @@ func (c *Collection[K, T]) Set(item T) {
|
|||||||
c.Add(item)
|
c.Add(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Collection[K, T]) Range(f func(T) bool) {
|
||||||
|
if c.L != nil {
|
||||||
|
c.L.RLock()
|
||||||
|
defer c.L.RUnlock()
|
||||||
|
}
|
||||||
|
for _, item := range c.Items {
|
||||||
|
if !f(item) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Collection[K, T]) Remove(item T) {
|
func (c *Collection[K, T]) Remove(item T) {
|
||||||
c.RemoveByKey(item.GetKey())
|
c.RemoveByKey(item.GetKey())
|
||||||
}
|
}
|
||||||
|
@@ -6,10 +6,19 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxBlockSize = 4 * 1024 * 1024
|
const (
|
||||||
|
MaxBlockSize = 1 << 22
|
||||||
|
BuddySize = MaxBlockSize << 4
|
||||||
|
MinPowerOf2 = 10
|
||||||
|
)
|
||||||
|
|
||||||
var pools sync.Map
|
var (
|
||||||
var EnableCheckSize bool = false
|
memoryPool [BuddySize]byte
|
||||||
|
buddy = NewBuddy(BuddySize >> MinPowerOf2)
|
||||||
|
lock sync.Mutex
|
||||||
|
poolStart = int64(uintptr(unsafe.Pointer(&memoryPool[0])))
|
||||||
|
//EnableCheckSize bool = false
|
||||||
|
)
|
||||||
|
|
||||||
type MemoryAllocator struct {
|
type MemoryAllocator struct {
|
||||||
allocator *Allocator
|
allocator *Allocator
|
||||||
@@ -19,11 +28,19 @@ type MemoryAllocator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetMemoryAllocator(size int) (ret *MemoryAllocator) {
|
func GetMemoryAllocator(size int) (ret *MemoryAllocator) {
|
||||||
if value, ok := pools.Load(size); ok {
|
lock.Lock()
|
||||||
ret = value.(*sync.Pool).Get().(*MemoryAllocator)
|
offset, err := buddy.Alloc(size >> MinPowerOf2)
|
||||||
} else {
|
lock.Unlock()
|
||||||
ret = NewMemoryAllocator(size)
|
if err != nil {
|
||||||
|
return NewMemoryAllocator(size)
|
||||||
}
|
}
|
||||||
|
offset = offset << MinPowerOf2
|
||||||
|
ret = &MemoryAllocator{
|
||||||
|
Size: size,
|
||||||
|
memory: memoryPool[offset : offset+size],
|
||||||
|
allocator: NewAllocator(size),
|
||||||
|
}
|
||||||
|
ret.start = poolStart + int64(offset)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,14 +55,9 @@ func NewMemoryAllocator(size int) (ret *MemoryAllocator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ma *MemoryAllocator) Recycle() {
|
func (ma *MemoryAllocator) Recycle() {
|
||||||
ma.allocator = NewAllocator(ma.Size)
|
lock.Lock()
|
||||||
size := ma.Size
|
_ = buddy.Free(int((poolStart - ma.start) >> 10))
|
||||||
pool, _ := pools.LoadOrStore(size, &sync.Pool{
|
lock.Unlock()
|
||||||
New: func() any {
|
|
||||||
return NewMemoryAllocator(size)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
pool.(*sync.Pool).Put(ma)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ma *MemoryAllocator) Malloc(size int) (memory []byte) {
|
func (ma *MemoryAllocator) Malloc(size int) (memory []byte) {
|
||||||
@@ -77,10 +89,11 @@ type ScalableMemoryAllocator struct {
|
|||||||
totalMalloc int64
|
totalMalloc int64
|
||||||
totalFree int64
|
totalFree int64
|
||||||
size int
|
size int
|
||||||
|
childSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScalableMemoryAllocator(size int) (ret *ScalableMemoryAllocator) {
|
func NewScalableMemoryAllocator(size int) (ret *ScalableMemoryAllocator) {
|
||||||
return &ScalableMemoryAllocator{children: []*MemoryAllocator{GetMemoryAllocator(size)}, size: size}
|
return &ScalableMemoryAllocator{children: []*MemoryAllocator{GetMemoryAllocator(size)}, size: size, childSize: size}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma *ScalableMemoryAllocator) checkSize() {
|
func (sma *ScalableMemoryAllocator) checkSize() {
|
||||||
@@ -123,9 +136,9 @@ func (sma *ScalableMemoryAllocator) Malloc(size int) (memory []byte) {
|
|||||||
if sma == nil {
|
if sma == nil {
|
||||||
return make([]byte, size)
|
return make([]byte, size)
|
||||||
}
|
}
|
||||||
if EnableCheckSize {
|
//if EnableCheckSize {
|
||||||
defer sma.checkSize()
|
// defer sma.checkSize()
|
||||||
}
|
//}
|
||||||
defer sma.addMallocCount(size)
|
defer sma.addMallocCount(size)
|
||||||
var child *MemoryAllocator
|
var child *MemoryAllocator
|
||||||
for _, child = range sma.children {
|
for _, child = range sma.children {
|
||||||
@@ -133,7 +146,13 @@ func (sma *ScalableMemoryAllocator) Malloc(size int) (memory []byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
child = GetMemoryAllocator(max(min(MaxBlockSize, child.Size*2), size))
|
for sma.childSize <= MaxBlockSize {
|
||||||
|
sma.childSize = sma.childSize << 1
|
||||||
|
if sma.childSize >= size {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child = GetMemoryAllocator(sma.childSize)
|
||||||
sma.size += child.Size
|
sma.size += child.Size
|
||||||
memory = child.Malloc(size)
|
memory = child.Malloc(size)
|
||||||
sma.children = append(sma.children, child)
|
sma.children = append(sma.children, child)
|
||||||
@@ -148,9 +167,9 @@ func (sma *ScalableMemoryAllocator) Free(mem []byte) bool {
|
|||||||
if sma == nil {
|
if sma == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if EnableCheckSize {
|
//if EnableCheckSize {
|
||||||
defer sma.checkSize()
|
// defer sma.checkSize()
|
||||||
}
|
//}
|
||||||
ptr := int64(uintptr(unsafe.Pointer(&mem[0])))
|
ptr := int64(uintptr(unsafe.Pointer(&mem[0])))
|
||||||
size := len(mem)
|
size := len(mem)
|
||||||
for i, child := range sma.children {
|
for i, child := range sma.children {
|
||||||
|
@@ -332,12 +332,6 @@ func (p *Plugin) Subscribe(streamPath string, options ...any) (subscriber *Subsc
|
|||||||
switch v := option.(type) {
|
switch v := option.(type) {
|
||||||
case func(*config.Subscribe):
|
case func(*config.Subscribe):
|
||||||
v(&subscriber.Subscribe)
|
v(&subscriber.Subscribe)
|
||||||
case SubscriberHandler:
|
|
||||||
defer func() {
|
|
||||||
if err == nil {
|
|
||||||
subscriber.Handle(v)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subscriber.Init(p, streamPath, options...)
|
subscriber.Init(p, streamPath, options...)
|
||||||
|
@@ -109,11 +109,10 @@ func (p *HDLPlugin) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
defer binary.BigEndian.PutUint32(b[:4], uint32(data.Size)+11)
|
defer binary.BigEndian.PutUint32(b[:4], uint32(data.Size)+11)
|
||||||
return gotFlvTag(append(net.Buffers{b[:]}, data.Memory.Buffers...))
|
return gotFlvTag(append(net.Buffers{b[:]}, data.Memory.Buffers...))
|
||||||
}
|
}
|
||||||
sub.Handle(m7s.SubscriberHandler{
|
m7s.PlayBlock(sub, func(audio *rtmp.RTMPAudio) error {
|
||||||
OnAudio: func(audio *rtmp.RTMPAudio) error {
|
|
||||||
return rtmpData2FlvTag(FLV_TAG_TYPE_AUDIO, &audio.RTMPData)
|
return rtmpData2FlvTag(FLV_TAG_TYPE_AUDIO, &audio.RTMPData)
|
||||||
}, OnVideo: func(video *rtmp.RTMPVideo) error {
|
}, func(video *rtmp.RTMPVideo) error {
|
||||||
return rtmpData2FlvTag(FLV_TAG_TYPE_VIDEO, &video.RTMPData)
|
return rtmpData2FlvTag(FLV_TAG_TYPE_VIDEO, &video.RTMPData)
|
||||||
}})
|
})
|
||||||
gotFlvTag(net.Buffers{b[:4]})
|
gotFlvTag(net.Buffers{b[:4]})
|
||||||
}
|
}
|
||||||
|
@@ -104,7 +104,6 @@ func (puller *HDLPuller) Pull(p *m7s.Puller) (err error) {
|
|||||||
var frame rtmp.RTMPData
|
var frame rtmp.RTMPData
|
||||||
frame.RecyclableMemory, err = puller.ReadBytes(int(dataSize))
|
frame.RecyclableMemory, err = puller.ReadBytes(int(dataSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
frame.Recycle()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
puller.absTS = offsetTs + (timestamp - startTs)
|
puller.absTS = offsetTs + (timestamp - startTs)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package plugin_rtmp
|
package plugin_rtmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
@@ -42,13 +42,17 @@ func (p *RTMPPlugin) OnTCPConnect(conn *net.TCPConn) {
|
|||||||
logger := p.Logger.With("remote", conn.RemoteAddr().String())
|
logger := p.Logger.With("remote", conn.RemoteAddr().String())
|
||||||
receivers := make(map[uint32]*RTMPReceiver)
|
receivers := make(map[uint32]*RTMPReceiver)
|
||||||
var err error
|
var err error
|
||||||
logger.Info("conn")
|
|
||||||
nc := NewNetConnection(conn, logger)
|
nc := NewNetConnection(conn, logger)
|
||||||
defer nc.Destroy()
|
|
||||||
ctx, cancel := context.WithCancelCause(p)
|
|
||||||
defer func() {
|
defer func() {
|
||||||
logger.Info("conn close")
|
nc.Destroy()
|
||||||
cancel(err)
|
if p := recover(); p != nil {
|
||||||
|
err = p.(error)
|
||||||
|
}
|
||||||
|
if len(receivers) > 0 {
|
||||||
|
for _, receiver := range receivers {
|
||||||
|
receiver.Dispose(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
/* Handshake */
|
/* Handshake */
|
||||||
if err = nc.Handshake(p.C2); err != nil {
|
if err = nc.Handshake(p.C2); err != nil {
|
||||||
@@ -156,7 +160,7 @@ func (p *RTMPPlugin) OnTCPConnect(conn *net.TCPConn) {
|
|||||||
StreamID: cmd.StreamId,
|
StreamID: cmd.StreamId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
receiver.Publisher, err = p.Publish(nc.AppName+"/"+cmd.PublishingName, ctx, conn, connectInfo)
|
receiver.Publisher, err = p.Publish(nc.AppName+"/"+cmd.PublishingName, p.Context, conn, connectInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
delete(receivers, cmd.StreamId)
|
delete(receivers, cmd.StreamId)
|
||||||
err = receiver.Response(cmd.TransactionId, NetStream_Publish_BadName, Level_Error)
|
err = receiver.Response(cmd.TransactionId, NetStream_Publish_BadName, Level_Error)
|
||||||
@@ -176,18 +180,13 @@ func (p *RTMPPlugin) OnTCPConnect(conn *net.TCPConn) {
|
|||||||
}
|
}
|
||||||
var suber *m7s.Subscriber
|
var suber *m7s.Subscriber
|
||||||
// sender.ID = fmt.Sprintf("%s|%d", conn.RemoteAddr().String(), sender.StreamID)
|
// sender.ID = fmt.Sprintf("%s|%d", conn.RemoteAddr().String(), sender.StreamID)
|
||||||
suber, err = p.Subscribe(streamPath, ctx, conn, connectInfo)
|
suber, err = p.Subscribe(streamPath, p.Context, conn, connectInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = ns.Response(cmd.TransactionId, NetStream_Play_Failed, Level_Error)
|
err = ns.Response(cmd.TransactionId, NetStream_Play_Failed, Level_Error)
|
||||||
} else {
|
} else {
|
||||||
ns.BeginPlay(cmd.TransactionId)
|
ns.BeginPlay(cmd.TransactionId)
|
||||||
audio, video := ns.CreateSender()
|
audio, video := ns.CreateSender(false)
|
||||||
go suber.Handle(m7s.SubscriberHandler{
|
go m7s.PlayBlock(suber, audio.HandleAudio, video.HandleVideo)
|
||||||
OnAudio: func(a *RTMPAudio) error {
|
|
||||||
return audio.SendFrame(&a.RTMPData)
|
|
||||||
}, OnVideo: func(v *RTMPVideo) error {
|
|
||||||
return video.SendFrame(&v.RTMPData)
|
|
||||||
}})
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("sendMessage play", "error", err)
|
logger.Error("sendMessage play", "error", err)
|
||||||
@@ -209,7 +208,7 @@ func (p *RTMPPlugin) OnTCPConnect(conn *net.TCPConn) {
|
|||||||
logger.Warn("ReceiveVideo", "MessageStreamID", msg.MessageStreamID)
|
logger.Warn("ReceiveVideo", "MessageStreamID", msg.MessageStreamID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if err == io.EOF || err == io.ErrUnexpectedEOF {
|
} else if err == io.EOF || errors.Is(err, io.ErrUnexpectedEOF) {
|
||||||
logger.Info("rtmp client closed")
|
logger.Info("rtmp client closed")
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@@ -9,7 +9,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"m7s.live/m7s/v5"
|
"m7s.live/m7s/v5"
|
||||||
. "m7s.live/m7s/v5/pkg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
@@ -104,7 +103,13 @@ func (client *Client) Connect(p *m7s.Client) (err error) {
|
|||||||
|
|
||||||
func (puller *Client) Pull(p *m7s.Puller) (err error) {
|
func (puller *Client) Pull(p *m7s.Puller) (err error) {
|
||||||
p.MetaData = puller.ServerInfo
|
p.MetaData = puller.ServerInfo
|
||||||
defer puller.Close()
|
defer func() {
|
||||||
|
puller.Close()
|
||||||
|
if p := recover(); p != nil {
|
||||||
|
err = p.(error)
|
||||||
|
}
|
||||||
|
p.Dispose(err)
|
||||||
|
}()
|
||||||
err = puller.SendMessage(RTMP_MSG_AMF0_COMMAND, &CommandMessage{"createStream", 2})
|
err = puller.SendMessage(RTMP_MSG_AMF0_COMMAND, &CommandMessage{"createStream", 2})
|
||||||
for err == nil {
|
for err == nil {
|
||||||
msg, err := puller.RecvMessage()
|
msg, err := puller.RecvMessage()
|
||||||
@@ -185,19 +190,8 @@ func (pusher *Client) Push(p *m7s.Pusher) (err error) {
|
|||||||
})
|
})
|
||||||
} else if response, ok := msg.MsgData.(*ResponsePublishMessage); ok {
|
} else if response, ok := msg.MsgData.(*ResponsePublishMessage); ok {
|
||||||
if response.Infomation["code"] == NetStream_Publish_Start {
|
if response.Infomation["code"] == NetStream_Publish_Start {
|
||||||
audio, video := pusher.CreateSender()
|
audio, video := pusher.CreateSender(true)
|
||||||
go p.Handle(m7s.SubscriberHandler{
|
go m7s.PlayBlock(&p.Subscriber, audio.HandleAudio, video.HandleVideo)
|
||||||
OnAudio: func(a *RTMPAudio) error {
|
|
||||||
if audio.SendFrame(&a.RTMPData) != nil {
|
|
||||||
return ErrInterrupt
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}, OnVideo: func(v *RTMPVideo) error {
|
|
||||||
if video.SendFrame(&v.RTMPData) != nil {
|
|
||||||
return ErrInterrupt
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}})
|
|
||||||
} else {
|
} else {
|
||||||
return errors.New(response.Infomation["code"].(string))
|
return errors.New(response.Infomation["code"].(string))
|
||||||
}
|
}
|
||||||
|
@@ -116,18 +116,18 @@ func (nc *NetConnection) simple_handshake(C1 []byte, checkC2 bool) error {
|
|||||||
nc.Write(S0S1)
|
nc.Write(S0S1)
|
||||||
nc.Write(C1) // S2
|
nc.Write(C1) // S2
|
||||||
C2, err := nc.ReadBytes(C1S1_SIZE)
|
C2, err := nc.ReadBytes(C1S1_SIZE)
|
||||||
C2.Recycle()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
C2.Recycle()
|
||||||
if checkC2 {
|
if checkC2 {
|
||||||
buf := nc.mediaDataPool.NextN(C2.Size)
|
buf := nc.mediaDataPool.NextN(C2.Size)
|
||||||
C2.Read(buf)
|
_, err = C2.Read(buf)
|
||||||
if !bytes.Equal(buf[8:], S0S1[9:]) {
|
if !bytes.Equal(buf[8:], S0S1[9:]) {
|
||||||
return errors.New("C2 Error")
|
return errors.New("C2 Error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nc *NetConnection) complex_handshake(C1 []byte) error {
|
func (nc *NetConnection) complex_handshake(C1 []byte) error {
|
||||||
@@ -178,10 +178,10 @@ func (nc *NetConnection) complex_handshake(C1 []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer := net.Buffers{[]byte{RTMP_HANDSHAKE_VERSION}, S1, S2_Random, S2_Digest}
|
buffer := net.Buffers{[]byte{RTMP_HANDSHAKE_VERSION}, S1, S2_Random, S2_Digest}
|
||||||
buffer.WriteTo(nc)
|
_, err = buffer.WriteTo(nc)
|
||||||
b, _ := nc.ReadBytes(1536)
|
b, _ := nc.ReadBytes(1536)
|
||||||
b.Recycle()
|
b.Recycle()
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateClient(C1 []byte) (scheme int, challenge []byte, digest []byte, ok bool, err error) {
|
func validateClient(C1 []byte) (scheme int, challenge []byte, digest []byte, ok bool, err error) {
|
||||||
|
@@ -2,6 +2,7 @@ package rtmp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"m7s.live/m7s/v5/pkg"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"m7s.live/m7s/v5"
|
"m7s.live/m7s/v5"
|
||||||
@@ -10,12 +11,28 @@ import (
|
|||||||
type AVSender struct {
|
type AVSender struct {
|
||||||
*NetConnection
|
*NetConnection
|
||||||
ChunkHeader
|
ChunkHeader
|
||||||
|
errContinue bool
|
||||||
lastAbs uint32
|
lastAbs uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (av *AVSender) HandleAudio(frame *RTMPAudio) (err error) {
|
||||||
|
return av.SendFrame(&frame.RTMPData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (av *AVSender) HandleVideo(frame *RTMPVideo) (err error) {
|
||||||
|
return av.SendFrame(&frame.RTMPData)
|
||||||
|
}
|
||||||
|
|
||||||
func (av *AVSender) SendFrame(frame *RTMPData) (err error) {
|
func (av *AVSender) SendFrame(frame *RTMPData) (err error) {
|
||||||
// seq := frame.Sequence
|
// seq := frame.Sequence
|
||||||
payloadLen := frame.Size
|
payloadLen := frame.Size
|
||||||
|
if av.errContinue {
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
err = pkg.ErrInterrupt
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
if payloadLen == 0 {
|
if payloadLen == 0 {
|
||||||
err = errors.New("payload is empty")
|
err = errors.New("payload is empty")
|
||||||
// av.Error("payload is empty", zap.Error(err))
|
// av.Error("payload is empty", zap.Error(err))
|
||||||
@@ -47,7 +64,7 @@ func (av *AVSender) SendFrame(frame *RTMPData) (err error) {
|
|||||||
// if seq != frame.Sequence {
|
// if seq != frame.Sequence {
|
||||||
// return errors.New("sequence is not equal")
|
// return errors.New("sequence is not equal")
|
||||||
// }
|
// }
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type RTMPReceiver struct {
|
type RTMPReceiver struct {
|
||||||
|
@@ -74,13 +74,15 @@ func NewNetConnection(conn net.Conn, logger *slog.Logger) (ret *NetConnection) {
|
|||||||
tmpBuf: make(util.Buffer, 4),
|
tmpBuf: make(util.Buffer, 4),
|
||||||
chunkHeaderBuf: make(util.Buffer, 0, 20),
|
chunkHeaderBuf: make(util.Buffer, 0, 20),
|
||||||
}
|
}
|
||||||
ret.mediaDataPool.ScalableMemoryAllocator = util.NewScalableMemoryAllocator(1024)
|
ret.mediaDataPool.ScalableMemoryAllocator = util.NewScalableMemoryAllocator(1 << util.MinPowerOf2)
|
||||||
|
ret.Info("new connection")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (conn *NetConnection) Destroy() {
|
func (conn *NetConnection) Destroy() {
|
||||||
conn.Conn.Close()
|
conn.Conn.Close()
|
||||||
conn.BufReader.Recycle()
|
conn.BufReader.Recycle()
|
||||||
conn.mediaDataPool.Recycle()
|
conn.mediaDataPool.Recycle()
|
||||||
|
conn.Info("destroy connection")
|
||||||
}
|
}
|
||||||
func (conn *NetConnection) SendStreamID(eventType uint16, streamID uint32) (err error) {
|
func (conn *NetConnection) SendStreamID(eventType uint16, streamID uint32) (err error) {
|
||||||
return conn.SendMessage(RTMP_MSG_USER_CONTROL, &StreamIDMessage{UserControlMessage{EventType: eventType}, streamID})
|
return conn.SendMessage(RTMP_MSG_USER_CONTROL, &StreamIDMessage{UserControlMessage{EventType: eventType}, streamID})
|
||||||
@@ -141,13 +143,15 @@ func (conn *NetConnection) readChunk() (msg *Chunk, err error) {
|
|||||||
return nil, errors.New("get chunk type error :" + err.Error())
|
return nil, errors.New("get chunk type error :" + err.Error())
|
||||||
}
|
}
|
||||||
msgLen := int(chunk.MessageLength)
|
msgLen := int(chunk.MessageLength)
|
||||||
|
if msgLen == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
var mem util.RecyclableMemory
|
var mem util.RecyclableMemory
|
||||||
if unRead := msgLen - chunk.bufLen; unRead < conn.readChunkSize {
|
if unRead := msgLen - chunk.bufLen; unRead < conn.readChunkSize {
|
||||||
mem, err = conn.ReadBytes(unRead)
|
mem, err = conn.ReadBytes(unRead)
|
||||||
} else {
|
} else {
|
||||||
mem, err = conn.ReadBytes(conn.readChunkSize)
|
mem, err = conn.ReadBytes(conn.readChunkSize)
|
||||||
}
|
}
|
||||||
mem.Recycle()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -5,26 +5,28 @@ type NetStream struct {
|
|||||||
StreamID uint32
|
StreamID uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NetStream) CreateAudioSender() *AVSender {
|
func (ns *NetStream) CreateAudioSender(c bool) *AVSender {
|
||||||
var av AVSender
|
var av AVSender
|
||||||
av.NetConnection = ns.NetConnection
|
av.NetConnection = ns.NetConnection
|
||||||
av.ChunkStreamID = RTMP_CSID_AUDIO
|
av.ChunkStreamID = RTMP_CSID_AUDIO
|
||||||
av.MessageTypeID = RTMP_MSG_AUDIO
|
av.MessageTypeID = RTMP_MSG_AUDIO
|
||||||
av.MessageStreamID = ns.StreamID
|
av.MessageStreamID = ns.StreamID
|
||||||
|
av.errContinue = c
|
||||||
return &av
|
return &av
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NetStream) CreateVideoSender() *AVSender {
|
func (ns *NetStream) CreateVideoSender(c bool) *AVSender {
|
||||||
var av AVSender
|
var av AVSender
|
||||||
av.NetConnection = ns.NetConnection
|
av.NetConnection = ns.NetConnection
|
||||||
av.ChunkStreamID = RTMP_CSID_VIDEO
|
av.ChunkStreamID = RTMP_CSID_VIDEO
|
||||||
av.MessageTypeID = RTMP_MSG_VIDEO
|
av.MessageTypeID = RTMP_MSG_VIDEO
|
||||||
av.MessageStreamID = ns.StreamID
|
av.MessageStreamID = ns.StreamID
|
||||||
|
av.errContinue = c
|
||||||
return &av
|
return &av
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NetStream) CreateSender() (audio *AVSender, video *AVSender) {
|
func (ns *NetStream) CreateSender(c bool) (audio *AVSender, video *AVSender) {
|
||||||
return ns.CreateAudioSender(), ns.CreateVideoSender()
|
return ns.CreateAudioSender(c), ns.CreateVideoSender(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *NetStream) Response(tid uint64, code, level string) error {
|
func (ns *NetStream) Response(tid uint64, code, level string) error {
|
||||||
@@ -63,7 +65,7 @@ func (ns *NetStream) BeginPlay(tid uint64) (err error) {
|
|||||||
|
|
||||||
func (ns *NetStream) Close() error {
|
func (ns *NetStream) Close() error {
|
||||||
if ns.NetConnection != nil {
|
if ns.NetConnection != nil {
|
||||||
return ns.NetConnection.Close()
|
ns.NetConnection.Destroy()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -182,7 +182,7 @@ func (conf *WebRTCPlugin) Push_(w http.ResponseWriter, r *http.Request) {
|
|||||||
if !publisher.PubAudio {
|
if !publisher.PubAudio {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mem := util.NewScalableMemoryAllocator(1460 * 100)
|
mem := util.NewScalableMemoryAllocator(1 << 12)
|
||||||
defer mem.Recycle()
|
defer mem.Recycle()
|
||||||
frame := &mrtp.RTPAudio{}
|
frame := &mrtp.RTPAudio{}
|
||||||
frame.RTPCodecParameters = &codecP
|
frame.RTPCodecParameters = &codecP
|
||||||
@@ -222,7 +222,7 @@ func (conf *WebRTCPlugin) Push_(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var lastPLISent time.Time
|
var lastPLISent time.Time
|
||||||
mem := util.NewScalableMemoryAllocator(1460 * 100)
|
mem := util.NewScalableMemoryAllocator(1 << 12)
|
||||||
defer mem.Recycle()
|
defer mem.Recycle()
|
||||||
frame := &mrtp.RTPVideo{}
|
frame := &mrtp.RTPVideo{}
|
||||||
frame.RTPCodecParameters = &codecP
|
frame.RTPCodecParameters = &codecP
|
||||||
@@ -432,23 +432,20 @@ func (conf *WebRTCPlugin) Play_(w http.ResponseWriter, r *http.Request) {
|
|||||||
if videoSender == nil {
|
if videoSender == nil {
|
||||||
suber.SubVideo = false
|
suber.SubVideo = false
|
||||||
}
|
}
|
||||||
go suber.Handle(m7s.SubscriberHandler{
|
go m7s.PlayBlock(suber, func(frame *mrtp.RTPAudio) (err error) {
|
||||||
OnAudio: func(frame *mrtp.RTPAudio) (err error) {
|
|
||||||
for _, p := range frame.Packets {
|
for _, p := range frame.Packets {
|
||||||
if err = audioTLSRTP.WriteRTP(p); err != nil {
|
if err = audioTLSRTP.WriteRTP(p); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
},
|
}, func(frame *mrtp.RTPVideo) error {
|
||||||
OnVideo: func(frame *mrtp.RTPVideo) error {
|
|
||||||
for _, p := range frame.Packets {
|
for _, p := range frame.Packets {
|
||||||
if err := videoTLSRTP.WriteRTP(p); err != nil {
|
if err := videoTLSRTP.WriteRTP(p); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
conn.OnICECandidate(func(ice *ICECandidate) {
|
conn.OnICECandidate(func(ice *ICECandidate) {
|
||||||
|
59
publisher.go
59
publisher.go
@@ -1,6 +1,7 @@
|
|||||||
package m7s
|
package m7s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -17,6 +18,7 @@ const (
|
|||||||
PublisherStateTrackAdded
|
PublisherStateTrackAdded
|
||||||
PublisherStateSubscribed
|
PublisherStateSubscribed
|
||||||
PublisherStateWaitSubscriber
|
PublisherStateWaitSubscriber
|
||||||
|
PublisherStateDisposed
|
||||||
)
|
)
|
||||||
|
|
||||||
type SpeedControl struct {
|
type SpeedControl struct {
|
||||||
@@ -57,7 +59,7 @@ func (t *AVTracks) IsEmpty() bool {
|
|||||||
|
|
||||||
func (t *AVTracks) CreateSubTrack(dataType reflect.Type) (track *AVTrack) {
|
func (t *AVTracks) CreateSubTrack(dataType reflect.Type) (track *AVTrack) {
|
||||||
track = NewAVTrack(dataType, t.AVTrack)
|
track = NewAVTrack(dataType, t.AVTrack)
|
||||||
track.WrapIndex = len(t.Items)
|
track.WrapIndex = t.Length
|
||||||
t.Add(track)
|
t.Add(track)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -70,12 +72,16 @@ type Publisher struct {
|
|||||||
VideoTrack AVTracks
|
VideoTrack AVTracks
|
||||||
AudioTrack AVTracks
|
AudioTrack AVTracks
|
||||||
DataTrack *DataTrack
|
DataTrack *DataTrack
|
||||||
Subscribers map[*Subscriber]struct{} `json:"-" yaml:"-"`
|
Subscribers util.Collection[int, *Subscriber] `json:"-" yaml:"-"`
|
||||||
GOP int
|
GOP int
|
||||||
baseTs time.Duration
|
baseTs time.Duration
|
||||||
lastTs time.Duration
|
lastTs time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Publisher) SubscriberRange(yield func(sub *Subscriber) bool) {
|
||||||
|
p.Subscribers.Range(yield)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Publisher) GetKey() string {
|
func (p *Publisher) GetKey() string {
|
||||||
return p.StreamPath
|
return p.StreamPath
|
||||||
}
|
}
|
||||||
@@ -118,27 +124,25 @@ func (p *Publisher) checkTimeout() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Publisher) RemoveSubscriber(subscriber *Subscriber) (err error) {
|
func (p *Publisher) RemoveSubscriber(subscriber *Subscriber) {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
delete(p.Subscribers, subscriber)
|
p.Subscribers.Remove(subscriber)
|
||||||
p.Info("subscriber -1", "count", len(p.Subscribers))
|
p.Info("subscriber -1", "count", p.Subscribers.Length)
|
||||||
if p.State == PublisherStateSubscribed && len(p.Subscribers) == 0 {
|
if p.State == PublisherStateSubscribed && p.Subscribers.Length == 0 {
|
||||||
p.State = PublisherStateWaitSubscriber
|
p.State = PublisherStateWaitSubscriber
|
||||||
if p.DelayCloseTimeout > 0 {
|
if p.DelayCloseTimeout > 0 {
|
||||||
p.TimeoutTimer.Reset(p.DelayCloseTimeout)
|
p.TimeoutTimer.Reset(p.DelayCloseTimeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Publisher) AddSubscriber(subscriber *Subscriber) (err error) {
|
func (p *Publisher) AddSubscriber(subscriber *Subscriber) {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
subscriber.Publisher = p
|
subscriber.Publisher = p
|
||||||
if _, ok := p.Subscribers[subscriber]; !ok {
|
if p.Subscribers.AddUnique(subscriber) {
|
||||||
p.Subscribers[subscriber] = struct{}{}
|
p.Info("subscriber +1", "count", p.Subscribers.Length)
|
||||||
p.Info("subscriber +1", "count", len(p.Subscribers))
|
|
||||||
switch p.State {
|
switch p.State {
|
||||||
case PublisherStateTrackAdded, PublisherStateWaitSubscriber:
|
case PublisherStateTrackAdded, PublisherStateWaitSubscriber:
|
||||||
p.State = PublisherStateSubscribed
|
p.State = PublisherStateSubscribed
|
||||||
@@ -147,7 +151,6 @@ func (p *Publisher) AddSubscriber(subscriber *Subscriber) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Publisher) writeAV(t *AVTrack, data IAVFrame) {
|
func (p *Publisher) writeAV(t *AVTrack, data IAVFrame) {
|
||||||
@@ -179,11 +182,11 @@ func (p *Publisher) WriteVideo(data IAVFrame) (err error) {
|
|||||||
}
|
}
|
||||||
t := p.VideoTrack.AVTrack
|
t := p.VideoTrack.AVTrack
|
||||||
if t == nil {
|
if t == nil {
|
||||||
t = NewAVTrack(data, p.Logger.With("track", "video"), 50)
|
t = NewAVTrack(data, p.Logger.With("track", "video"), 100)
|
||||||
p.Lock()
|
p.Lock()
|
||||||
p.VideoTrack.AVTrack = t
|
p.VideoTrack.AVTrack = t
|
||||||
p.VideoTrack.Add(t)
|
p.VideoTrack.Add(t)
|
||||||
if len(p.Subscribers) > 0 {
|
if p.Subscribers.Length > 0 {
|
||||||
p.State = PublisherStateSubscribed
|
p.State = PublisherStateSubscribed
|
||||||
} else {
|
} else {
|
||||||
p.State = PublisherStateTrackAdded
|
p.State = PublisherStateTrackAdded
|
||||||
@@ -294,7 +297,7 @@ func (p *Publisher) WriteAudio(data IAVFrame) (err error) {
|
|||||||
p.Lock()
|
p.Lock()
|
||||||
p.AudioTrack.AVTrack = t
|
p.AudioTrack.AVTrack = t
|
||||||
p.AudioTrack.Add(t)
|
p.AudioTrack.Add(t)
|
||||||
if len(p.Subscribers) > 0 {
|
if p.Subscribers.Length > 0 {
|
||||||
p.State = PublisherStateSubscribed
|
p.State = PublisherStateSubscribed
|
||||||
} else {
|
} else {
|
||||||
p.State = PublisherStateTrackAdded
|
p.State = PublisherStateTrackAdded
|
||||||
@@ -319,7 +322,7 @@ func (p *Publisher) WriteData(data IDataFrame) (err error) {
|
|||||||
p.DataTrack = &DataTrack{}
|
p.DataTrack = &DataTrack{}
|
||||||
p.DataTrack.Logger = p.Logger.With("track", "data")
|
p.DataTrack.Logger = p.Logger.With("track", "data")
|
||||||
p.Lock()
|
p.Lock()
|
||||||
if len(p.Subscribers) > 0 {
|
if p.Subscribers.Length > 0 {
|
||||||
p.State = PublisherStateSubscribed
|
p.State = PublisherStateSubscribed
|
||||||
} else {
|
} else {
|
||||||
p.State = PublisherStateTrackAdded
|
p.State = PublisherStateTrackAdded
|
||||||
@@ -354,6 +357,25 @@ func (p *Publisher) GetVideoTrack(dataType reflect.Type) (t *AVTrack) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Publisher) Dispose(err error) {
|
||||||
|
p.Lock()
|
||||||
|
defer p.Unlock()
|
||||||
|
if p.State == PublisherStateDisposed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !errors.Is(p.StopReason(), ErrKick) && p.IsStopped() {
|
||||||
|
if !p.AudioTrack.IsEmpty() {
|
||||||
|
p.AudioTrack.Dispose()
|
||||||
|
}
|
||||||
|
if !p.VideoTrack.IsEmpty() {
|
||||||
|
p.VideoTrack.Dispose()
|
||||||
|
}
|
||||||
|
p.State = PublisherStateDisposed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Stop(err)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Publisher) TakeOver(old *Publisher) {
|
func (p *Publisher) TakeOver(old *Publisher) {
|
||||||
p.baseTs = old.lastTs
|
p.baseTs = old.lastTs
|
||||||
p.VideoTrack = old.VideoTrack
|
p.VideoTrack = old.VideoTrack
|
||||||
@@ -363,7 +385,10 @@ func (p *Publisher) TakeOver(old *Publisher) {
|
|||||||
p.AudioTrack.ICodecCtx = nil
|
p.AudioTrack.ICodecCtx = nil
|
||||||
p.AudioTrack.Logger = p.Logger.With("track", "audio")
|
p.AudioTrack.Logger = p.Logger.With("track", "audio")
|
||||||
p.DataTrack = old.DataTrack
|
p.DataTrack = old.DataTrack
|
||||||
p.Subscribers = old.Subscribers
|
for subscriber := range old.SubscriberRange {
|
||||||
|
p.AddSubscriber(subscriber)
|
||||||
|
}
|
||||||
|
old.Subscribers = util.Collection[int, *Subscriber]{}
|
||||||
// for _, track := range p.TransTrack {
|
// for _, track := range p.TransTrack {
|
||||||
// track.ICodecCtx = nil
|
// track.ICodecCtx = nil
|
||||||
// }
|
// }
|
||||||
|
68
server.go
68
server.go
@@ -51,7 +51,7 @@ type Server struct {
|
|||||||
Streams util.Collection[string, *Publisher]
|
Streams util.Collection[string, *Publisher]
|
||||||
Pulls util.Collection[string, *Puller]
|
Pulls util.Collection[string, *Puller]
|
||||||
Pushs util.Collection[string, *Pusher]
|
Pushs util.Collection[string, *Pusher]
|
||||||
Waiting map[string][]*Subscriber
|
Waiting util.Collection[string, *Publisher]
|
||||||
Subscribers util.Collection[int, *Subscriber]
|
Subscribers util.Collection[int, *Subscriber]
|
||||||
LogHandler MultiLogHandler
|
LogHandler MultiLogHandler
|
||||||
pidG int
|
pidG int
|
||||||
@@ -68,7 +68,6 @@ type Server struct {
|
|||||||
func NewServer() (s *Server) {
|
func NewServer() (s *Server) {
|
||||||
s = &Server{
|
s = &Server{
|
||||||
ID: int(serverIndexG.Add(1)),
|
ID: int(serverIndexG.Add(1)),
|
||||||
Waiting: make(map[string][]*Subscriber),
|
|
||||||
eventChan: make(chan any, 10),
|
eventChan: make(chan any, 10),
|
||||||
}
|
}
|
||||||
s.config.HTTP.ListenAddrTLS = ":8443"
|
s.config.HTTP.ListenAddrTLS = ":8443"
|
||||||
@@ -94,7 +93,6 @@ type rawconfig = map[string]map[string]any
|
|||||||
func (s *Server) reset() {
|
func (s *Server) reset() {
|
||||||
server := Server{
|
server := Server{
|
||||||
ID: s.ID,
|
ID: s.ID,
|
||||||
Waiting: make(map[string][]*Subscriber),
|
|
||||||
eventChan: make(chan any, 10),
|
eventChan: make(chan any, 10),
|
||||||
}
|
}
|
||||||
server.Logger = s.Logger
|
server.Logger = s.Logger
|
||||||
@@ -222,13 +220,13 @@ func (s *Server) run(ctx context.Context, conf any) (err error) {
|
|||||||
s.eventLoop()
|
s.eventLoop()
|
||||||
err = context.Cause(s)
|
err = context.Cause(s)
|
||||||
s.Warn("Server is done", "reason", err)
|
s.Warn("Server is done", "reason", err)
|
||||||
for _, publisher := range s.Streams.Items {
|
for publisher := range s.Streams.Range {
|
||||||
publisher.Stop(err)
|
publisher.Stop(err)
|
||||||
}
|
}
|
||||||
for _, subscriber := range s.Subscribers.Items {
|
for subscriber := range s.Subscribers.Range {
|
||||||
subscriber.Stop(err)
|
subscriber.Stop(err)
|
||||||
}
|
}
|
||||||
for _, p := range s.Plugins.Items {
|
for p := range s.Plugins.Range {
|
||||||
p.Stop(err)
|
p.Stop(err)
|
||||||
}
|
}
|
||||||
httpConf.StopListen()
|
httpConf.StopListen()
|
||||||
@@ -269,13 +267,21 @@ func (s *Server) eventLoop() {
|
|||||||
case <-s.Done():
|
case <-s.Done():
|
||||||
return
|
return
|
||||||
case <-pulse.C:
|
case <-pulse.C:
|
||||||
for _, publisher := range s.Streams.Items {
|
for publisher := range s.Streams.Range {
|
||||||
if err := publisher.checkTimeout(); err != nil {
|
if err := publisher.checkTimeout(); err != nil {
|
||||||
publisher.Stop(err)
|
publisher.Stop(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for subscriber := range s.Waiting {
|
for publisher := range s.Waiting.Range {
|
||||||
for _, sub := range s.Waiting[subscriber] {
|
if publisher.Plugin != nil {
|
||||||
|
if err := publisher.checkTimeout(); err != nil {
|
||||||
|
publisher.Dispose(err)
|
||||||
|
newPublisher := &Publisher{}
|
||||||
|
newPublisher.StreamPath = publisher.StreamPath
|
||||||
|
s.Waiting.Set(newPublisher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for sub := range publisher.SubscriberRange {
|
||||||
select {
|
select {
|
||||||
case <-sub.TimeoutTimer.C:
|
case <-sub.TimeoutTimer.C:
|
||||||
sub.Stop(ErrSubscribeTimeout)
|
sub.Stop(ErrSubscribeTimeout)
|
||||||
@@ -347,7 +353,7 @@ func (s *Server) eventLoop() {
|
|||||||
case slog.Handler:
|
case slog.Handler:
|
||||||
s.LogHandler.Add(v)
|
s.LogHandler.Add(v)
|
||||||
}
|
}
|
||||||
for _, plugin := range s.Plugins.Items {
|
for plugin := range s.Plugins.Range {
|
||||||
if plugin.Disabled {
|
if plugin.Disabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -363,7 +369,7 @@ func (s *Server) onUnsubscribe(subscriber *Subscriber) {
|
|||||||
if subscriber.Closer != nil {
|
if subscriber.Closer != nil {
|
||||||
subscriber.Close()
|
subscriber.Close()
|
||||||
}
|
}
|
||||||
for _, pusher := range s.Pushs.Items {
|
for pusher := range s.Pushs.Range {
|
||||||
if &pusher.Subscriber == subscriber {
|
if &pusher.Subscriber == subscriber {
|
||||||
s.Pushs.Remove(pusher)
|
s.Pushs.Remove(pusher)
|
||||||
break
|
break
|
||||||
@@ -372,25 +378,17 @@ func (s *Server) onUnsubscribe(subscriber *Subscriber) {
|
|||||||
if subscriber.Publisher != nil {
|
if subscriber.Publisher != nil {
|
||||||
subscriber.Publisher.RemoveSubscriber(subscriber)
|
subscriber.Publisher.RemoveSubscriber(subscriber)
|
||||||
}
|
}
|
||||||
if subscribers, ok := s.Waiting[subscriber.StreamPath]; ok {
|
|
||||||
if index := slices.Index(subscribers, subscriber); index >= 0 {
|
|
||||||
s.Waiting[subscriber.StreamPath] = slices.Delete(subscribers, index, index+1)
|
|
||||||
if len(subscribers) == 1 {
|
|
||||||
delete(s.Waiting, subscriber.StreamPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) onUnpublish(publisher *Publisher) {
|
func (s *Server) onUnpublish(publisher *Publisher) {
|
||||||
s.Streams.Remove(publisher)
|
s.Streams.Remove(publisher)
|
||||||
|
s.Waiting.Add(publisher)
|
||||||
s.Info("unpublish", "streamPath", publisher.StreamPath, "count", s.Streams.Length)
|
s.Info("unpublish", "streamPath", publisher.StreamPath, "count", s.Streams.Length)
|
||||||
for subscriber := range publisher.Subscribers {
|
for subscriber := range publisher.SubscriberRange {
|
||||||
s.Waiting[publisher.StreamPath] = append(s.Waiting[publisher.StreamPath], subscriber)
|
|
||||||
subscriber.TimeoutTimer.Reset(publisher.WaitCloseTimeout)
|
subscriber.TimeoutTimer.Reset(publisher.WaitCloseTimeout)
|
||||||
}
|
}
|
||||||
if publisher.Closer != nil {
|
if publisher.Closer != nil {
|
||||||
publisher.Close()
|
_ = publisher.Close()
|
||||||
}
|
}
|
||||||
s.Pulls.RemoveByKey(publisher.StreamPath)
|
s.Pulls.RemoveByKey(publisher.StreamPath)
|
||||||
}
|
}
|
||||||
@@ -401,12 +399,9 @@ func (s *Server) OnPublish(publisher *Publisher) error {
|
|||||||
publisher.Warn("kick")
|
publisher.Warn("kick")
|
||||||
oldPublisher.Stop(ErrKick)
|
oldPublisher.Stop(ErrKick)
|
||||||
publisher.TakeOver(oldPublisher)
|
publisher.TakeOver(oldPublisher)
|
||||||
oldPublisher.Subscribers = nil
|
|
||||||
} else {
|
} else {
|
||||||
return ErrStreamExist
|
return ErrStreamExist
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
publisher.Subscribers = make(map[*Subscriber]struct{})
|
|
||||||
}
|
}
|
||||||
s.Streams.Set(publisher)
|
s.Streams.Set(publisher)
|
||||||
s.pidG++
|
s.pidG++
|
||||||
@@ -415,14 +410,15 @@ func (s *Server) OnPublish(publisher *Publisher) error {
|
|||||||
publisher.Logger = p.With("streamPath", publisher.StreamPath, "puber", publisher.ID)
|
publisher.Logger = p.With("streamPath", publisher.StreamPath, "puber", publisher.ID)
|
||||||
publisher.TimeoutTimer = time.NewTimer(p.config.PublishTimeout)
|
publisher.TimeoutTimer = time.NewTimer(p.config.PublishTimeout)
|
||||||
publisher.Info("publish")
|
publisher.Info("publish")
|
||||||
if subscribers, ok := s.Waiting[publisher.StreamPath]; ok {
|
if waiting, ok := s.Waiting.Get(publisher.StreamPath); ok {
|
||||||
for i, subscriber := range subscribers {
|
if waiting.Plugin != nil {
|
||||||
if i == 0 && subscriber.Publisher != nil {
|
publisher.TakeOver(waiting)
|
||||||
publisher.TakeOver(subscriber.Publisher)
|
} else {
|
||||||
}
|
for subscriber := range waiting.SubscriberRange {
|
||||||
publisher.AddSubscriber(subscriber)
|
publisher.AddSubscriber(subscriber)
|
||||||
}
|
}
|
||||||
delete(s.Waiting, publisher.StreamPath)
|
}
|
||||||
|
s.Waiting.Remove(waiting)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -435,9 +431,13 @@ func (s *Server) OnSubscribe(subscriber *Subscriber) error {
|
|||||||
s.Subscribers.Add(subscriber)
|
s.Subscribers.Add(subscriber)
|
||||||
subscriber.Info("subscribe")
|
subscriber.Info("subscribe")
|
||||||
if publisher, ok := s.Streams.Get(subscriber.StreamPath); ok {
|
if publisher, ok := s.Streams.Get(subscriber.StreamPath); ok {
|
||||||
return publisher.AddSubscriber(subscriber)
|
publisher.AddSubscriber(subscriber)
|
||||||
|
} else if publisher, ok = s.Waiting.Get(subscriber.StreamPath); ok {
|
||||||
|
publisher.AddSubscriber(subscriber)
|
||||||
} else {
|
} else {
|
||||||
s.Waiting[subscriber.StreamPath] = append(s.Waiting[subscriber.StreamPath], subscriber)
|
newPublisher := &Publisher{}
|
||||||
|
newPublisher.StreamPath = subscriber.StreamPath
|
||||||
|
newPublisher.AddSubscriber(subscriber)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -448,7 +448,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "visit:%s\nMonibuca Engine %s StartTime:%s\n", r.URL.Path, Version, s.StartTime)
|
fmt.Fprintf(w, "visit:%s\nMonibuca Engine %s StartTime:%s\n", r.URL.Path, Version, s.StartTime)
|
||||||
for _, plugin := range s.Plugins.Items {
|
for plugin := range s.Plugins.Range {
|
||||||
fmt.Fprintf(w, "Plugin %s Version:%s\n", plugin.Meta.Name, plugin.Meta.Version)
|
fmt.Fprintf(w, "Plugin %s Version:%s\n", plugin.Meta.Name, plugin.Meta.Version)
|
||||||
}
|
}
|
||||||
for _, api := range s.apiList {
|
for _, api := range s.apiList {
|
||||||
|
@@ -2,6 +2,7 @@ package m7s
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -70,11 +71,6 @@ type Subscriber struct {
|
|||||||
VideoReader *AVRingReader
|
VideoReader *AVRingReader
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscriberHandler struct {
|
|
||||||
OnAudio any
|
|
||||||
OnVideo any
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Subscriber) OnVideoFrame(yield func(*AVFrame) bool) {
|
func (s *Subscriber) OnVideoFrame(yield func(*AVFrame) bool) {
|
||||||
if !s.SubVideo || s.Publisher == nil {
|
if !s.SubVideo || s.Publisher == nil {
|
||||||
return
|
return
|
||||||
@@ -169,24 +165,24 @@ func HandleVideo[T IAVFrame](s *Subscriber) func(func(T) bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Subscriber) Handle(handler SubscriberHandler) {
|
func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(V) error) {
|
||||||
var ar, vr *AVRingReader
|
var ar, vr *AVRingReader
|
||||||
var ah, vh reflect.Value
|
|
||||||
var a1, v1 reflect.Type
|
var a1, v1 reflect.Type
|
||||||
var at, vt *AVTrack
|
var at, vt *AVTrack
|
||||||
var awi, vwi int
|
var awi, vwi int
|
||||||
|
var startAudioTs, startVideoTs time.Duration
|
||||||
var initState = 0
|
var initState = 0
|
||||||
|
var prePublisher *Publisher
|
||||||
var subMode = s.SubMode //订阅模式
|
var subMode = s.SubMode //订阅模式
|
||||||
if s.Args.Has(s.SubModeArgName) {
|
if s.Args.Has(s.SubModeArgName) {
|
||||||
subMode, _ = strconv.Atoi(s.Args.Get(s.SubModeArgName))
|
subMode, _ = strconv.Atoi(s.Args.Get(s.SubModeArgName))
|
||||||
}
|
}
|
||||||
var audioFrame, videoFrame *AVFrame
|
var audioFrame, videoFrame *AVFrame
|
||||||
if handler.OnAudio != nil && s.SubAudio {
|
if s.SubAudio {
|
||||||
|
a1 = reflect.TypeOf(onAudio).In(0)
|
||||||
a1 = reflect.TypeOf(handler.OnAudio).In(0)
|
|
||||||
}
|
}
|
||||||
if handler.OnVideo != nil && s.SubVideo {
|
if s.SubVideo {
|
||||||
v1 = reflect.TypeOf(handler.OnVideo).In(0)
|
v1 = reflect.TypeOf(onVideo).In(0)
|
||||||
}
|
}
|
||||||
createAudioReader := func() {
|
createAudioReader := func() {
|
||||||
if s.Publisher == nil || a1 == nil {
|
if s.Publisher == nil || a1 == nil {
|
||||||
@@ -204,9 +200,9 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
if at != nil {
|
if at != nil {
|
||||||
ar = NewAVRingReader(at)
|
ar = NewAVRingReader(at)
|
||||||
s.AudioReader = ar
|
s.AudioReader = ar
|
||||||
|
ar.StartTs = startAudioTs
|
||||||
ar.Logger = s.Logger.With("reader", a1.String())
|
ar.Logger = s.Logger.With("reader", a1.String())
|
||||||
ar.Info("start read")
|
ar.Info("start read")
|
||||||
ah = reflect.ValueOf(handler.OnAudio)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createVideoReader := func() {
|
createVideoReader := func() {
|
||||||
@@ -224,14 +220,15 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
}
|
}
|
||||||
if vt != nil {
|
if vt != nil {
|
||||||
vr = NewAVRingReader(vt)
|
vr = NewAVRingReader(vt)
|
||||||
|
vr.StartTs = startVideoTs
|
||||||
s.VideoReader = vr
|
s.VideoReader = vr
|
||||||
vr.Logger = s.Logger.With("reader", v1.String())
|
vr.Logger = s.Logger.With("reader", v1.String())
|
||||||
vr.Info("start read")
|
vr.Info("start read")
|
||||||
vh = reflect.ValueOf(handler.OnVideo)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createAudioReader()
|
createAudioReader()
|
||||||
createVideoReader()
|
createVideoReader()
|
||||||
|
prePublisher = s.Publisher
|
||||||
defer func() {
|
defer func() {
|
||||||
if ar != nil {
|
if ar != nil {
|
||||||
ar.StopRead()
|
ar.StopRead()
|
||||||
@@ -240,22 +237,18 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
vr.StopRead()
|
vr.StopRead()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
inputs := make([]reflect.Value, 1)
|
|
||||||
sendAudioFrame := func() (err error) {
|
sendAudioFrame := func() (err error) {
|
||||||
if awi >= 0 {
|
if awi >= 0 {
|
||||||
if s.Enabled(s, TraceLevel) {
|
if s.Enabled(s, TraceLevel) {
|
||||||
s.Trace("send audio frame", "seq", audioFrame.Sequence)
|
s.Trace("send audio frame", "seq", audioFrame.Sequence)
|
||||||
}
|
}
|
||||||
inputs[0] = reflect.ValueOf(audioFrame.Wraps[awi])
|
err = onAudio(audioFrame.Wraps[awi].(A))
|
||||||
} else {
|
} else {
|
||||||
inputs[0] = reflect.ValueOf(audioFrame)
|
err = onAudio(any(audioFrame).(A))
|
||||||
}
|
}
|
||||||
res := ah.Call(inputs)
|
if err != nil && !errors.Is(err, ErrInterrupt) {
|
||||||
if len(res) > 0 && !res[0].IsNil() {
|
|
||||||
if err := res[0].Interface().(error); err != ErrInterrupt {
|
|
||||||
s.Stop(err)
|
s.Stop(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
audioFrame = nil
|
audioFrame = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -264,19 +257,31 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
if s.Enabled(s, TraceLevel) {
|
if s.Enabled(s, TraceLevel) {
|
||||||
s.Trace("send video frame", "seq", videoFrame.Sequence, "data", videoFrame.Wraps[vwi].String(), "size", videoFrame.Wraps[vwi].GetSize())
|
s.Trace("send video frame", "seq", videoFrame.Sequence, "data", videoFrame.Wraps[vwi].String(), "size", videoFrame.Wraps[vwi].GetSize())
|
||||||
}
|
}
|
||||||
inputs[0] = reflect.ValueOf(videoFrame.Wraps[vwi])
|
err = onVideo(videoFrame.Wraps[vwi].(V))
|
||||||
} else {
|
} else {
|
||||||
inputs[0] = reflect.ValueOf(videoFrame)
|
err = onVideo(any(videoFrame).(V))
|
||||||
}
|
}
|
||||||
res := vh.Call(inputs)
|
if err != nil && !errors.Is(err, ErrInterrupt) {
|
||||||
if len(res) > 0 && !res[0].IsNil() {
|
|
||||||
if err = res[0].Interface().(error); err != ErrInterrupt {
|
|
||||||
s.Stop(err)
|
s.Stop(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
videoFrame = nil
|
videoFrame = nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
checkPublisherChange := func() {
|
||||||
|
if prePublisher != s.Publisher {
|
||||||
|
if ar != nil {
|
||||||
|
startAudioTs = time.Duration(ar.AbsTime) * time.Millisecond
|
||||||
|
ar.StopRead()
|
||||||
|
}
|
||||||
|
if vr != nil {
|
||||||
|
startVideoTs = time.Duration(vr.AbsTime) * time.Millisecond
|
||||||
|
vr.StopRead()
|
||||||
|
}
|
||||||
|
createAudioReader()
|
||||||
|
createVideoReader()
|
||||||
|
prePublisher = s.Publisher
|
||||||
|
}
|
||||||
|
}
|
||||||
var err error
|
var err error
|
||||||
for err == nil {
|
for err == nil {
|
||||||
err = s.Err()
|
err = s.Err()
|
||||||
@@ -297,7 +302,7 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
vr.LastCodecCtx = vr.Track.ICodecCtx
|
vr.LastCodecCtx = vr.Track.ICodecCtx
|
||||||
if seqFrame := vr.Track.SequenceFrame; seqFrame != nil {
|
if seqFrame := vr.Track.SequenceFrame; seqFrame != nil {
|
||||||
s.Debug("video codec changed", "data", seqFrame.String())
|
s.Debug("video codec changed", "data", seqFrame.String())
|
||||||
vh.Call([]reflect.Value{reflect.ValueOf(seqFrame)})
|
err = onVideo(seqFrame.(V))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ar != nil {
|
if ar != nil {
|
||||||
@@ -315,6 +320,9 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
if !s.IFrameOnly || videoFrame.IDR {
|
if !s.IFrameOnly || videoFrame.IDR {
|
||||||
err = sendVideoFrame()
|
err = sendVideoFrame()
|
||||||
}
|
}
|
||||||
|
if ar == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
createVideoReader()
|
createVideoReader()
|
||||||
@@ -347,7 +355,7 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
if ar.DecConfChanged() {
|
if ar.DecConfChanged() {
|
||||||
ar.LastCodecCtx = ar.Track.ICodecCtx
|
ar.LastCodecCtx = ar.Track.ICodecCtx
|
||||||
if seqFrame := ar.Track.SequenceFrame; seqFrame != nil {
|
if seqFrame := ar.Track.SequenceFrame; seqFrame != nil {
|
||||||
ah.Call([]reflect.Value{reflect.ValueOf(seqFrame)})
|
err = onAudio(seqFrame.(A))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if vr != nil && videoFrame != nil {
|
if vr != nil && videoFrame != nil {
|
||||||
@@ -365,5 +373,6 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
|
|||||||
} else {
|
} else {
|
||||||
createAudioReader()
|
createAudioReader()
|
||||||
}
|
}
|
||||||
|
checkPublisherChange()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user