Demo for virtual studio

Updated at:

A complete, runnable demo for managing a virtual studio by calling ApsaraVideo Live API operations.

API workflow

Sample code

Note
  • Create a production studio

    // Create a production studio.
    func CreateCaster(liveClient *live20161101.Client) (*live20161101.CreateCasterResponse, error) {
    	// The request parameters for creating a production studio.
    	createCasterRequest := &live20161101.CreateCasterRequest{}
    	createCasterRequest.ClientToken = tea.String(uuid.New().String())
    	createCasterRequest.CasterName = tea.String("Production studio for testing")
    	createCasterRequest.ChargeType = tea.String("PostPaid")
    	createCasterRequest.NormType = tea.Int32(1)
    	createCasterResponse, err := liveClient.CreateCaster(createCasterRequest)
    	if err != nil {
    		return nil, errors.New("CreateCaster failed: " + err.Error())
    	}
    	return createCasterResponse, nil
    }

    For request parameters, see CreateCaster.

  • Configure the production studio

    // Configure the production studio.
    func SetCasterConfig(liveClient *live20161101.Client, casterId *string, domainName *string) (*live20161101.SetCasterConfigResponse, error) {
    	// The parameters for configuring the production studio.
    	createSetCasterConfig := &live20161101.SetCasterConfigRequest{}
    	createSetCasterConfig.CasterId = casterId
    	createSetCasterConfig.CasterName = tea.String("Production studio for testing")
    	createSetCasterConfig.ChannelEnable = tea.Int32(1)
    	createSetCasterConfig.Delay = tea.Float32(0)
    	createSetCasterConfig.DomainName = domainName
    	createSetCasterConfig.ProgramEffect = tea.Int32(1)
    	createSetCasterConfig.ProgramName = tea.String("test loop play")
    	// Transcoding settings (screen orientation and definition).
    	// The CasterTemplate parameter can be set to the following values: lp_ld (low definition), lp_sd (standard definition), lp_hd (high definition), or lp_ud (ultra-high definition). lp_ld_v (low definition in portrait mode), lp_sd_v (standard definition in portrait mode), lp_hd_v (high definition in portrait mode), or lp_ud_v (ultra-high definition in portrait mode).
    	createSetCasterConfig.TranscodeConfig = tea.String(`{"CasterTemplate": "lp_ld"}`)
    	// Configure the recording parameters for the production studio. For more information about the JSON fields, see AddLiveAppRecordConfig.
    	// createSetCasterConfig.RecordConfig = tea.String(`{ "endpoint": "", "ossBucket": "", "videoFormat": [{"format": "flv", "interval": 900, "prefix":"record/{AppName}/{StreamName}/{StartTime}_{EndTime}" }]}`)
    	setCasterConfigResponse, err := liveClient.SetCasterConfig(createSetCasterConfig)
    	if err != nil {
    		return nil, errors.New("SetCasterConfig failed: " + err.Error())
    	}
    	return setCasterConfigResponse, nil
    }

    For parameter details, see Configure a production studio.

  • Add a video resource

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      addCasterVideoResourceRequest := &live20161101.AddCasterVideoResourceRequest{
        RegionId: tea.String("<Your RegionId>"),
        CasterId: tea.String("<Your CasterId>"),
        ResourceName: tea.String("<Your ResourceName>"),
        LiveStreamUrl: tea.String("<Your LiveStreamUrl>"),
        MaterialId: tea.String("<Your MaterialId>"),
        VodUrl: tea.String("<Your VodUrl>"),
        ImageId: tea.String("<Your ImageId>"),
        ImageUrl: tea.String("<Your ImageUrl>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.AddCasterVideoResourceWithOptions(addCasterVideoResourceRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For parameter details, see AddCasterVideoResource.

  • Add a virtual studio layout

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      addStudioLayoutRequest := &live20161101.AddStudioLayoutRequest{
        RegionId: tea.String("<Your RegionId>"),
        CasterId: tea.String("<Your CasterId>"),
        LayoutName: tea.String("<Your LayoutName>"),
        LayoutType: tea.String("<Your LayoutType>"),
        CommonConfig: tea.String("<Your CommonConfig>"),
        BgImageConfig: tea.String("<Your BgImageConfig>"),
        ScreenInputConfigList: tea.String("<Your ScreenInputConfigList>"),
        MediaInputConfigList: tea.String("<Your MediaInputConfigList>"),
        LayerOrderConfigList: tea.String("<Your LayerOrderConfigList>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.AddStudioLayoutWithOptions(addStudioLayoutRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For more information about the AddStudioLayout operation, see AddStudioLayout.

  • Start the production studio and set the playback scene

    package caster
    
    import (
    	"github.com/aliyun/alibaba-cloud-sdk-go/services/live"
    	"github.com/go-ini/ini"
    	"testing"
    	"time"
    )
    
    // Start the production studio and set the playback scenes.
    func StartCaster(t *testing.T) {
    	cfg, err := ini.Load("conf/config.ini")
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	// An AccessKey pair of an Alibaba Cloud account has permissions to call all API operations. We recommend that you use a RAM user to call API operations or perform O&M.
      // Do not hard-code the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources in your account may be compromised.
      // In this example, the AccessKey pair is read from a configuration file for identity verification. For more information about how to configure the file, see ApsaraVideo Live > Development Reference > SDK Reference > Server-side SDKs > Go SDK.
    	accessKeyID := cfg.Section("").Key("access_key_id").String()
    	accessKeySecret := cfg.Section("").Key("access_key_secret").String()
    	liveClient, err := live.NewClientWithAccessKey("cn-shanghai", accessKeyID, accessKeySecret)
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	// Start the production studio.
    	startCasterRequest := live.CreateStartCasterRequest()
    	startCasterRequest.CasterId = "xxx"
    	startCasterResp, err := liveClient.StartCaster(startCasterRequest)
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	// Pause the process for a moment. It takes time to load resources. If you start the production studio immediately, the resources may fail to be loaded.
    	time.Sleep(time.Second)
    
    	// Set the playback scenes.
    	// PVW (Optional)
    	setCasterSceneConfigRequest := live.CreateSetCasterSceneConfigRequest()
    	setCasterSceneConfigRequest.LayoutId = "xxx"
    	setCasterSceneConfigRequest.CasterId = "xxx"
    	setCasterSceneConfigRequest.SceneId = startCasterResp.PvwSceneInfos.SceneInfo[0].SceneId
    	_, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
    	if err != nil {
    		t.Fatal(err)
    	}
    	// PGM (Required)
    	setCasterSceneConfigRequest.SceneId = startCasterResp.PgmSceneInfos.SceneInfo[0].SceneId
    	_, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
    	if err != nil {
    		t.Fatal(err)
    	}
    }

    For the StartCaster API reference, see StartCaster.

    For the SetCasterSceneConfig API reference, see SetCasterSceneConfig.

  • Update the scene configuration of the production studio

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials.
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      updateCasterSceneConfigRequest := &live20161101.UpdateCasterSceneConfigRequest{
        RegionId: tea.String("<Your RegionId>"),
        ComponentId: []*string{tea.String("")},
        CasterId: tea.String("<Your CasterId>"),
        SceneId: tea.String("<Your SceneId>"),
        LayoutId: tea.String("<Your LayoutId>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.UpdateCasterSceneConfigWithOptions(updateCasterSceneConfigRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For more information about the request parameters for the UpdateCasterSceneConfig operation, see UpdateCasterSceneConfig.

  • Stop the production studio

    // Stop the production studio.
    func StopCaster(liveClient *live20161101.Client, casterId *string) error {
    	stopCasterRequest := &live20161101.StopCasterRequest{
    		CasterId: casterId,
    	}
    	_, err := liveClient.StopCaster(stopCasterRequest)
    	if err != nil {
    		return errors.New("StopCaster failed: " + err.Error())
    	}
    	return nil
    }

    For the StopCaster API reference, see StopCaster.

  • Delete a virtual studio layout

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      deleteStudioLayoutRequest := &live20161101.DeleteStudioLayoutRequest{
        RegionId: tea.String("<Your RegionId>"),
        CasterId: tea.String("<Your CasterId>"),
        LayoutId: tea.String("<Your LayoutId>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.DeleteStudioLayoutWithOptions(deleteStudioLayoutRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For more information about the DeleteStudioLayout operation, see DeleteStudioLayout.

  • Delete the production studio

    // Delete the production studio.
    func DeleteCaster(liveClient *live20161101.Client, casterId *string) error {
    	deleteCasterRequest := &live20161101.DeleteCasterRequest{
    		CasterId: casterId,
    	}
    	_, err := liveClient.DeleteCaster(deleteCasterRequest)
    	if err != nil {
    		return errors.New("DeleteCaster failed: " + err.Error())
    	}
    	return nil
    }

    For the DeleteCaster API reference, see DeleteCaster.

  • Modify a virtual studio layout

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      modifyStudioLayoutRequest := &live20161101.ModifyStudioLayoutRequest{
        RegionId: tea.String("<Your RegionId>"),
        CasterId: tea.String("<Your CasterId>"),
        LayoutId: tea.String("<Your LayoutId>"),
        LayoutName: tea.String("<Your LayoutName>"),
        CommonConfig: tea.String("<Your CommonConfig>"),
        BgImageConfig: tea.String("<Your BgImageConfig>"),
        ScreenInputConfigList: tea.String("<Your ScreenInputConfigList>"),
        MediaInputConfigList: tea.String("<Your MediaInputConfigList>"),
        LayerOrderConfigList: tea.String("<Your LayerOrderConfigList>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.ModifyStudioLayoutWithOptions(modifyStudioLayoutRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For more information about the ModifyStudioLayout operation, see ModifyStudioLayout.

  • Query virtual studio layouts

    // This file is auto-generated, don't edit it. Thanks.
    package main
    
    import (
      "encoding/json"
      "strings"
      "fmt"
      "os"
      live20161101  "github.com/alibabacloud-go/live-20161101/v2/client"
      openapi  "github.com/alibabacloud-go/darabonba-openapi/v2/client"
      util  "github.com/alibabacloud-go/tea-utils/v2/service"
      credential  "github.com/aliyun/credentials-go/credentials"
      "github.com/alibabacloud-go/tea/tea"
    )
    
    
    // Description:
    // 
    // Use a credential to initialize a client.
    // 
    // @return Client
    // 
    // @throws Exception
    func CreateClient () (_result *live20161101.Client, _err error) {
      // We recommend that you use a credential-free method in your project for better security. For more information about how to configure credentials, see https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-go-access-credentials
      credential, _err := credential.NewCredential(nil)
      if _err != nil {
        return _result, _err
      }
    
      config := &openapi.Config{
        Credential: credential,
      }
      // For more information about endpoints, see https://api.alibabacloud.com/product/live.
      config.Endpoint = tea.String("live.aliyuncs.com")
      _result = &live20161101.Client{}
      _result, _err = live20161101.NewClient(config)
      return _result, _err
    }
    
    func _main (args []*string) (_err error) {
      client, _err := CreateClient()
      if _err != nil {
        return _err
      }
    
      describeStudioLayoutsRequest := &live20161101.DescribeStudioLayoutsRequest{
        RegionId: tea.String("<Your RegionId>"),
      }
      runtime := &util.RuntimeOptions{}
      tryErr := func()(_e error) {
        defer func() {
          if r := tea.Recover(recover()); r != nil {
            _e = r
          }
        }()
        // If you copy the code to run it, print the return value of the API operation.
        _, _err = client.DescribeStudioLayoutsWithOptions(describeStudioLayoutsRequest, runtime)
        if _err != nil {
          return _err
        }
    
        return nil
      }()
    
      if tryErr != nil {
        var error = &tea.SDKError{}
        if _t, ok := tryErr.(*tea.SDKError); ok {
          error = _t
        } else {
          error.Message = tea.String(tryErr.Error())
        }
        // This is for demonstration purposes only. Handle exceptions with caution. Do not ignore exceptions in your projects.
        // Error message
        fmt.Println(tea.StringValue(error.Message))
        // Diagnostic address
        var data interface{}
        d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
        d.Decode(&data)
        if m, ok := data.(map[string]interface{}); ok {
          recommend, _ := m["Recommend"]
          fmt.Println(recommend)
        }
        _, _err = util.AssertAsString(error.Message)
        if _err != nil {
          return _err
        }
      }
      return _err
    }
    
    
    func main() {
      err := _main(tea.StringSlice(os.Args[1:]))
      if err != nil {
        panic(err)
      }
    }

    For more information about the DescribeStudioLayouts operation, see DescribeStudioLayouts.