diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..1f07e73 --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,28 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.18' + + - name: Test + run: go test -v ./... + + - name: Build + run: go build -v ./... diff --git a/.gitignore b/.gitignore index e8e69ce..8da216d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ go.work .idea .vscode .DS_Store + +**/.env \ No newline at end of file diff --git a/README.md b/README.md index ab65fad..947aa94 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ## 安装 使用以下命令从 GitHub 安装依赖: ```shell -go get -u github.com/AgoraIO/agora-rest-client-go +go get -u github.com/AgoraIO-Community/agora-rest-client-go ``` ## 使用示例 以调用云录制服务为例: @@ -30,9 +30,9 @@ import ( "context" "log" - "github.com/AgoraIO/agora-rest-client-go/core" - "github.com/AgoraIO/agora-rest-client-go/services/cloudrecording" - v1 "github.com/AgoraIO/agora-rest-client-go/services/cloudrecording/v1" + "github.com/AgoraIO-Community/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording" + v1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" ) const ( diff --git a/core/domain.go b/core/domain.go index d00fa5e..015911b 100644 --- a/core/domain.go +++ b/core/domain.go @@ -3,7 +3,6 @@ package core import ( "context" "fmt" - "slices" "sync" "time" ) @@ -157,7 +156,7 @@ func (d *DomainPool) NextRegion() { } func (d *DomainPool) selectDomain(domain string) { - if slices.Contains(d.domainSuffixes, domain) { + if Contains(d.domainSuffixes, domain) { d.currentDomain = domain d.lastUpdate = time.Now() } diff --git a/core/utils.go b/core/utils.go new file mode 100644 index 0000000..7535aa5 --- /dev/null +++ b/core/utils.go @@ -0,0 +1,10 @@ +package core + +func Contains(S []string, E string) bool { + for _, s := range S { + if s == E { + return true + } + } + return false +} diff --git a/examples/cloudrecording/README.md b/examples/cloudrecording/README.md new file mode 100644 index 0000000..74943ae --- /dev/null +++ b/examples/cloudrecording/README.md @@ -0,0 +1,37 @@ +## CloudRecording Example + +> 这是 Agora Cloud Recording 的一个示例项目,使用了 Agora Cloud Recording RESTful API,实现了频道录制的功能。本示例支持合流录制、单流录制和页面录制三种模式。 + +### 运行示例项目 + +#### 前提条件 + +在当前目录创建一个 `.env` 文件,填入以下内容: + +```bash +APP_ID= +BASIC_AUTH_USERNAME= +BASIC_AUTH_PASSWORD= +CNAME= +TOKEN= +UID= +STORAGE_CONFIG_VENDOR= +STORAGE_CONFIG_REGION= +STORAGE_CONFIG_BUCKET= +STORAGE_CONFIG_ACCESS_KEY= +STORAGE_CONFIG_SECRET_KEY= +``` +相关的参数可以通过可在 [CloudRecording 服务说明](../../services/cloudrecording/README.md) 查看 + +#### 执行 + +通过下面的命令来运行示例项目: + +```bash +go run main.go -mode= +``` + +其中 `` 表示运行的云录制模式,以下是 mode 数值对应的录制模式: +* 1: MixRecording 合流录制 +* 2: IndividualRecording 单流录制 +* 3: WebRecording 页面录制 diff --git a/examples/cloudrecording/main.go b/examples/cloudrecording/main.go index ac55cd5..1170f1f 100644 --- a/examples/cloudrecording/main.go +++ b/examples/cloudrecording/main.go @@ -2,27 +2,32 @@ package main import ( "context" + "flag" "log" + "os" + "strconv" "time" - "github.com/AgoraIO/agora-rest-client-go/core" - "github.com/AgoraIO/agora-rest-client-go/services/cloudrecording" - v1 "github.com/AgoraIO/agora-rest-client-go/services/cloudrecording/v1" + "github.com/joho/godotenv" + + "github.com/AgoraIO-Community/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording" + v1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" ) -const ( - appId = "" - username = "" - password = "" - token = "" - cname = "" - uid = "" +var ( + appId string + username string + password string + token string + cname string + uid string // 选择你的区域,目前支持的区域有: // US: 北美 // EU: 欧洲 // CN: 中国大陆 // AP: 亚太 - region = core.CN + region core.RegionArea = core.CN ) var ( @@ -34,40 +39,72 @@ var ( Bucket: "", AccessKey: "", SecretKey: "", + FileNamePrefix: []string{ + "", + }, } ) func main() { - AcquireFunc() - MixRecording() - IndividualRecording() -} + log.SetFlags(log.LstdFlags | log.Lshortfile) + err := godotenv.Load("/Users/admin/go/src/agora-rest-client-go/examples/cloudrecording/.env") + if err != nil { + log.Fatal(err) + } -func AcquireFunc() { - c := core.NewClient(&core.Config{ - AppID: appId, - Credential: core.NewBasicAuthCredential(username, password), - RegionCode: region, - Logger: core.DiscardLogger, - }) + appId = os.Getenv("APP_ID") + if appId == "" { + panic("APP_ID is required") + } + username = os.Getenv("BASIC_AUTH_USERNAME") + if username == "" { + panic("BASIC_AUTH_USERNAME is required") + } - cloudRecordingAPI := cloudrecording.NewAPI(c) + password = os.Getenv("BASIC_AUTH_PASSWORD") + if password == "" { + panic("BASIC_PASSWORD is required") + } + token = os.Getenv("TOKEN") + cname = os.Getenv("CNAME") + if cname == "" { + panic("CNAME is required") + } + uid = os.Getenv("UID") + if uid == "" { + panic("UID is required") + } - resp, err := cloudRecordingAPI.V1().Acquire().Do(context.TODO(), &v1.AcquirerReqBody{ - Cname: cname, - Uid: uid, - ClientRequest: &v1.AcquirerClientRequest{ - Scene: 0, - ResourceExpiredHour: 24, - }, - }) + vendorStr := os.Getenv("STORAGE_CONFIG_VENDOR") + storageVendor, err := strconv.Atoi(vendorStr) if err != nil { - log.Fatal(err) + panic(err) } - if resp.IsSuccess() { - log.Printf("resourceId:%s", resp.SuccessRes.ResourceId) - } else { - log.Printf("resp:%+v", resp) + storageRegionStr := os.Getenv("STORAGE_CONFIG_REGION") + storageRegion, err := strconv.Atoi(storageRegionStr) + if err != nil { + panic(err) + } + + storageConfig.Vendor = storageVendor + storageConfig.Region = storageRegion + + storageConfig.Bucket = os.Getenv("STORAGE_CONFIG_BUCKET") + storageConfig.AccessKey = os.Getenv("STORAGE_CONFIG_ACCESS_KEY") + storageConfig.SecretKey = os.Getenv("STORAGE_CONFIG_SECRET_KEY") + + mode := flag.Int("mode", 3, "1: mix, 2: individual, 3: webRecording") + flag.Parse() + + switch *mode { + case 1: + MixRecording() + case 2: + IndividualRecording() + case 3: + WebRecording() + default: + panic("mode is required, 1: mix, 2: individual, 3: webRecording") } } @@ -75,7 +112,6 @@ func AcquireFunc() { func MixRecording() { mode := "mix" - log.SetFlags(log.LstdFlags | log.Lshortfile) ctx := context.Background() c := core.NewClient(&core.Config{ AppID: appId, @@ -122,12 +158,10 @@ func MixRecording() { BackgroundColor: "#000000", }, SubscribeAudioUIDs: []string{ - "22", - "456", + "#allstream#", }, SubscribeVideoUIDs: []string{ - "22", - "456", + "#allstream#", }, }, RecordingFileConfig: &v1.RecordingFileConfig{ @@ -272,12 +306,12 @@ func MixRecording() { StreamSubscribe: &v1.UpdateStreamSubscribe{ AudioUidList: &v1.UpdateAudioUIDList{ SubscribeAudioUIDs: []string{ - "999", + "#allstream#", }, }, VideoUidList: &v1.UpdateVideoUIDList{ SubscribeVideoUIDs: []string{ - "999", + "#allstream#", }, }, }, @@ -300,7 +334,7 @@ func MixRecording() { // IndividualRecording hls func IndividualRecording() { mode := "individual" - log.SetFlags(log.LstdFlags | log.Lshortfile) + ctx := context.Background() c := core.NewClient(&core.Config{ AppID: appId, @@ -465,3 +499,122 @@ func IndividualRecording() { } time.Sleep(2 * time.Second) } + +func WebRecording() { + ctx := context.Background() + c := core.NewClient(&core.Config{ + AppID: appId, + Credential: core.NewBasicAuthCredential(username, password), + RegionCode: region, + Logger: core.NewDefaultLogger(core.LogDebug), + }) + + webRecordingV1 := cloudrecording.NewAPI(c).V1().WebRecording() + + // acquire + resp, err := webRecordingV1.Acquire().Do(ctx, cname, uid, &v1.AcquirerWebRecodingClientRequest{ + ResourceExpiredHour: 24, + }) + if err != nil { + log.Fatal(err) + } + if resp.IsSuccess() { + log.Printf("acquire success:%+v", resp.SuccessRes) + } else { + log.Fatalf("acquire failed:%+v", resp) + } + + resourceId := resp.SuccessRes.ResourceId + + // start + starterResp, err := webRecordingV1.Start().Do(ctx, resourceId, cname, uid, &v1.StartWebRecordingClientRequest{ + AppsCollection: &v1.AppsCollection{ + CombinationPolicy: "default", + }, + RecordingFileConfig: &v1.RecordingFileConfig{ + AvFileType: []string{ + "hls", + "mp4", + }, + }, + StorageConfig: storageConfig, + ExtensionServiceConfig: &v1.ExtensionServiceConfig{ + ErrorHandlePolicy: "error_abort", + ExtensionServices: []v1.ExtensionService{ + { + ServiceName: "web_recorder_service", + ErrorHandlePolicy: "error_abort", + ServiceParam: &v1.ServiceParam{ + URL: "https://live.bilibili.com/", + AudioProfile: 2, + VideoWidth: 1280, + VideoHeight: 720, + MaxRecordingHour: 1, + }, + }, + }, + }, + }) + if err != nil { + log.Fatal(err) + } + if starterResp.IsSuccess() { + log.Printf("starterResp success:%+v", &starterResp.SuccessResp) + } else { + log.Fatalf("starterResp failed:%+v", &starterResp.ErrResponse) + } + + startSuccessResp := starterResp.SuccessResp + sid := startSuccessResp.SID + + defer func() { + // stop + stopResp, err := webRecordingV1.Stop().Do(ctx, resourceId, sid, &v1.StopReqBody{ + Cname: cname, + Uid: uid, + ClientRequest: &v1.StopClientRequest{ + AsyncStop: false, + }, + }) + if err != nil { + log.Fatalln(err) + } + if stopResp.IsSuccess() { + log.Printf("stopResp success:%+v", &stopResp.SuccessResp) + } else { + log.Fatalf("stopResp failed:%+v", &stopResp.ErrResponse) + } + log.Printf("stopServerResponse:%+v", stopResp.SuccessResp.ServerResponse) + }() + + // query + queryResp, err := webRecordingV1.Query().Do(ctx, resourceId, sid) + if err != nil { + log.Fatalln(err) + } + if queryResp.IsSuccess() { + log.Printf("queryResp success:%+v", queryResp.SuccessResp) + } else { + log.Fatalf("queryResp failed:%+v", queryResp.ErrResponse) + } + log.Printf("queryServerResponse:%+v", queryResp.SuccessResp.ServerResponse) + + time.Sleep(3 * time.Second) + + // update + updateResp, err := webRecordingV1.Update().Do(ctx, resourceId, sid, cname, uid, &v1.UpdateWebRecordingClientRequest{ + WebRecordingConfig: &v1.UpdateWebRecordingConfig{ + Onhold: false, + }, + }) + if err != nil { + log.Fatalln(err) + } + if updateResp.IsSuccess() { + log.Printf("updateResp success:%+v", updateResp.SuccessResp) + } else { + log.Fatalf("updateResp failed:%+v", updateResp.ErrResponse) + } + + time.Sleep(3 * time.Second) +} diff --git a/go.mod b/go.mod index 720437c..ecc3664 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ -module github.com/AgoraIO/agora-rest-client-go +module github.com/AgoraIO-Community/agora-rest-client-go go 1.18 require ( + github.com/joho/godotenv v1.5.1 github.com/pkg/errors v0.9.1 github.com/tidwall/gjson v1.17.0 ) diff --git a/go.sum b/go.sum index fc1738b..021a31f 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= diff --git a/services/cloudrecording/cloudrecording.go b/services/cloudrecording/cloudrecording.go index 15a81c7..392bf03 100644 --- a/services/cloudrecording/cloudrecording.go +++ b/services/cloudrecording/cloudrecording.go @@ -1,8 +1,9 @@ package cloudrecording import ( - "github.com/AgoraIO/agora-rest-client-go/core" - v1 "github.com/AgoraIO/agora-rest-client-go/services/cloudrecording/v1" + "github.com/AgoraIO-Community/agora-rest-client-go/core" + v1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" + "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1/webrecording" ) const projectName = "cloud_recording" @@ -19,6 +20,6 @@ func (a *API) buildPrefixPath() string { return "/apps/" + a.client.GetAppID() + "/" + projectName } -func (a *API) V1() *v1.Collection { - return v1.NewCollection(a.buildPrefixPath(), a.client) +func (a *API) V1() *v1.BaseCollection { + return v1.NewCollection(a.buildPrefixPath(), a.client, webrecording.NewWebRecording()) } diff --git a/services/cloudrecording/v1/acquire.go b/services/cloudrecording/v1/acquire.go index c575b4b..6cdc738 100644 --- a/services/cloudrecording/v1/acquire.go +++ b/services/cloudrecording/v1/acquire.go @@ -7,7 +7,7 @@ import ( "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type Acquire struct { @@ -31,7 +31,7 @@ type AcquirerClientRequest struct { Scene int `json:"scene"` ResourceExpiredHour int `json:"resourceExpiredHour"` ExcludeResourceIds []string `json:"excludeResourceIds,omitempty"` - RegionAffinity int `json:"regionAffinity"` + RegionAffinity int `json:"regionAffinity,omitempty"` } type AcquirerResp struct { diff --git a/services/cloudrecording/v1/query.go b/services/cloudrecording/v1/query.go index 0446cfd..cb5dd16 100644 --- a/services/cloudrecording/v1/query.go +++ b/services/cloudrecording/v1/query.go @@ -8,7 +8,7 @@ import ( "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type Query struct { diff --git a/services/cloudrecording/v1/response.go b/services/cloudrecording/v1/response.go index d5eb74d..e84b9cd 100644 --- a/services/cloudrecording/v1/response.go +++ b/services/cloudrecording/v1/response.go @@ -3,7 +3,7 @@ package v1 import ( "net/http" - client "github.com/AgoraIO/agora-rest-client-go/core" + client "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type ErrResponse struct { diff --git a/services/cloudrecording/v1/start.go b/services/cloudrecording/v1/start.go index aa2b7cb..b6b2ef0 100644 --- a/services/cloudrecording/v1/start.go +++ b/services/cloudrecording/v1/start.go @@ -7,7 +7,7 @@ import ( "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type Starter struct { @@ -187,12 +187,13 @@ type SnapshotConfig struct { FileType []string `json:"fileType"` } type StorageConfig struct { - Vendor int `json:"vendor"` - Region int `json:"region"` - Bucket string `json:"bucket"` - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` - FileNamePrefix []string `json:"fileNamePrefix,omitempty"` + Vendor int `json:"vendor"` + Region int `json:"region"` + Bucket string `json:"bucket"` + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + FileNamePrefix []string `json:"fileNamePrefix,omitempty"` + ExtensionParams *ExtensionParams `json:"extensionParams,omitempty"` } type ExtensionParams struct { @@ -201,8 +202,7 @@ type ExtensionParams struct { } type ExtensionServiceConfig struct { - ErrorHandlePolicy string `json:"errorHandlePolicy"` - APIVersion string `json:"apiVersion"` + ErrorHandlePolicy string `json:"errorHandlePolicy,omitempty"` ExtensionServices []ExtensionService `json:"extensionServices"` } @@ -217,18 +217,18 @@ type Outputs struct { } type ServiceParam struct { - Outputs []Outputs `json:"outputs"` + Outputs []Outputs `json:"outputs,omitempty"` URL string `json:"url"` - VideoBitRate int `json:"VideoBitrate"` - VideoFPS int `json:"videoFps"` + VideoBitRate int `json:"VideoBitrate,omitempty"` + VideoFPS int `json:"videoFps,omitempty"` AudioProfile int `json:"audioProfile"` - Mobile bool `json:"mobile"` + Mobile bool `json:"mobile,omitempty"` VideoWidth int `json:"videoWidth"` VideoHeight int `json:"videoHeight"` MaxRecordingHour int `json:"maxRecordingHour"` - MaxVideoDuration int `json:"MaxVideoDuration"` - Onhold bool `json:"onhold"` - ReadyTimeout int `json:"readyTimeout"` + MaxVideoDuration int `json:"maxVideoDuration,omitempty"` + Onhold bool `json:"onhold,omitempty"` + ReadyTimeout int `json:"readyTimeout,omitempty"` } type StarterResp struct { @@ -237,7 +237,7 @@ type StarterResp struct { } type StartSuccessResp struct { - CName string `json:"cname"` + Cname string `json:"cname"` UID string `json:"uid"` ResourceId string `json:"resourceId"` SID string `json:"sid"` @@ -276,3 +276,16 @@ func (a *Starter) Do(ctx context.Context, resourceID string, mode string, payloa resp.BaseResponse = responseData return &resp, nil } + +func (a *Starter) DoWebRecording(ctx context.Context, resourceID string, cname string, uid string, clientRequest *StartWebRecordingClientRequest) (*StarterResp, error) { + mode := WebMode + return a.Do(ctx, resourceID, mode, &StartReqBody{ + Cname: cname, + Uid: uid, + ClientRequest: &StartClientRequest{ + RecordingFileConfig: clientRequest.RecordingFileConfig, + StorageConfig: clientRequest.StorageConfig, + ExtensionServiceConfig: clientRequest.ExtensionServiceConfig, + }, + }) +} diff --git a/services/cloudrecording/v1/stop.go b/services/cloudrecording/v1/stop.go index 46aef23..7661d19 100644 --- a/services/cloudrecording/v1/stop.go +++ b/services/cloudrecording/v1/stop.go @@ -8,7 +8,7 @@ import ( "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type Stop struct { @@ -39,6 +39,8 @@ type StopReqBody struct { ClientRequest *StopClientRequest `json:"clientRequest"` } +// StopClientRequest is the request body of stop. +// 当 async_stop 为 true 时,表示异步停止录制。默认值为 false,异步情况下可能会获取不到对应的serverResponse内容 type StopClientRequest struct { AsyncStop bool `json:"async_stop"` } @@ -100,28 +102,54 @@ type StopWebRecordingServerResponse struct { ExtensionServiceState []struct { Payload struct { UploadingStatus string `json:"uploadingStatus"` + FileList []struct { + FileName string `json:"fileName"` + TrackType string `json:"trackType"` + Uid string `json:"uid"` + MixedAllUser bool `json:"mixedAllUser"` + IsPlayable bool `json:"isPlayable"` + SliceStartTime int64 `json:"sliceStartTime"` + } `json:"fileList"` + Onhold bool `json:"onhold"` + State string `json:"state"` } `json:"payload"` ServiceName string `json:"serviceName"` + ExitReason string `json:"exit_reason"` } `json:"extensionServiceState"` } func (s *StopSuccessResp) GetIndividualRecordingServerResponse() *StopIndividualRecordingServerResponse { + if s.individualRecordingServerResponse == nil { + return nil + } return s.individualRecordingServerResponse } func (s *StopSuccessResp) GetIndividualVideoScreenshotServerResponse() *StopIndividualVideoScreenshotServerResponse { + if s.individualVideoScreenshotResponse == nil { + return nil + } return s.individualVideoScreenshotResponse } func (s *StopSuccessResp) GetMixRecordingHLSServerResponse() *StopMixRecordingHLSServerResponse { + if s.mixRecordingHLSServerResponse == nil { + return nil + } return s.mixRecordingHLSServerResponse } func (s *StopSuccessResp) GetMixRecordingHLSAndMP4ServerResponse() *StopMixRecordingHLSAndMP4ServerResponse { + if s.mixRecordingHLSAndMP4ServerResponse == nil { + return nil + } return s.mixRecordingHLSAndMP4ServerResponse } func (s *StopSuccessResp) GetWebRecordingServerResponse() *StopWebRecordingServerResponse { + if s.webRecordingServerResponse == nil { + return nil + } return s.webRecordingServerResponse } func (s *StopSuccessResp) GetServerResponseMode() StopRespServerResponseMode { @@ -182,9 +210,12 @@ func (s *StopSuccessResp) setServerResponse(rawBody []byte, mode string) error { serverResponseMode = StopWebRecordingServerResponseMode serverResponse := gjson.GetBytes(rawBody, "serverResponse") var resp StopWebRecordingServerResponse - if err := json.Unmarshal([]byte(serverResponse.String()), &resp); err != nil { - return err + if serverResponse.Exists() { + if err := json.Unmarshal([]byte(serverResponse.String()), &resp); err != nil { + return err + } } + s.webRecordingServerResponse = &resp default: return errors.New("unknown mode") } diff --git a/services/cloudrecording/v1/update.go b/services/cloudrecording/v1/update.go index 8e0d4ca..e1e3aff 100644 --- a/services/cloudrecording/v1/update.go +++ b/services/cloudrecording/v1/update.go @@ -7,7 +7,7 @@ import ( "github.com/pkg/errors" "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type Update struct { @@ -68,6 +68,8 @@ type UpdateResp struct { type UpdateSuccessResp struct { ResourceId string `json:"resourceId"` SID string `json:"sid"` + UID string `json:"uid"` + Cname string `json:"cname"` } type UpdateServerResponse struct { @@ -112,5 +114,6 @@ func (s *Update) Do(ctx context.Context, resourceID string, sid string, mode str resp.ErrResponse = errResponse } resp.BaseResponse = responseData + return &resp, nil } diff --git a/services/cloudrecording/v1/update_layout.go b/services/cloudrecording/v1/update_layout.go index db493ec..c219e5a 100644 --- a/services/cloudrecording/v1/update_layout.go +++ b/services/cloudrecording/v1/update_layout.go @@ -7,7 +7,7 @@ import ( "github.com/tidwall/gjson" - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) type UpdateLayout struct { diff --git a/services/cloudrecording/v1/v1.go b/services/cloudrecording/v1/v1.go index ad789e0..2f17884 100644 --- a/services/cloudrecording/v1/v1.go +++ b/services/cloudrecording/v1/v1.go @@ -1,59 +1,67 @@ package v1 import ( - "github.com/AgoraIO/agora-rest-client-go/core" + "github.com/AgoraIO-Community/agora-rest-client-go/core" ) -type Collection struct { - prefixPath string - client core.Client +type BaseCollection struct { + prefixPath string + client core.Client + webRecording WebRecording } -func NewCollection(prefixPath string, client core.Client) *Collection { - return &Collection{ - prefixPath: "/v1" + prefixPath, - client: client, +func NewCollection(prefixPath string, client core.Client, webRecording WebRecording) *BaseCollection { + b := &BaseCollection{ + prefixPath: "/v1" + prefixPath, + client: client, + webRecording: webRecording, } + b.webRecording.SetBase(b) + return b } -func (c *Collection) Acquire() *Acquire { +func (c *BaseCollection) Acquire() *Acquire { return &Acquire{ client: c.client, prefixPath: c.prefixPath, } } -func (c *Collection) Start() *Starter { +func (c *BaseCollection) Start() *Starter { return &Starter{ client: c.client, prefixPath: c.prefixPath, } } -func (c *Collection) Stop() *Stop { +func (c *BaseCollection) Stop() *Stop { return &Stop{ client: c.client, prefixPath: c.prefixPath, } } -func (c *Collection) Query() *Query { +func (c *BaseCollection) Query() *Query { return &Query{ client: c.client, prefixPath: c.prefixPath, } } -func (c *Collection) Update() *Update { +func (c *BaseCollection) Update() *Update { return &Update{ client: c.client, prefixPath: c.prefixPath, } } -func (c *Collection) UpdateLayout() *UpdateLayout { +func (c *BaseCollection) UpdateLayout() *UpdateLayout { return &UpdateLayout{ client: c.client, prefixPath: c.prefixPath, } } + +func (c *BaseCollection) WebRecording() WebRecording { + return c.webRecording +} diff --git a/services/cloudrecording/v1/webcording.go b/services/cloudrecording/v1/webcording.go new file mode 100644 index 0000000..09110ed --- /dev/null +++ b/services/cloudrecording/v1/webcording.go @@ -0,0 +1,73 @@ +package v1 + +import ( + "context" +) + +type AcquirerWebRecodingClientRequest struct { + ResourceExpiredHour int `json:"resourceExpiredHour"` + ExcludeResourceIds []string `json:"excludeResourceIds,omitempty"` + RegionAffinity int `json:"regionAffinity,omitempty"` +} + +type AcquireWebRecording interface { + Do(ctx context.Context, cname string, uid string, clientRequest *AcquirerWebRecodingClientRequest) (*AcquirerResp, error) +} + +type QueryWebRecordingResp struct { + Response + SuccessResp QueryWebRecordingSuccessResp +} + +type QueryWebRecordingSuccessResp struct { + ResourceId string + SID string + ServerResponse QueryWebRecordingServerResponse +} +type QueryWebRecording interface { + Do(ctx context.Context, resourceID string, sid string) (*QueryWebRecordingResp, error) +} + +type StartWebRecordingClientRequest struct { + AppsCollection *AppsCollection `json:"appsCollection,omitempty"` + RecordingFileConfig *RecordingFileConfig `json:"recordingFileConfig,omitempty"` + StorageConfig *StorageConfig `json:"storageConfig,omitempty"` + ExtensionServiceConfig *ExtensionServiceConfig `json:"extensionServiceConfig,omitempty"` +} + +type StartWebRecording interface { + Do(ctx context.Context, resourceID string, cname string, uid string, clientRequest *StartWebRecordingClientRequest) (*StarterResp, error) +} + +type StopWebRecordingResp struct { + Response + SuccessResp StopWebRecordingSuccessResp +} + +type StopWebRecordingSuccessResp struct { + ResourceId string + SID string + ServerResponse StopWebRecordingServerResponse +} + +type StopWebRecording interface { + Do(ctx context.Context, resourceID string, sid string, payload *StopReqBody) (*StopWebRecordingResp, error) +} + +type UpdateWebRecordingClientRequest struct { + WebRecordingConfig *UpdateWebRecordingConfig `json:"webRecordingConfig,omitempty"` + RtmpPublishConfig *UpdateRtmpPublishConfig `json:"rtmpPublishConfig,omitempty"` +} + +type UpdateWebRecording interface { + Do(ctx context.Context, resourceID string, sid string, cname string, uid string, clientRequest *UpdateWebRecordingClientRequest) (*UpdateResp, error) +} + +type WebRecording interface { + SetBase(base *BaseCollection) + Acquire() AcquireWebRecording + Query() QueryWebRecording + Start() StartWebRecording + Stop() StopWebRecording + Update() UpdateWebRecording +} diff --git a/services/cloudrecording/v1/webrecording/acquire.go b/services/cloudrecording/v1/webrecording/acquire.go new file mode 100644 index 0000000..0bf369b --- /dev/null +++ b/services/cloudrecording/v1/webrecording/acquire.go @@ -0,0 +1,26 @@ +package webrecording + +import ( + "context" + + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Acquire struct { + BaseAcquire *baseV1.Acquire +} + +var _ baseV1.AcquireWebRecording = (*Acquire)(nil) + +func (a *Acquire) Do(ctx context.Context, cname string, uid string, clientRequest *baseV1.AcquirerWebRecodingClientRequest) (*baseV1.AcquirerResp, error) { + return a.BaseAcquire.Do(ctx, &baseV1.AcquirerReqBody{ + Cname: cname, + Uid: uid, + ClientRequest: &baseV1.AcquirerClientRequest{ + Scene: 1, + ResourceExpiredHour: clientRequest.ResourceExpiredHour, + ExcludeResourceIds: clientRequest.ExcludeResourceIds, + RegionAffinity: clientRequest.RegionAffinity, + }, + }) +} diff --git a/services/cloudrecording/v1/webrecording/query.go b/services/cloudrecording/v1/webrecording/query.go new file mode 100644 index 0000000..7482bf6 --- /dev/null +++ b/services/cloudrecording/v1/webrecording/query.go @@ -0,0 +1,34 @@ +package webrecording + +import ( + "context" + + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Query struct { + BaseQuery *baseV1.Query +} + +var _ baseV1.QueryWebRecording = (*Query)(nil) + +func (q *Query) Do(ctx context.Context, resourceID string, sid string) (*baseV1.QueryWebRecordingResp, error) { + resp, err := q.BaseQuery.Do(ctx, resourceID, sid, baseV1.WebMode) + if err != nil { + return nil, err + } + + var webResp baseV1.QueryWebRecordingResp + + webResp.Response = resp.Response + if resp.IsSuccess() { + successResp := resp.SuccessResp + webResp.SuccessResp = baseV1.QueryWebRecordingSuccessResp{ + ResourceId: successResp.ResourceId, + SID: successResp.SID, + ServerResponse: *successResp.GetWebRecording2CDNServerResponse(), + } + } + + return &webResp, nil +} diff --git a/services/cloudrecording/v1/webrecording/start.go b/services/cloudrecording/v1/webrecording/start.go new file mode 100644 index 0000000..2d0f763 --- /dev/null +++ b/services/cloudrecording/v1/webrecording/start.go @@ -0,0 +1,26 @@ +package webrecording + +import ( + "context" + + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Starter struct { + BaseStarter *baseV1.Starter +} + +var _ baseV1.StartWebRecording = (*Starter)(nil) + +func (s *Starter) Do(ctx context.Context, resourceID string, cname string, uid string, clientRequest *baseV1.StartWebRecordingClientRequest) (*baseV1.StarterResp, error) { + mode := baseV1.WebMode + return s.BaseStarter.Do(ctx, resourceID, mode, &baseV1.StartReqBody{ + Cname: cname, + Uid: uid, + ClientRequest: &baseV1.StartClientRequest{ + RecordingFileConfig: clientRequest.RecordingFileConfig, + StorageConfig: clientRequest.StorageConfig, + ExtensionServiceConfig: clientRequest.ExtensionServiceConfig, + }, + }) +} diff --git a/services/cloudrecording/v1/webrecording/stop.go b/services/cloudrecording/v1/webrecording/stop.go new file mode 100644 index 0000000..2e93d3f --- /dev/null +++ b/services/cloudrecording/v1/webrecording/stop.go @@ -0,0 +1,35 @@ +package webrecording + +import ( + "context" + + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Stop struct { + BaseStop *baseV1.Stop +} + +var _ baseV1.StopWebRecording = (*Stop)(nil) + +func (s *Stop) Do(ctx context.Context, resourceID string, sid string, payload *baseV1.StopReqBody) (*baseV1.StopWebRecordingResp, error) { + mode := baseV1.WebMode + resp, err := s.BaseStop.Do(ctx, resourceID, sid, mode, payload) + if err != nil { + return nil, err + } + + var webResp baseV1.StopWebRecordingResp + + webResp.Response = resp.Response + if resp.IsSuccess() { + successResp := resp.SuccessResp + webResp.SuccessResp = baseV1.StopWebRecordingSuccessResp{ + ResourceId: successResp.ResourceId, + SID: successResp.SID, + ServerResponse: *successResp.GetWebRecordingServerResponse(), + } + } + + return &webResp, nil +} diff --git a/services/cloudrecording/v1/webrecording/update.go b/services/cloudrecording/v1/webrecording/update.go new file mode 100644 index 0000000..03fd1ad --- /dev/null +++ b/services/cloudrecording/v1/webrecording/update.go @@ -0,0 +1,24 @@ +package webrecording + +import ( + "context" + + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Update struct { + BaseUpdate *baseV1.Update +} + +var _ baseV1.UpdateWebRecording = (*Update)(nil) + +func (s *Update) Do(ctx context.Context, resourceID string, sid string, cname string, uid string, clientRequest *baseV1.UpdateWebRecordingClientRequest) (*baseV1.UpdateResp, error) { + return s.BaseUpdate.Do(ctx, resourceID, sid, baseV1.WebMode, &baseV1.UpdateReqBody{ + Cname: cname, + Uid: uid, + ClientRequest: &baseV1.UpdateClientRequest{ + WebRecordingConfig: clientRequest.WebRecordingConfig, + RtmpPublishConfig: clientRequest.RtmpPublishConfig, + }, + }) +} diff --git a/services/cloudrecording/v1/webrecording/webrecording.go b/services/cloudrecording/v1/webrecording/webrecording.go new file mode 100644 index 0000000..d785766 --- /dev/null +++ b/services/cloudrecording/v1/webrecording/webrecording.go @@ -0,0 +1,39 @@ +package webrecording + +import ( + baseV1 "github.com/AgoraIO-Community/agora-rest-client-go/services/cloudrecording/v1" +) + +type Impl struct { + Base *baseV1.BaseCollection +} + +func NewWebRecording() *Impl { + return &Impl{} +} + +var _ baseV1.WebRecording = (*Impl)(nil) + +func (w *Impl) SetBase(base *baseV1.BaseCollection) { + w.Base = base +} + +func (w *Impl) Acquire() baseV1.AcquireWebRecording { + return &Acquire{BaseAcquire: w.Base.Acquire()} +} + +func (w *Impl) Query() baseV1.QueryWebRecording { + return &Query{BaseQuery: w.Base.Query()} +} + +func (w *Impl) Start() baseV1.StartWebRecording { + return &Starter{BaseStarter: w.Base.Start()} +} + +func (w *Impl) Stop() baseV1.StopWebRecording { + return &Stop{BaseStop: w.Base.Stop()} +} + +func (w *Impl) Update() baseV1.UpdateWebRecording { + return &Update{BaseUpdate: w.Base.Update()} +}