mirror of
https://github.com/AynaLivePlayer/liveroom-sdk.git
synced 2026-05-09 08:44:04 +08:00
first commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
go.sum
|
||||
42
example/openblive/openblive.go
Normal file
42
example/openblive/openblive.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"liveroom"
|
||||
"liveroom/provider/openblive"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
const apiServer = "http://0.0.0.0:9090"
|
||||
|
||||
func main() {
|
||||
provider := openblive.NewOpenBLiveClientProvider(apiServer, 1661006726438)
|
||||
room := provider(liveroom.LiveRoomConfig{
|
||||
Room: "YOUR_CLIENT_KEY",
|
||||
Provider: openblive.ProviderName,
|
||||
})
|
||||
room.OnMessage(func(msg *liveroom.Message) {
|
||||
fmt.Println(msg.User.Username, msg.User.Uid, msg.User.Medal.Name, msg.Message)
|
||||
})
|
||||
room.OnStatusChange(
|
||||
func(connected bool) {
|
||||
if connected {
|
||||
fmt.Println("Connected")
|
||||
} else {
|
||||
fmt.Println("Disconnected")
|
||||
}
|
||||
})
|
||||
room.OnDisconnect(
|
||||
func(liveroom liveroom.LiveRoom) {
|
||||
fmt.Println("Disconnected AAAAAAAa")
|
||||
})
|
||||
fmt.Println("connect", room.Connect())
|
||||
quit := make(chan os.Signal)
|
||||
signal.Notify(quit, os.Interrupt, os.Kill)
|
||||
<-quit
|
||||
fmt.Println("disconnect", room.Disconnect())
|
||||
time.Sleep(3 * time.Second)
|
||||
fmt.Println("Bye")
|
||||
}
|
||||
14
go.mod
Normal file
14
go.mod
Normal file
@@ -0,0 +1,14 @@
|
||||
module liveroom
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/aynakeya/open-bilibili-live v0.0.3
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/spf13/cast v1.5.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
|
||||
)
|
||||
44
liveroom.go
Normal file
44
liveroom.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package liveroom
|
||||
|
||||
type LiveRoomConfig struct {
|
||||
Provider string `json:"provider"` // Provider is the name of the live room provider
|
||||
Room string `json:"room"` // RoomID is the unique identifier of the live room
|
||||
}
|
||||
|
||||
type LiveRoomProvider func(cfg LiveRoomConfig) LiveRoom
|
||||
|
||||
type UserMedal struct {
|
||||
Name string `json:"name"`
|
||||
Level int `json:"level"`
|
||||
RoomID string `json:"room_id"`
|
||||
}
|
||||
|
||||
const (
|
||||
PrivilegeNone = iota
|
||||
PrivilegeBasic
|
||||
PrivilegeAdvanced
|
||||
PrivilegeUltimate
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Uid string
|
||||
Username string
|
||||
Admin bool
|
||||
Privilege int
|
||||
Medal UserMedal
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
User User
|
||||
Message string
|
||||
}
|
||||
|
||||
type LiveRoom interface {
|
||||
GetName() string // should return the name of the provider
|
||||
Config() *LiveRoomConfig // should return mutable model (not a copy)
|
||||
Connect() error
|
||||
Disconnect() error
|
||||
OnDisconnect(func(liveroom LiveRoom))
|
||||
OnStatusChange(func(connected bool))
|
||||
OnMessage(func(msg *Message))
|
||||
}
|
||||
68
provider/openblive/apiclient.go
Normal file
68
provider/openblive/apiclient.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package openblive
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/aynakeya/open-bilibili-live"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type remoteApiClient struct {
|
||||
client *resty.Client
|
||||
}
|
||||
|
||||
type openbliveResponse struct {
|
||||
Result *openblive.AppStartResult `json:"result"`
|
||||
Error *openblive.PublicError `json:"error"`
|
||||
}
|
||||
|
||||
func newRemoteApiClient(remoteApi string) openblive.IApiClient {
|
||||
return &remoteApiClient{
|
||||
client: resty.New().SetBaseURL(remoteApi),
|
||||
}
|
||||
}
|
||||
|
||||
type sceneAppResponse struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data openbliveResponse `json:"data"`
|
||||
}
|
||||
|
||||
func parseApiResponse(resp *resty.Response, err error) (*openblive.AppStartResult, *openblive.PublicError) {
|
||||
if err != nil {
|
||||
return nil, openblive.ErrUnknown.WithDetail(err)
|
||||
}
|
||||
var sceneResp sceneAppResponse
|
||||
err = json.Unmarshal(resp.Body(), &sceneResp)
|
||||
if err != nil {
|
||||
return nil, openblive.ErrUnknown.WithDetail(err)
|
||||
}
|
||||
if sceneResp.Code != 0 {
|
||||
return nil, openblive.ErrUnknown.WithDetail(errors.New(sceneResp.Msg))
|
||||
}
|
||||
return sceneResp.Data.Result, sceneResp.Data.Error
|
||||
|
||||
}
|
||||
|
||||
func (r *remoteApiClient) AppStart(code string, appId int64) (*openblive.AppStartResult, *openblive.PublicError) {
|
||||
return parseApiResponse(r.client.R().
|
||||
SetQueryParam("code", code).
|
||||
SetQueryParam("app_id", cast.ToString(appId)).
|
||||
Get("/api/blivedm/openblive/app_start"))
|
||||
}
|
||||
|
||||
func (r *remoteApiClient) AppEnd(appId int64, gameId string) *openblive.PublicError {
|
||||
_, err := parseApiResponse(r.client.R().
|
||||
SetQueryParam("app_id", cast.ToString(appId)).
|
||||
SetQueryParam("game_id", gameId).
|
||||
Get("/api/blivedm/openblive/app_end"))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *remoteApiClient) HearBeat(gameId string) *openblive.PublicError {
|
||||
_, err := parseApiResponse(r.client.R().
|
||||
SetQueryParam("game_id", gameId).
|
||||
Get("/api/blivedm/openblive/heartbeat"))
|
||||
return err
|
||||
}
|
||||
118
provider/openblive/openblive.go
Normal file
118
provider/openblive/openblive.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package openblive
|
||||
|
||||
import (
|
||||
"context"
|
||||
openblive "github.com/aynakeya/open-bilibili-live"
|
||||
"liveroom"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const ProviderName = "openblive"
|
||||
|
||||
type OpenBLiveClient struct {
|
||||
cfg liveroom.LiveRoomConfig
|
||||
openbliveClient *openblive.BLiveClient
|
||||
conn openblive.BLiveLongConnection
|
||||
onMessage func(msg *liveroom.Message)
|
||||
onDisconnect func(liveroom liveroom.LiveRoom)
|
||||
onStatusChange func(connected bool)
|
||||
}
|
||||
|
||||
func NewOpenBLiveClientProvider(apiServer string, appId int64) liveroom.LiveRoomProvider {
|
||||
return func(cfg liveroom.LiveRoomConfig) liveroom.LiveRoom {
|
||||
if cfg.Provider != ProviderName {
|
||||
return nil
|
||||
}
|
||||
return &OpenBLiveClient{
|
||||
cfg: cfg,
|
||||
openbliveClient: openblive.NewBliveClient(appId, cfg.Room, newRemoteApiClient(apiServer)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func guardLevelToPrivilege(level int) int {
|
||||
switch level {
|
||||
case 1:
|
||||
return liveroom.PrivilegeUltimate
|
||||
case 2:
|
||||
return liveroom.PrivilegeAdvanced
|
||||
case 3:
|
||||
return liveroom.PrivilegeBasic
|
||||
default:
|
||||
return liveroom.PrivilegeNone
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) danmuHandler(data openblive.DanmakuData) {
|
||||
if o.onMessage == nil {
|
||||
return
|
||||
}
|
||||
o.onMessage(&liveroom.Message{
|
||||
User: liveroom.User{
|
||||
Uid: data.OpenID,
|
||||
Username: data.UName,
|
||||
Admin: false, // not supported by open bilibili live
|
||||
Privilege: guardLevelToPrivilege(data.GuardLevel),
|
||||
Medal: liveroom.UserMedal{
|
||||
Name: data.FansMedalName,
|
||||
Level: data.FansMedalLevel,
|
||||
RoomID: strconv.Itoa(data.RoomID),
|
||||
},
|
||||
},
|
||||
Message: data.Msg,
|
||||
})
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) disconnectHandler(conn openblive.BLiveLongConnection) {
|
||||
if o.onStatusChange != nil {
|
||||
o.onStatusChange(false)
|
||||
}
|
||||
if o.onDisconnect != nil {
|
||||
o.onDisconnect(o)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) GetName() string {
|
||||
return ProviderName
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) Config() *liveroom.LiveRoomConfig {
|
||||
return &o.cfg
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) Connect() error {
|
||||
err := o.openbliveClient.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.conn = o.openbliveClient.GetLongConn()
|
||||
o.conn.OnDanmu(o.danmuHandler)
|
||||
o.conn.OnDisconnect(o.disconnectHandler)
|
||||
e := o.conn.EstablishConnection(context.Background())
|
||||
if e == nil {
|
||||
if o.onStatusChange != nil {
|
||||
o.onStatusChange(true)
|
||||
}
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) Disconnect() error {
|
||||
_ = o.conn.CloseConnection()
|
||||
if o.onStatusChange != nil {
|
||||
o.onStatusChange(false)
|
||||
}
|
||||
return o.openbliveClient.End()
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) OnStatusChange(f func(connected bool)) {
|
||||
o.onStatusChange = f
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) OnDisconnect(f func(liveroom liveroom.LiveRoom)) {
|
||||
o.onDisconnect = f
|
||||
}
|
||||
|
||||
func (o *OpenBLiveClient) OnMessage(f func(msg *liveroom.Message)) {
|
||||
o.onMessage = f
|
||||
}
|
||||
24
registry.go
Normal file
24
registry.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package liveroom
|
||||
|
||||
var _providers map[string]LiveRoomProvider = make(map[string]LiveRoomProvider)
|
||||
|
||||
func RegisterProvider(name string, provider LiveRoomProvider) {
|
||||
if _, ok := _providers[name]; ok {
|
||||
panic("provider " + name + " already exists")
|
||||
return
|
||||
}
|
||||
_providers[name] = provider
|
||||
}
|
||||
|
||||
func GetProvider(name string) (LiveRoomProvider, bool) {
|
||||
provider, ok := _providers[name]
|
||||
return provider, ok
|
||||
}
|
||||
|
||||
func ListAvailableProviders() []string {
|
||||
var names []string
|
||||
for name := range _providers {
|
||||
names = append(names, name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
Reference in New Issue
Block a user