Feat: use protobuf

pull/21/head
zijiren233 2 years ago
parent a3ef679f18
commit 813d5c348d

@ -8,6 +8,7 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/go-resty/resty/v2 v2.9.1
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/golang/protobuf v1.5.3
github.com/google/uuid v1.3.1
github.com/gorilla/websocket v1.5.0
github.com/json-iterator/go v1.1.12
@ -20,11 +21,11 @@ require (
github.com/spf13/cobra v1.7.0
github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc
github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb
github.com/zijiren233/ksync v0.2.0
github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26
github.com/zijiren233/stream v0.5.1
github.com/zijiren233/yaml-comment v0.2.0
golang.org/x/crypto v0.14.0
google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v3 v3.0.1
)
@ -62,6 +63,5 @@ require (
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
)

@ -2,8 +2,6 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc=
github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
github.com/caarlos0/env/v9 v9.0.0 h1:SI6JNsOA+y5gj9njpgybykATIylrRMklbs5ch6wO6pc=
@ -38,12 +36,8 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs=
github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24=
github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8=
github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w=
github.com/go-resty/resty/v2 v2.9.1 h1:PIgGx4VrHvag0juCJ4dDv3MiFRlDmP0vicBucwf+gLM=
github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9gV/VGZIy4=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@ -55,6 +49,7 @@ github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJ
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -97,8 +92,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA=
github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
@ -145,24 +138,10 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zijiren233/gencontainer v0.0.0-20230930061950-82324a07eacb h1:sOVY4BfQo/uzoACkFTvfCJd0mHhhPQjcwgKTICOW+Js=
github.com/zijiren233/gencontainer v0.0.0-20230930061950-82324a07eacb/go.mod h1:V5oL7PrZxgisuLCblFWd89Jg99O8vM1n58llcxZ2hDY=
github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc h1:qEYdClJZG4GHT7pG+scIkN36u5/n1uj5bAPt8UeLkO4=
github.com/zijiren233/gencontainer v0.0.0-20230930135658-e410015e13cc/go.mod h1:V5oL7PrZxgisuLCblFWd89Jg99O8vM1n58llcxZ2hDY=
github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb h1:0DyOxf/TbbGodHhOVHNoPk+7v/YBJACs22gKpKlatWw=
github.com/zijiren233/go-colorable v0.0.0-20230930131441-997304c961cb/go.mod h1:6TCzjDiQ8+5gWZiwsC3pnA5M0vUy2jV2Y7ciHJh729g=
github.com/zijiren233/ksync v0.2.0 h1:OyXVXbVQYFEVfWM13NApt4LMHbLQ3HTs4oYcLmqL6NE=
github.com/zijiren233/ksync v0.2.0/go.mod h1:YNvvoErcbtF86Xn18J8QJ14jKOXinxFVOzyp4hn8FKw=
github.com/zijiren233/livelib v0.0.0-20230930062256-1d07bbddcefb h1:t6zLooW4uVz2gKWmbZN4ljXKJpbiLnQF9j1kTMfV8OM=
github.com/zijiren233/livelib v0.0.0-20230930062256-1d07bbddcefb/go.mod h1:C4OwAodQXpMLYiioqH4ANjZJD4+sFRK0nPbXNoYZU5k=
github.com/zijiren233/livelib v0.0.0-20231005100909-7893feb306a9 h1:GRhW0AmqeUN0CbAzJQhQXQ5sz139/lMn6yuD+ZBVn/s=
github.com/zijiren233/livelib v0.0.0-20231005100909-7893feb306a9/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo=
github.com/zijiren233/livelib v0.1.0 h1:QdNj39eaIB/g7bBhDFbwrDuGkoghHWEwZXgBVwQ5QtY=
github.com/zijiren233/livelib v0.1.0/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo=
github.com/zijiren233/livelib v0.1.1 h1:PjGqQXgJw2sqWWBp5JEtwqnpNplWqX5BY3yo+5U9vOo=
github.com/zijiren233/livelib v0.1.1/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo=
github.com/zijiren233/livelib v0.1.2-0.20231010021513-5130877d6f5e h1:x1KhyR/CIaZ2Yfb1mGwX0nUhRVOJnFPUFNN+AVqv7VA=
github.com/zijiren233/livelib v0.1.2-0.20231010021513-5130877d6f5e/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo=
github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26 h1:h7cw3cPQX3VheviU0y0bUVV0CnQ8fJegJgZMBpb/tfw=
github.com/zijiren233/livelib v0.1.2-0.20231010145337-1651f7b4be26/go.mod h1:2wrAAqNIdMZjQrdbO7ERQfqK4VS5fzgUj2xXwrJ8/uo=
github.com/zijiren233/stream v0.5.1 h1:9SUwM/fpET6frtBRT5WZBHnan0Hyzkezk/P8N78cgZQ=
@ -178,18 +157,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -199,7 +173,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
@ -219,7 +192,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -236,18 +208,18 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M=
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

@ -0,0 +1,2 @@
#!/bin/bash
protoc --go_out=./proto ./proto/*.proto

@ -0,0 +1,632 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v4.24.4
// source: proto/message.proto
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ElementMessageType int32
const (
ElementMessageType_UNKNOWN ElementMessageType = 0
ElementMessageType_ERROR ElementMessageType = 1
ElementMessageType_CHAT_MESSAGE ElementMessageType = 2
ElementMessageType_PLAY ElementMessageType = 3
ElementMessageType_PAUSE ElementMessageType = 4
ElementMessageType_CHECK_SEEK ElementMessageType = 5
ElementMessageType_TOO_FAST ElementMessageType = 6
ElementMessageType_TOO_SLOW ElementMessageType = 7
ElementMessageType_CHANGE_RATE ElementMessageType = 8
ElementMessageType_CHANGE_SEEK ElementMessageType = 9
ElementMessageType_CHANGE_CURRENT ElementMessageType = 10
ElementMessageType_CHANGE_MOVIES ElementMessageType = 11
ElementMessageType_CHANGE_PEOPLE ElementMessageType = 12
)
// Enum value maps for ElementMessageType.
var (
ElementMessageType_name = map[int32]string{
0: "UNKNOWN",
1: "ERROR",
2: "CHAT_MESSAGE",
3: "PLAY",
4: "PAUSE",
5: "CHECK_SEEK",
6: "TOO_FAST",
7: "TOO_SLOW",
8: "CHANGE_RATE",
9: "CHANGE_SEEK",
10: "CHANGE_CURRENT",
11: "CHANGE_MOVIES",
12: "CHANGE_PEOPLE",
}
ElementMessageType_value = map[string]int32{
"UNKNOWN": 0,
"ERROR": 1,
"CHAT_MESSAGE": 2,
"PLAY": 3,
"PAUSE": 4,
"CHECK_SEEK": 5,
"TOO_FAST": 6,
"TOO_SLOW": 7,
"CHANGE_RATE": 8,
"CHANGE_SEEK": 9,
"CHANGE_CURRENT": 10,
"CHANGE_MOVIES": 11,
"CHANGE_PEOPLE": 12,
}
)
func (x ElementMessageType) Enum() *ElementMessageType {
p := new(ElementMessageType)
*p = x
return p
}
func (x ElementMessageType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ElementMessageType) Descriptor() protoreflect.EnumDescriptor {
return file_proto_message_proto_enumTypes[0].Descriptor()
}
func (ElementMessageType) Type() protoreflect.EnumType {
return &file_proto_message_proto_enumTypes[0]
}
func (x ElementMessageType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ElementMessageType.Descriptor instead.
func (ElementMessageType) EnumDescriptor() ([]byte, []int) {
return file_proto_message_proto_rawDescGZIP(), []int{0}
}
type MovieInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
Live bool `protobuf:"varint,4,opt,name=live,proto3" json:"live,omitempty"`
Proxy bool `protobuf:"varint,5,opt,name=proxy,proto3" json:"proxy,omitempty"`
RtmpSource bool `protobuf:"varint,6,opt,name=rtmp_source,json=rtmpSource,proto3" json:"rtmp_source,omitempty"`
Type string `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
Headers map[string]string `protobuf:"bytes,8,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
PullKey string `protobuf:"bytes,9,opt,name=pull_key,json=pullKey,proto3" json:"pull_key,omitempty"`
CreatedAt int64 `protobuf:"varint,10,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
Creator string `protobuf:"bytes,11,opt,name=creator,proto3" json:"creator,omitempty"`
}
func (x *MovieInfo) Reset() {
*x = MovieInfo{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MovieInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MovieInfo) ProtoMessage() {}
func (x *MovieInfo) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_proto_msgTypes[0]
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 MovieInfo.ProtoReflect.Descriptor instead.
func (*MovieInfo) Descriptor() ([]byte, []int) {
return file_proto_message_proto_rawDescGZIP(), []int{0}
}
func (x *MovieInfo) GetId() uint64 {
if x != nil {
return x.Id
}
return 0
}
func (x *MovieInfo) GetUrl() string {
if x != nil {
return x.Url
}
return ""
}
func (x *MovieInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *MovieInfo) GetLive() bool {
if x != nil {
return x.Live
}
return false
}
func (x *MovieInfo) GetProxy() bool {
if x != nil {
return x.Proxy
}
return false
}
func (x *MovieInfo) GetRtmpSource() bool {
if x != nil {
return x.RtmpSource
}
return false
}
func (x *MovieInfo) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *MovieInfo) GetHeaders() map[string]string {
if x != nil {
return x.Headers
}
return nil
}
func (x *MovieInfo) GetPullKey() string {
if x != nil {
return x.PullKey
}
return ""
}
func (x *MovieInfo) GetCreatedAt() int64 {
if x != nil {
return x.CreatedAt
}
return 0
}
func (x *MovieInfo) GetCreator() string {
if x != nil {
return x.Creator
}
return ""
}
type Status struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Seek float64 `protobuf:"fixed64,1,opt,name=seek,proto3" json:"seek,omitempty"`
Rate float64 `protobuf:"fixed64,2,opt,name=rate,proto3" json:"rate,omitempty"`
Playing bool `protobuf:"varint,3,opt,name=playing,proto3" json:"playing,omitempty"`
}
func (x *Status) Reset() {
*x = Status{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Status) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Status) ProtoMessage() {}
func (x *Status) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_proto_msgTypes[1]
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 Status.ProtoReflect.Descriptor instead.
func (*Status) Descriptor() ([]byte, []int) {
return file_proto_message_proto_rawDescGZIP(), []int{1}
}
func (x *Status) GetSeek() float64 {
if x != nil {
return x.Seek
}
return 0
}
func (x *Status) GetRate() float64 {
if x != nil {
return x.Rate
}
return 0
}
func (x *Status) GetPlaying() bool {
if x != nil {
return x.Playing
}
return false
}
type Current struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Movie *MovieInfo `protobuf:"bytes,1,opt,name=movie,proto3" json:"movie,omitempty"`
Status *Status `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
}
func (x *Current) Reset() {
*x = Current{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Current) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Current) ProtoMessage() {}
func (x *Current) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_proto_msgTypes[2]
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 Current.ProtoReflect.Descriptor instead.
func (*Current) Descriptor() ([]byte, []int) {
return file_proto_message_proto_rawDescGZIP(), []int{2}
}
func (x *Current) GetMovie() *MovieInfo {
if x != nil {
return x.Movie
}
return nil
}
func (x *Current) GetStatus() *Status {
if x != nil {
return x.Status
}
return nil
}
type ElementMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type ElementMessageType `protobuf:"varint,1,opt,name=type,proto3,enum=proto.ElementMessageType" json:"type,omitempty"`
Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"`
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
Rate float64 `protobuf:"fixed64,4,opt,name=rate,proto3" json:"rate,omitempty"`
Seek float64 `protobuf:"fixed64,5,opt,name=seek,proto3" json:"seek,omitempty"`
Current *Current `protobuf:"bytes,6,opt,name=current,proto3,oneof" json:"current,omitempty"`
PeopleNum int64 `protobuf:"varint,7,opt,name=people_num,json=peopleNum,proto3" json:"people_num,omitempty"`
Time int64 `protobuf:"varint,8,opt,name=time,proto3" json:"time,omitempty"`
}
func (x *ElementMessage) Reset() {
*x = ElementMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_message_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ElementMessage) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ElementMessage) ProtoMessage() {}
func (x *ElementMessage) ProtoReflect() protoreflect.Message {
mi := &file_proto_message_proto_msgTypes[3]
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 ElementMessage.ProtoReflect.Descriptor instead.
func (*ElementMessage) Descriptor() ([]byte, []int) {
return file_proto_message_proto_rawDescGZIP(), []int{3}
}
func (x *ElementMessage) GetType() ElementMessageType {
if x != nil {
return x.Type
}
return ElementMessageType_UNKNOWN
}
func (x *ElementMessage) GetSender() string {
if x != nil {
return x.Sender
}
return ""
}
func (x *ElementMessage) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
func (x *ElementMessage) GetRate() float64 {
if x != nil {
return x.Rate
}
return 0
}
func (x *ElementMessage) GetSeek() float64 {
if x != nil {
return x.Seek
}
return 0
}
func (x *ElementMessage) GetCurrent() *Current {
if x != nil {
return x.Current
}
return nil
}
func (x *ElementMessage) GetPeopleNum() int64 {
if x != nil {
return x.PeopleNum
}
return 0
}
func (x *ElementMessage) GetTime() int64 {
if x != nil {
return x.Time
}
return 0
}
var File_proto_message_proto protoreflect.FileDescriptor
var file_proto_message_proto_rawDesc = []byte{
0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe9, 0x02, 0x0a,
0x09, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04,
0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x18, 0x05, 0x20,
0x01, 0x28, 0x08, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x74,
0x6d, 0x70, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0a, 0x72, 0x74, 0x6d, 0x70, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74,
0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
0x37, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e,
0x66, 0x6f, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x70, 0x75, 0x6c, 0x6c,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x75, 0x6c, 0x6c,
0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0b, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x3a, 0x0a, 0x0c,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01,
0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c,
0x61, 0x79, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x6c, 0x61,
0x79, 0x69, 0x6e, 0x67, 0x22, 0x58, 0x0a, 0x07, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12,
0x26, 0x0a, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x05, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x87,
0x02, 0x0a, 0x0e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01,
0x52, 0x04, 0x72, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x18, 0x05,
0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x73, 0x65, 0x65, 0x6b, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x65, 0x6f,
0x70, 0x6c, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70,
0x65, 0x6f, 0x70, 0x6c, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65,
0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08,
0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2a, 0xdb, 0x01, 0x0a, 0x12, 0x45, 0x6c, 0x65,
0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12,
0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05,
0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x54, 0x5f,
0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4c, 0x41,
0x59, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x41, 0x55, 0x53, 0x45, 0x10, 0x04, 0x12, 0x0e,
0x0a, 0x0a, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x05, 0x12, 0x0c,
0x0a, 0x08, 0x54, 0x4f, 0x4f, 0x5f, 0x46, 0x41, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08,
0x54, 0x4f, 0x4f, 0x5f, 0x53, 0x4c, 0x4f, 0x57, 0x10, 0x07, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x48,
0x41, 0x4e, 0x47, 0x45, 0x5f, 0x52, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x43,
0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x45, 0x45, 0x4b, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e,
0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x0a,
0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4d, 0x4f, 0x56, 0x49, 0x45,
0x53, 0x10, 0x0b, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x50, 0x45,
0x4f, 0x50, 0x4c, 0x45, 0x10, 0x0c, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x3b, 0x70, 0x62, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_message_proto_rawDescOnce sync.Once
file_proto_message_proto_rawDescData = file_proto_message_proto_rawDesc
)
func file_proto_message_proto_rawDescGZIP() []byte {
file_proto_message_proto_rawDescOnce.Do(func() {
file_proto_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_message_proto_rawDescData)
})
return file_proto_message_proto_rawDescData
}
var file_proto_message_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_message_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_proto_message_proto_goTypes = []interface{}{
(ElementMessageType)(0), // 0: proto.ElementMessageType
(*MovieInfo)(nil), // 1: proto.MovieInfo
(*Status)(nil), // 2: proto.Status
(*Current)(nil), // 3: proto.Current
(*ElementMessage)(nil), // 4: proto.ElementMessage
nil, // 5: proto.MovieInfo.HeadersEntry
}
var file_proto_message_proto_depIdxs = []int32{
5, // 0: proto.MovieInfo.headers:type_name -> proto.MovieInfo.HeadersEntry
1, // 1: proto.Current.movie:type_name -> proto.MovieInfo
2, // 2: proto.Current.status:type_name -> proto.Status
0, // 3: proto.ElementMessage.type:type_name -> proto.ElementMessageType
3, // 4: proto.ElementMessage.current:type_name -> proto.Current
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_proto_message_proto_init() }
func file_proto_message_proto_init() {
if File_proto_message_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MovieInfo); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Status); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Current); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_message_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ElementMessage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_proto_message_proto_msgTypes[3].OneofWrappers = []interface{}{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_message_proto_rawDesc,
NumEnums: 1,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_message_proto_goTypes,
DependencyIndexes: file_proto_message_proto_depIdxs,
EnumInfos: file_proto_message_proto_enumTypes,
MessageInfos: file_proto_message_proto_msgTypes,
}.Build()
File_proto_message_proto = out.File
file_proto_message_proto_rawDesc = nil
file_proto_message_proto_goTypes = nil
file_proto_message_proto_depIdxs = nil
}

@ -0,0 +1,56 @@
syntax = "proto3";
option go_package = ".;pb";
package proto;
enum ElementMessageType {
UNKNOWN = 0;
ERROR = 1;
CHAT_MESSAGE = 2;
PLAY = 3;
PAUSE = 4;
CHECK_SEEK = 5;
TOO_FAST = 6;
TOO_SLOW = 7;
CHANGE_RATE = 8;
CHANGE_SEEK = 9;
CHANGE_CURRENT = 10;
CHANGE_MOVIES = 11;
CHANGE_PEOPLE = 12;
}
message MovieInfo {
uint64 id = 1;
string url = 2;
string name = 3;
bool live = 4;
bool proxy = 5;
bool rtmp_source = 6;
string type = 7;
map<string, string> headers = 8;
string pull_key = 9;
int64 created_at = 10;
string creator = 11;
}
message Status {
double seek = 1;
double rate = 2;
bool playing = 3;
}
message Current {
MovieInfo movie = 1;
Status status = 2;
}
message ElementMessage {
ElementMessageType type = 1;
string sender = 2;
string message = 3;
double rate = 4;
double seek = 5;
optional Current current = 6;
int64 people_num = 7;
int64 time = 8;
}

@ -46,8 +46,8 @@ func (c *Client) Room() *Room {
return c.user.room
}
func (c *Client) Broadcast(msg Message, conf ...BroadcastConf) {
c.user.Broadcast(msg, conf...)
func (c *Client) Broadcast(msg Message, conf ...BroadcastConf) error {
return c.user.Broadcast(msg, conf...)
}
func (c *Client) Send(msg Message) error {

@ -4,136 +4,165 @@ import (
"sync"
"time"
json "github.com/json-iterator/go"
pb "github.com/synctv-org/synctv/proto"
)
type current struct {
current Current
lock sync.RWMutex
}
type Current struct {
movie MovieInfo
status Status
lock sync.RWMutex
Movie MovieInfo `json:"movie"`
Status Status `json:"status"`
}
func newCurrent() *Current {
return &Current{
movie: MovieInfo{},
status: newStatus(),
func newCurrent() *current {
return &current{
current: Current{
Status: newStatus(),
},
}
}
type Status struct {
Seek float64 `json:"seek"`
Rate float64 `json:"rate"`
Playing bool `json:"playing"`
lastUpdateTime time.Time
Seek float64 `json:"seek"`
Rate float64 `json:"rate"`
Playing bool `json:"playing"`
lastUpdate time.Time
}
func newStatus() Status {
return Status{
Seek: 0,
Rate: 1.0,
lastUpdateTime: time.Now(),
Seek: 0,
Rate: 1.0,
lastUpdate: time.Now(),
}
}
func (c *Current) MarshalJSON() ([]byte, error) {
func (c *current) Current() Current {
c.lock.RLock()
defer c.lock.RUnlock()
c.updateSeek()
return json.Marshal(map[string]interface{}{
"movie": c.movie,
"status": c.status,
})
c.current.updateSeek()
return c.current
}
func (c *Current) Movie() MovieInfo {
func (c *current) Movie() MovieInfo {
c.lock.RLock()
defer c.lock.RUnlock()
return c.movie
return c.current.Movie
}
func (c *Current) SetMovie(movie MovieInfo) {
func (c *current) SetMovie(movie MovieInfo) {
c.lock.Lock()
defer c.lock.Unlock()
c.movie = movie
c.setSeek(0, 0)
c.current.Movie = movie
c.current.SetSeek(0, 0)
}
func (c *Current) Status() Status {
func (c *current) Status() Status {
c.lock.RLock()
defer c.lock.RUnlock()
c.updateSeek()
return c.status
c.current.updateSeek()
return c.current.Status
}
func (c *current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
return c.current.SetStatus(playing, seek, rate, timeDiff)
}
func (c *current) SetSeekRate(seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
return c.current.SetSeekRate(seek, rate, timeDiff)
}
func (c *Current) Proto() *pb.Current {
return &pb.Current{
Movie: &pb.MovieInfo{
Id: c.Movie.Id,
Url: c.Movie.Url,
Name: c.Movie.Name,
Live: c.Movie.Live,
Proxy: c.Movie.Proxy,
RtmpSource: c.Movie.RtmpSource,
Type: c.Movie.Type,
Headers: c.Movie.Headers,
PullKey: c.Movie.PullKey,
CreatedAt: c.Movie.CreatedAt,
Creator: c.Movie.Creator,
},
Status: &pb.Status{
Seek: c.Status.Seek,
Rate: c.Status.Rate,
Playing: c.Status.Playing,
},
}
}
func (c *Current) updateSeek() {
if c.movie.Live {
c.status.lastUpdateTime = time.Now()
if c.Movie.Live {
c.Status.lastUpdate = time.Now()
return
}
if c.status.Playing {
c.status.Seek += time.Since(c.status.lastUpdateTime).Seconds() * c.status.Rate
if c.Status.Playing {
c.Status.Seek += time.Since(c.Status.lastUpdate).Seconds() * c.Status.Rate
}
c.status.lastUpdateTime = time.Now()
c.Status.lastUpdate = time.Now()
}
func (c *Current) setLiveStatus() Status {
c.status.Playing = true
c.status.Rate = 1.0
c.status.Seek = 0
c.status.lastUpdateTime = time.Now()
return c.status
c.Status.Playing = true
c.Status.Rate = 1.0
c.Status.Seek = 0
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetStatus(playing bool, seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
if c.movie.Live {
if c.Movie.Live {
return c.setLiveStatus()
}
c.status.Playing = playing
c.status.Rate = rate
c.Status.Playing = playing
c.Status.Rate = rate
if playing {
c.status.Seek = seek + (timeDiff * rate)
c.Status.Seek = seek + (timeDiff * rate)
} else {
c.status.Seek = seek
c.Status.Seek = seek
}
c.status.lastUpdateTime = time.Now()
return c.status
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetSeekRate(seek, rate, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
if c.movie.Live {
if c.Movie.Live {
return c.setLiveStatus()
}
if c.status.Playing {
c.status.Seek = seek + (timeDiff * rate)
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * rate)
} else {
c.status.Seek = seek
c.Status.Seek = seek
}
c.status.Rate = rate
c.status.lastUpdateTime = time.Now()
return c.status
c.Status.Rate = rate
c.Status.lastUpdate = time.Now()
return c.Status
}
func (c *Current) SetSeek(seek, timeDiff float64) Status {
c.lock.Lock()
defer c.lock.Unlock()
return c.setSeek(seek, timeDiff)
}
func (c *Current) setSeek(seek, timeDiff float64) Status {
if c.movie.Live {
if c.Movie.Live {
return c.setLiveStatus()
}
if c.status.Playing {
c.status.Seek = seek + (timeDiff * c.status.Rate)
if c.Status.Playing {
c.Status.Seek = seek + (timeDiff * c.Status.Rate)
} else {
c.status.Seek = seek
c.Status.Seek = seek
}
c.status.lastUpdateTime = time.Now()
return c.status
c.Status.lastUpdate = time.Now()
return c.Status
}

@ -1,12 +1,11 @@
package room
import (
"encoding/json"
"fmt"
"io"
"github.com/gorilla/websocket"
"gopkg.in/yaml.v3"
pb "github.com/synctv-org/synctv/proto"
"google.golang.org/protobuf/proto"
)
type Message interface {
@ -15,72 +14,54 @@ type Message interface {
Encode(wc io.Writer) error
}
type ElementMessageType int
const (
Error ElementMessageType = iota + 1
ChatMessage
Play
Pause
CheckSeek
TooFast
TooSlow
ChangeRate
ChangeSeek
ChangeCurrent
ChangeMovieList
ChangePeopleNum
)
type ElementMessage struct {
Type ElementMessageType `json:"type" yaml:"type"`
Sender string `json:"sender,omitempty" yaml:"sender,omitempty"`
Message string `json:"message,omitempty" yaml:"message,omitempty"`
Seek float64 `json:"seek,omitempty" yaml:"seek,omitempty"`
Rate float64 `json:"rate,omitempty" yaml:"rate,omitempty"`
Current *Current `json:"current,omitempty" yaml:"current,omitempty"`
PeopleNum int64 `json:"peopleNum,omitempty" yaml:"peopleNum,omitempty"`
Time int64 `json:"time,omitempty" yaml:"time,omitempty"`
*pb.ElementMessage
}
func (em *ElementMessage) MessageType() int {
return websocket.TextMessage
return websocket.BinaryMessage
}
func (em *ElementMessage) String() string {
out, _ := yaml.Marshal(em)
switch em.Type {
case Error:
return fmt.Sprintf("Element Error: %s", out)
case ChatMessage:
return fmt.Sprintf("Element ChatMessage: %s", out)
case Play:
return fmt.Sprintf("Element Play: %s", out)
case Pause:
return fmt.Sprintf("Element Pause: %s", out)
case CheckSeek:
return fmt.Sprintf("Element CheckSeek: %s", out)
case TooFast:
return fmt.Sprintf("Element TooFast: %s", out)
case TooSlow:
return fmt.Sprintf("Element TooSlow: %s", out)
case ChangeRate:
return fmt.Sprintf("Element ChangeRate: %s", out)
case ChangeSeek:
return fmt.Sprintf("Element ChangeSeek: %s", out)
case ChangeCurrent:
return fmt.Sprintf("Element ChangeCurrent: %s", out)
case ChangeMovieList:
return fmt.Sprintf("Element ChangeMovieList: %s", out)
case ChangePeopleNum:
return fmt.Sprintf("Element ChangePeopleNum: %s", out)
default:
return fmt.Sprintf("Element Unknown: %s", out)
}
// out, _ := yaml.Marshal(em)
// switch em.Type {
// case Error:
// return fmt.Sprintf("Element Error: %s", out)
// case ChatMessage:
// return fmt.Sprintf("Element ChatMessage: %s", out)
// case Play:
// return fmt.Sprintf("Element Play: %s", out)
// case Pause:
// return fmt.Sprintf("Element Pause: %s", out)
// case CheckSeek:
// return fmt.Sprintf("Element CheckSeek: %s", out)
// case TooFast:
// return fmt.Sprintf("Element TooFast: %s", out)
// case TooSlow:
// return fmt.Sprintf("Element TooSlow: %s", out)
// case ChangeRate:
// return fmt.Sprintf("Element ChangeRate: %s", out)
// case ChangeSeek:
// return fmt.Sprintf("Element ChangeSeek: %s", out)
// case ChangeCurrent:
// return fmt.Sprintf("Element ChangeCurrent: %s", out)
// case ChangeMovies:
// return fmt.Sprintf("Element ChangeMovieList: %s", out)
// case ChangePeople:
// return fmt.Sprintf("Element ChangePeopleNum: %s", out)
// default:
// return fmt.Sprintf("Element Unknown: %s", out)
// }
return ""
}
func (em *ElementMessage) Encode(wc io.Writer) error {
return json.NewEncoder(wc).Encode(em)
b, err := proto.Marshal(em)
if err != nil {
return err
}
_, err = wc.Write(b)
return err
}
type PingMessage struct{}

@ -29,17 +29,16 @@ type movies struct {
// Url will be `PullKey` when Live and Proxy are true
type Movie struct {
BaseMovie
PullKey string `json:"pullKey"`
CreateAt int64 `json:"createAt"`
LastEditAt int64 `json:"lastEditAt"`
BaseMovieInfo
PullKey string `json:"pullKey"`
CreatedAt int64 `json:"createAt"`
id uint64
channel *rtmps.Channel
creator *User
}
type BaseMovie struct {
type BaseMovieInfo struct {
Url string `json:"url"`
Name string `json:"name"`
Live bool `json:"live"`
@ -70,7 +69,7 @@ func WithCreator(creator *User) MovieConf {
}
func NewMovie(id uint64, url, name, type_ string, live, proxy, rtmpSource bool, headers map[string]string, conf ...MovieConf) (*Movie, error) {
return NewMovieWithBaseMovie(id, BaseMovie{
return NewMovieWithBaseMovie(id, BaseMovieInfo{
Url: url,
Name: name,
Live: live,
@ -81,13 +80,11 @@ func NewMovie(id uint64, url, name, type_ string, live, proxy, rtmpSource bool,
})
}
func NewMovieWithBaseMovie(id uint64, baseMovie BaseMovie, conf ...MovieConf) (*Movie, error) {
now := time.Now().UnixMicro()
func NewMovieWithBaseMovie(id uint64, baseMovie BaseMovieInfo, conf ...MovieConf) (*Movie, error) {
m := &Movie{
id: id,
BaseMovie: baseMovie,
CreateAt: now,
LastEditAt: now,
id: id,
BaseMovieInfo: baseMovie,
CreatedAt: time.Now().UnixMilli(),
}
m.Init(conf...)
return m, m.Check()
@ -151,18 +148,11 @@ func (m *movies) range_(f func(e *dllist.Element[*Movie]) bool) (interrupt bool)
}
type MovieInfo struct {
Id uint64 `json:"id"`
Url string `json:"url"`
Name string `json:"name"`
Live bool `json:"live"`
Proxy bool `json:"proxy"`
RtmpSource bool `json:"rtmpSource"`
Type string `json:"type"`
Headers map[string]string `json:"headers"`
PullKey string `json:"pullKey"`
CreateAt int64 `json:"createAt"`
LastEditAt int64 `json:"lastEditAt"`
Creator string `json:"creator"`
Id uint64 `json:"id"`
BaseMovieInfo
PullKey string `json:"pullKey"`
CreatedAt int64 `json:"createdAt"`
Creator string `json:"creator"`
}
func (m *movies) MovieList() (movies []MovieInfo) {
@ -172,17 +162,18 @@ func (m *movies) MovieList() (movies []MovieInfo) {
movies = make([]MovieInfo, 0, m.l.Len())
m.range_(func(e *dllist.Element[*Movie]) bool {
movies = append(movies, MovieInfo{
Id: e.Value.id,
Url: e.Value.Url,
Name: e.Value.Name,
Live: e.Value.Live,
Proxy: e.Value.Proxy,
RtmpSource: e.Value.RtmpSource,
Type: e.Value.Type,
Headers: e.Value.Headers,
CreateAt: e.Value.CreateAt,
LastEditAt: e.Value.LastEditAt,
Creator: e.Value.Creator().Name(),
Id: e.Value.id,
BaseMovieInfo: BaseMovieInfo{
Url: e.Value.Url,
Name: e.Value.Name,
Live: e.Value.Live,
Proxy: e.Value.Proxy,
RtmpSource: e.Value.RtmpSource,
Type: e.Value.Type,
Headers: e.Value.Headers,
},
CreatedAt: e.Value.CreatedAt,
Creator: e.Value.Creator().Name(),
})
return true
})

@ -25,7 +25,7 @@ type Room struct {
password []byte
needPassword uint32
version uint64
current *Current
current *current
rtmps *rtmps.Server
rtmpa *rtmps.App
hidden uint32
@ -274,7 +274,8 @@ func (r *Room) updateVersion() uint64 {
}
func (r *Room) Current() *Current {
return r.current
c := r.current.Current()
return &c
}
// Seek will be set to 0
@ -285,18 +286,19 @@ func (r *Room) ChangeCurrentMovie(id uint64) error {
return err
}
r.current.SetMovie(MovieInfo{
Id: e.Value.id,
Url: e.Value.Url,
Name: e.Value.Name,
Live: e.Value.Live,
Proxy: e.Value.Proxy,
RtmpSource: e.Value.RtmpSource,
Type: e.Value.Type,
Headers: e.Value.Headers,
PullKey: e.Value.PullKey,
CreateAt: e.Value.CreateAt,
LastEditAt: e.Value.LastEditAt,
Creator: e.Value.Creator().Name(),
Id: e.Value.id,
BaseMovieInfo: BaseMovieInfo{
Url: e.Value.Url,
Name: e.Value.Name,
Live: e.Value.Live,
Proxy: e.Value.Proxy,
RtmpSource: e.Value.RtmpSource,
Type: e.Value.Type,
Headers: e.Value.Headers,
},
PullKey: e.Value.PullKey,
CreatedAt: e.Value.CreatedAt,
Creator: e.Value.Creator().Name(),
})
return nil
}

@ -7,6 +7,7 @@ import (
"time"
"github.com/gorilla/websocket"
pb "github.com/synctv-org/synctv/proto"
"github.com/zijiren233/gencontainer/dllist"
"github.com/zijiren233/stream"
"golang.org/x/crypto/bcrypt"
@ -143,7 +144,7 @@ func (u *User) SetAdmin(admin bool) {
}
func (u *User) NewMovie(url string, name string, type_ string, live bool, proxy bool, rtmpSource bool, headers map[string]string, conf ...MovieConf) (*Movie, error) {
return u.NewMovieWithBaseMovie(BaseMovie{
return u.NewMovieWithBaseMovie(BaseMovieInfo{
Url: url,
Name: name,
Live: live,
@ -154,11 +155,11 @@ func (u *User) NewMovie(url string, name string, type_ string, live bool, proxy
}, conf...)
}
func (u *User) NewMovieWithBaseMovie(baseMovie BaseMovie, conf ...MovieConf) (*Movie, error) {
func (u *User) NewMovieWithBaseMovie(baseMovie BaseMovieInfo, conf ...MovieConf) (*Movie, error) {
return NewMovieWithBaseMovie(atomic.AddUint64(&u.room.mid, 1), baseMovie, append(conf, WithCreator(u))...)
}
func (u *User) Movie(id uint64) (*MovieInfo, error) {
func (u *User) Movie(id uint64) (*pb.MovieInfo, error) {
u.room.movies.lock.RLock()
defer u.room.movies.lock.RUnlock()
@ -166,7 +167,7 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) {
if err != nil {
return nil, err
}
movie := &MovieInfo{
movie := &pb.MovieInfo{
Id: m.Id(),
Url: m.Url,
Name: m.Name,
@ -176,8 +177,7 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) {
Type: m.Type,
Headers: m.Headers,
PullKey: m.PullKey,
CreateAt: m.CreateAt,
LastEditAt: m.LastEditAt,
CreatedAt: m.CreatedAt,
Creator: m.Creator().Name(),
}
if movie.Proxy && u.name != movie.Creator {
@ -186,13 +186,13 @@ func (u *User) Movie(id uint64) (*MovieInfo, error) {
return movie, nil
}
func (u *User) MovieList() []*MovieInfo {
func (u *User) MovieList() []*pb.MovieInfo {
u.room.movies.lock.RLock()
defer u.room.movies.lock.RUnlock()
movies := make([]*MovieInfo, 0, u.room.movies.l.Len())
movies := make([]*pb.MovieInfo, 0, u.room.movies.l.Len())
u.room.movies.range_(func(e *dllist.Element[*Movie]) bool {
m := &MovieInfo{
m := &pb.MovieInfo{
Id: e.Value.Id(),
Url: e.Value.Url,
Name: e.Value.Name,
@ -202,8 +202,7 @@ func (u *User) MovieList() []*MovieInfo {
Type: e.Value.Type,
Headers: e.Value.Headers,
PullKey: e.Value.PullKey,
CreateAt: e.Value.CreateAt,
LastEditAt: e.Value.LastEditAt,
CreatedAt: e.Value.CreatedAt,
Creator: e.Value.Creator().Name(),
}
if e.Value.Proxy && u.name != m.Creator {

@ -17,6 +17,7 @@ import (
"github.com/google/uuid"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/conf"
pb "github.com/synctv-org/synctv/proto"
"github.com/synctv-org/synctv/room"
"github.com/synctv-org/synctv/utils"
"github.com/zijiren233/livelib/av"
@ -97,7 +98,7 @@ func Movies(ctx *gin.Context) {
}))
}
type PushMovieReq = room.BaseMovie
type PushMovieReq = room.BaseMovieInfo
func PushMovie(ctx *gin.Context) {
user, err := AuthRoom(ctx.GetHeader("Authorization"))
@ -219,8 +220,10 @@ func PushMovie(ctx *gin.Context) {
}
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeMovieList,
Sender: user.Name(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_MOVIES,
Sender: user.Name(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -318,8 +321,10 @@ func EditMovie(ctx *gin.Context) {
m.Headers = req.Headers
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeMovieList,
Sender: user.Name(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_MOVIES,
Sender: user.Name(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -351,8 +356,10 @@ func DelMovie(ctx *gin.Context) {
}
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeMovieList,
Sender: user.Name(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_MOVIES,
Sender: user.Name(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -374,8 +381,10 @@ func ClearMovies(ctx *gin.Context) {
}
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeMovieList,
Sender: user.Name(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_MOVIES,
Sender: user.Name(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -408,8 +417,10 @@ func SwapMovie(ctx *gin.Context) {
}
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeMovieList,
Sender: user.Name(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_MOVIES,
Sender: user.Name(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -439,11 +450,12 @@ func ChangeCurrentMovie(ctx *gin.Context) {
ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorResp(err))
return
}
if err := user.Broadcast(&room.ElementMessage{
Type: room.ChangeCurrent,
Sender: user.Name(),
Current: user.Room().Current(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_CURRENT,
Sender: user.Name(),
Current: user.Room().Current().Proto(),
},
}, room.WithSendToSelf()); err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, NewApiErrorResp(err))
return
@ -499,7 +511,7 @@ func ProxyMovie(ctx *gin.Context) {
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorResp(err))
}
cm := room.Current().Movie()
cm := room.Current().Movie
if !cm.Proxy || cm.Live {
ctx.AbortWithStatusJSON(http.StatusBadRequest, NewApiErrorStringResp("not support proxy"))
return

@ -15,6 +15,7 @@ import (
"github.com/golang-jwt/jwt/v5"
"github.com/maruel/natural"
"github.com/synctv-org/synctv/internal/conf"
pb "github.com/synctv-org/synctv/proto"
"github.com/synctv-org/synctv/room"
"github.com/zijiren233/gencontainer/vec"
rtmps "github.com/zijiren233/livelib/server"
@ -173,8 +174,10 @@ func NewCreateRoomHandler(s *rtmps.Server) gin.HandlerFunc {
current := r.ClientNum()
if current != pre {
if err := r.Broadcast(&room.ElementMessage{
Type: room.ChangePeopleNum,
PeopleNum: current,
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_PEOPLE,
PeopleNum: current,
},
}); err != nil {
log.Errorf("ws: room %s broadcast people num error: %v", r.ID(), err)
continue

@ -1,15 +1,18 @@
package handlers
import (
"io"
"net/http"
"time"
json "github.com/json-iterator/go"
"google.golang.org/protobuf/proto"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
log "github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/cmd/flags"
pb "github.com/synctv-org/synctv/proto"
"github.com/synctv-org/synctv/room"
"github.com/synctv-org/synctv/utils"
)
@ -34,8 +37,10 @@ func NewWSMessageHandler(u *room.User) func(c *websocket.Conn) error {
if err != nil {
log.Errorf("ws: register client error: %v", err)
b, err := json.Marshal(room.ElementMessage{
Type: room.Error,
Message: err.Error(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Message: err.Error(),
},
})
if err != nil {
return err
@ -78,7 +83,7 @@ func handleWriterMessage(c *room.Client) error {
func handleReaderMessage(c *room.Client) error {
defer c.Close()
var timeDiff float64
var msg pb.ElementMessage
for {
t, rd, err := c.NextReader()
if err != nil {
@ -94,100 +99,143 @@ func handleReaderMessage(c *room.Client) error {
log.Infof("ws: room %s user %s receive close message", c.Room().ID(), c.Username())
}
return nil
case websocket.TextMessage:
msg := room.ElementMessage{}
if err := json.NewDecoder(rd).Decode(&msg); err != nil {
log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err)
case websocket.BinaryMessage:
var data []byte
if data, err = io.ReadAll(rd); err != nil {
log.Errorf("ws: room %s user %s read message error: %v", c.Room().ID(), c.Username(), err)
if err := c.Send(&room.ElementMessage{
Type: room.Error,
Message: err.Error(),
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Message: err.Error(),
},
}); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err)
return err
}
continue
}
if flags.Dev {
log.Infof("ws: receive room %s user %s message: %+v", c.Room().ID(), c.Username(), msg)
}
if msg.Time != 0 {
timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds()
} else {
timeDiff = 0.0
}
if timeDiff < 0 {
timeDiff = 0
} else if timeDiff > 1.5 {
timeDiff = 1.5
}
switch msg.Type {
case room.ChatMessage:
if len(msg.Message) > 4096 {
c.Send(&room.ElementMessage{
Type: room.Error,
Message: "message too long",
})
continue
if err := proto.Unmarshal(data, &msg); err != nil {
log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err)
if err := c.Send(&room.ElementMessage{
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Message: err.Error(),
},
}); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err)
return err
}
c.Broadcast(&room.ElementMessage{
Type: room.ChatMessage,
Sender: c.Username(),
Message: msg.Message,
}, room.WithSendToSelf())
case room.Play:
status := c.Room().SetStatus(true, msg.Seek, msg.Rate, timeDiff)
c.Broadcast(&room.ElementMessage{
Type: room.Play,
Sender: c.Username(),
Seek: status.Seek,
Rate: status.Rate,
})
case room.Pause:
status := c.Room().SetStatus(false, msg.Seek, msg.Rate, timeDiff)
c.Broadcast(&room.ElementMessage{
Type: room.Pause,
Sender: c.Username(),
Seek: status.Seek,
Rate: status.Rate,
})
case room.ChangeRate:
status := c.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff)
c.Broadcast(&room.ElementMessage{
Type: room.ChangeRate,
Sender: c.Username(),
Seek: status.Seek,
Rate: status.Rate,
})
case room.ChangeSeek:
status := c.Room().SetSeekRate(msg.Seek, msg.Rate, timeDiff)
c.Broadcast(&room.ElementMessage{
Type: room.ChangeSeek,
Sender: c.Username(),
Seek: status.Seek,
Rate: status.Rate,
})
case room.CheckSeek:
status := c.Room().Current().Status()
if status.Seek+maxInterval < msg.Seek+timeDiff {
c.Send(&room.ElementMessage{
Type: room.TooFast,
Seek: status.Seek,
Rate: status.Rate,
})
} else if status.Seek-maxInterval > msg.Seek+timeDiff {
c.Send(&room.ElementMessage{
Type: room.TooSlow,
Seek: status.Seek,
Rate: status.Rate,
})
} else {
c.Send(&room.ElementMessage{
Type: room.CheckSeek,
Seek: status.Seek,
Rate: status.Rate,
})
continue
}
case websocket.TextMessage:
if err := json.NewDecoder(rd).Decode(&msg); err != nil {
log.Errorf("ws: room %s user %s decode message error: %v", c.Room().ID(), c.Username(), err)
if err := c.Send(&room.ElementMessage{
ElementMessage: &pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Message: err.Error(),
},
}); err != nil {
log.Errorf("ws: room %s user %s send error message error: %v", c.Room().ID(), c.Username(), err)
return err
}
continue
}
}
if flags.Dev {
log.Infof("ws: receive room %s user %s message: %+v", c.Room().ID(), c.Username(), msg.String())
}
if err := handleElementMsg(c.Room(), &msg, func(em *pb.ElementMessage) error {
em.Sender = c.Username()
return c.Send(&room.ElementMessage{ElementMessage: em})
}, func(em *pb.ElementMessage, bc ...room.BroadcastConf) error {
em.Sender = c.Username()
return c.Broadcast(&room.ElementMessage{ElementMessage: em}, bc...)
}); err != nil {
log.Errorf("ws: room %s user %s handle message error: %v", c.Room().ID(), c.Username(), err)
return err
}
}
}
type send func(*pb.ElementMessage) error
type broadcast func(*pb.ElementMessage, ...room.BroadcastConf) error
func handleElementMsg(r *room.Room, msg *pb.ElementMessage, send send, broadcast broadcast) error {
var timeDiff float64
if msg.Time != 0 {
timeDiff = time.Since(time.UnixMilli(msg.Time)).Seconds()
} else {
timeDiff = 0.0
}
if timeDiff < 0 {
timeDiff = 0
} else if timeDiff > 1.5 {
timeDiff = 1.5
}
switch msg.Type {
case pb.ElementMessageType_CHAT_MESSAGE:
if len(msg.Message) > 4096 {
send(&pb.ElementMessage{
Type: pb.ElementMessageType_ERROR,
Message: "message too long",
})
return nil
}
broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_CHAT_MESSAGE,
Message: msg.Message,
}, room.WithSendToSelf())
case pb.ElementMessageType_PLAY:
status := r.SetStatus(true, msg.Seek, msg.Rate, timeDiff)
broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_PLAY,
Seek: status.Seek,
Rate: status.Rate,
})
case pb.ElementMessageType_PAUSE:
status := r.SetStatus(false, msg.Seek, msg.Rate, timeDiff)
broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_PAUSE,
Seek: status.Seek,
Rate: status.Rate,
})
case pb.ElementMessageType_CHANGE_RATE:
status := r.SetSeekRate(msg.Seek, msg.Rate, timeDiff)
broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_RATE,
Seek: status.Seek,
Rate: status.Rate,
})
case pb.ElementMessageType_CHANGE_SEEK:
status := r.SetSeekRate(msg.Seek, msg.Rate, timeDiff)
broadcast(&pb.ElementMessage{
Type: pb.ElementMessageType_CHANGE_SEEK,
Seek: status.Seek,
Rate: status.Rate,
})
case pb.ElementMessageType_CHECK_SEEK:
status := r.Current().Status
if status.Seek+maxInterval < msg.Seek+timeDiff {
send(&pb.ElementMessage{
Type: pb.ElementMessageType_TOO_FAST,
Seek: status.Seek,
Rate: status.Rate,
})
} else if status.Seek-maxInterval > msg.Seek+timeDiff {
send(&pb.ElementMessage{
Type: pb.ElementMessageType_TOO_SLOW,
Seek: status.Seek,
Rate: status.Rate,
})
} else {
send(&pb.ElementMessage{
Type: pb.ElementMessageType_CHECK_SEEK,
Seek: status.Seek,
Rate: status.Rate,
})
}
}
return nil
}

Loading…
Cancel
Save