本文提供了直接调用虚拟演播厅OpenAPI的Demo,具体逻辑请根据实际情况自行编写。

虚拟演播厅调用流程

示例代码

说明 了解API的详细信息,请参见云导播API概览
  • 创建导播台
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        uuid "github.com/satori/go.uuid"
        "testing"
    )
    
    // 创建导播台
    func CreateCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // 创建导播台请求参数
        createCasterRequest := live.CreateCreateCasterRequest()
        createCasterRequest.ClientToken = uuid.NewV1().String()
        createCasterRequest.CasterName = "导播台测试" // 不生效的话,请通过接口【设置导播台】来设置
        createCasterRequest.ChargeType = "PostPaid"
        createCasterRequest.NormType = "4"
        _, err = liveClient.CreateCaster(createCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于CreateCaster接口的请求参数等更多信息,请参见创建导播台

  • 设置导播台
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // 设置导播台
    func SetCasterConfig(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // 设置导播台配置参数
        createSetCasterConfig := live.CreateSetCasterConfigRequest()
        createSetCasterConfig.CasterId = "xxxxxx"
        createSetCasterConfig.CasterName = "导播台测试"
        createSetCasterConfig.ChannelEnable = "1"
        createSetCasterConfig.Delay = "0"
        createSetCasterConfig.DomainName = "xxxxxxxx"
        createSetCasterConfig.ProgramEffect = "1"
        createSetCasterConfig.ProgramName = "test loop play"
        // 转码设置(横竖屏模式及清晰度设置)
        // 参考如下文档:SetCasterConfig
        // 其中:CasterTemplate取值范围如下
        // lp_ld:流畅、lp_sd:标清、lp_hd:高清、lp_ud:超清。
        // lp_ld_v:竖屏流畅、lp_sd_v:竖屏标清、lp_hd_v:竖屏高清、lp_ud_v:竖屏超清。
        createSetCasterConfig.TranscodeConfig = `{"CasterTemplate": "lp_ld"}`
        // 录制
        // json字段含义请参考:AddLiveAppRecordConfig
        createSetCasterConfig.RecordConfig = fmt.Sprintf(`{ "endpoint": "oss-cn-shanghai.aliyuncs.com", "ossBucket": "test-record", "videoFormat": [{"format": "flv", "interval": 900, "prefix":"record/{AppName}/{StreamName}/{StartTime}_{EndTime}" }]}`)
        _, err = liveClient.SetCasterConfig(createSetCasterConfig)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于SetCasterConfig接口的更多信息,请参见配置导播台

  • 添加视频资源
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // 添加资源
    func AddCasterVideoResource(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // 创建导播台视频资源
        addCasterVideoResourceRequest := live.CreateAddCasterVideoResourceRequest()
        addCasterVideoResourceRequest.CasterId = "xxxx"
        addCasterVideoResourceRequest.ResourceName = "测试使用视频资源"
        addCasterVideoResourceRequest.LiveStreamUrl = "xxxxxxxxxxxx"
        addCasterVideoResourceRequest.PtsCallbackInterval = "1000"
        addCasterVideoResourceResp, err := liveClient.AddCasterVideoResource(addCasterVideoResourceRequest)
        if err != nil {
            t.Fatal(err)
        }
        resourceID := addCasterVideoResourceResp.ResourceId
    
        // 视频资源与通道一一绑定
        setCasterChannelRequest := live.CreateSetCasterChannelRequest()
        setCasterChannelRequest.CasterId = "xxx"
        setCasterChannelRequest.PlayStatus = "1"
        setCasterChannelRequest.ChannelId = "RV01"
        setCasterChannelRequest.ResourceId = resourceID
        _, err = liveClient.SetCasterChannel(setCasterChannelRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于AddCasterVideoResource接口的更多信息,请参见添加导播台视频资源

  • 添加虚拟演播厅布局
    func TestAddStudioLayout(t *testing.T) {
       studioClient, err := client.NewClient(&openapi.Config{
          AccessKeyId:     tea.String("xxxx"),
          AccessKeySecret: tea.String("xxxx"),
          RegionId:        tea.String("cn-shanghai"),
       })
       if err != nil {
          t.Fatal(err)
       }
    
       rsp, err := studioClient.AddStudioLayout(&client.AddStudioLayoutRequest{
            // 导播台ID,必须是虚拟演播厅类型的
            CasterId: tea.String("xxxx"),
            // 布局名称
            LayoutName: tea.String("绿幕"),
            // 布局类型:common、studio
            LayoutType: tea.String("studio"),
            // 通用布局配置。格式为JSON字符串,当请求参数LayoutType取值为common时,本参数才必填。
            //CommonConfig: tea.String(`{"ChannelId":"RV01" }`),
            // 背景资源配置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填。
            BgImageConfig: tea.String(fmt.Sprintf(`
                { "Id":"k12kj31kj23", "ImageUrl":"", "MaterialId":"xxxx" }
            `)),
            // 抠像输入设置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填
            ScreenInputConfigList: tea.String(fmt.Sprintf(`
                [{ "Index":"1", "ChannelId":"RV01", "Color":"green", "PositionX":"0.1", "PositionY":"0.2", "HeightNormalized":"0.4" } ]
            `)),
            // 多媒体输入资源设置。格式为JSON字符串,当请求参数LayoutType取值为studio时,本参数才有效,且为选填。
            MediaInputConfigList: tea.String(fmt.Sprintf(`[{ "Id":"k12kj31****", "Index":"1", "ChannelId":"RV07", "FillMode":"none", "PositionRefer":"topLeft", "WidthNormalized":"0", "HeightNormalized":"0.4854", "PositionNormalized":"[0.3691, 0.1958]" }]`)),
            // 图层顺序设置。格式为JSON字符串,支持背景素材、多媒体素材排序,暂不支持抠像层。越排在前面,越在底层。
            LayerOrderConfigList: tea.String(fmt.Sprintf(`[{ "Type":"background", "Id":"k12kj31kj23" }, { "Type":"media", "Id":"k12kj31****" }]`)),
        })
        if err != nil {
            t.Fatal(err)
        }
        println(fmt.Sprintf("%+v", rsp))
    }

    关于AddStudioLayout接口的更多信息,请参见添加虚拟演播厅布局

  • 启动导播台、设置播放场景
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
        "time"
    )
    
    // 启动导播台、设置播放场景
    func StartCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // 启动导播台
        startCasterRequest := live.CreateStartCasterRequest()
        startCasterRequest.CasterId = "xxx"
        startCasterResp, err := liveClient.StartCaster(startCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    
        // 因为资源加载需要时间,如果立马启动,则可能资源尚未加载成功,所以需要暂停一下
        time.Sleep(time.Second)
    
        // 设置播放场景
        // PVW (可选设置)
        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 (必选设置)
        setCasterSceneConfigRequest.SceneId = startCasterResp.PgmSceneInfos.SceneInfo[0].SceneId
        _, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于StartCaster接口的更多信息,请参见启动导播台

    关于SetCasterSceneConfig接口的更多信息,请参见设置场景配置

  • 更新导播台场景配置
    func TestUpdateCasterSceneConfig(t *testing.T) {
       studioClient, err := client.NewClient(&openapi.Config{
          AccessKeyId:     tea.String("xxxx"),
          AccessKeySecret: tea.String("xxxx"),
          RegionId:        tea.String("cn-shanghai"),
       })
       if err != nil {
          t.Fatal(err)
       }
       rsp, err := studioClient.UpdateCasterSceneConfig(&client.UpdateCasterSceneConfigRequest{
          CasterId: tea.String("xxxx"),
          SceneId:  tea.String("xxxx"),
          LayoutId: tea.String("xxxx"),
       })
       if err != nil {
          t.Fatal(err)
       }
       println(fmt.Sprintf("%+v", rsp))
    }

    关于UpdateCasterSceneConfig接口的请求参数等更多信息,请参见更新导播场景配置

  • 停止导播台
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    // 停止导播台
    func StopCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("", "", "")
        if err != nil {
            t.Fatal(err)
        }
        // 停止导播台
        stopCasterRequest := live.CreateStopCasterRequest()
        stopCasterRequest.CasterId = "xxxx"
        _, err = liveClient.StopCaster(stopCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于StopCaster接口的更多信息,请参见停止导播台

  • 删除虚拟演播厅布局
    func TestModifyStudioLayout(t *testing.T) {
       studioClient, err := client.NewClient(&openapi.Config{
          AccessKeyId:     tea.String("xxxx"),
          AccessKeySecret: tea.String("xxxx"),
          RegionId:        tea.String("cn-shanghai"),
       })
       if err != nil {
          t.Fatal(err)
       }
    
       rsp, err := studioClient.ModifyStudioLayout(&client.ModifyStudioLayoutRequest{
            // 导播台ID,必须是虚拟演播厅类型的
            CasterId:   tea.String("xxxx"),
            LayoutId:   tea.String("xxxx"),
            LayoutName: tea.String("modify"),
            // 通用布局配置。格式为JSON字符串,当请求参数LayoutType取值为common时,本参数才必填。
            //CommonConfig: tea.String(`{"ChannelId":"RV01" }`),
            // 背景资源配置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填。
            BgImageConfig: tea.String(fmt.Sprintf(`
                { "Id":"k12kj31kj23", "ImageUrl":"https://xxxxx_!!6000000005962-2-tps-1920-1080.png", "MaterialId":"" }
            `)),
            // 抠像输入设置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填
            ScreenInputConfigList: tea.String(fmt.Sprintf(`
                [{ "Index":"1", "ChannelId":"RV01", "Color":"green", "PositionX":"0.1", "PositionY":"0.2", "HeightNormalized":"0.4" } ]
            `)),
            // 多媒体输入资源设置。格式为JSON字符串,当请求参数LayoutType取值为studio时,本参数才有效,且为选填。
            MediaInputConfigList: tea.String(fmt.Sprintf(`[{ "Id":"k12kj31****", "Index":"1", "ChannelId":"RV08", "FillMode":"none", "PositionRefer":"topLeft", "WidthNormalized":"0", "HeightNormalized":"0.4854", "PositionNormalized":"[0.3691, 0.1958]" }]`)),
            // 图层顺序设置。格式为JSON字符串,支持背景素材、多媒体素材排序,暂不支持抠像层。越排在前面,越在底层。
            LayerOrderConfigList: tea.String(fmt.Sprintf(`[{ "Type":"background", "Id":"k12kj31kj23" }, { "Type":"media", "Id":"k12kj31****" }]`)),
        })
        if err != nil {
            t.Fatal(err)
        }
        println(fmt.Sprintf("%+v", rsp))
    }

    关于DeleteStudioLayout接口的更多信息,请参见删除虚拟演播厅布局

  • 删除导播台
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    // 停止并删除导播台
    func DeleteCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("", "", "")
        if err != nil {
            t.Fatal(err)
        }
        // 删除导播台
        deleteCasterRequest := live.CreateDeleteCasterRequest()
        deleteCasterRequest.CasterId = "xxxxxxx"
        _, err = liveClient.DeleteCaster(deleteCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    关于DeleteCaster接口的更多信息,请参见删除导播台

  • 修改虚拟演播厅布局
    func TestModifyStudioLayout(t *testing.T) {
       studioClient, err := client.NewClient(&openapi.Config{
          AccessKeyId:     tea.String("xxxx"),
          AccessKeySecret: tea.String("xxxx"),
          RegionId:        tea.String("cn-shanghai"),
       })
       if err != nil {
          t.Fatal(err)
       }
    
       rsp, err := studioClient.ModifyStudioLayout(&client.ModifyStudioLayoutRequest{
            // 导播台ID,必须是虚拟演播厅类型的
            CasterId:   tea.String("xxxx"),
            LayoutId:   tea.String("xxxx"),
            LayoutName: tea.String("modify"),
            // 通用布局配置。格式为JSON字符串,当请求参数LayoutType取值为common时,本参数才必填。
            //CommonConfig: tea.String(`{"ChannelId":"RV01" }`),
            // 背景资源配置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填。
            BgImageConfig: tea.String(fmt.Sprintf(`
                { "Id":"k12kj31kj23", "ImageUrl":"https://xxxxx_!!6000000005962-2-tps-1920-1080.png", "MaterialId":"" }
            `)),
            // 抠像输入设置。格式为JSON字符串, 当请求参数LayoutType取值为studio时,本参数才必填
            ScreenInputConfigList: tea.String(fmt.Sprintf(`
                [{ "Index":"1", "ChannelId":"RV01", "Color":"green", "PositionX":"0.1", "PositionY":"0.2", "HeightNormalized":"0.4" } ]
            `)),
            // 多媒体输入资源设置。格式为JSON字符串,当请求参数LayoutType取值为studio时,本参数才有效,且为选填。
            MediaInputConfigList: tea.String(fmt.Sprintf(`[{ "Id":"k12kj31****", "Index":"1", "ChannelId":"RV08", "FillMode":"none", "PositionRefer":"topLeft", "WidthNormalized":"0", "HeightNormalized":"0.4854", "PositionNormalized":"[0.3691, 0.1958]" }]`)),
            // 图层顺序设置。格式为JSON字符串,支持背景素材、多媒体素材排序,暂不支持抠像层。越排在前面,越在底层。
            LayerOrderConfigList: tea.String(fmt.Sprintf(`[{ "Type":"background", "Id":"k12kj31kj23" }, { "Type":"media", "Id":"k12kj31****" }]`)),
        })
        if err != nil {
            t.Fatal(err)
        }
        println(fmt.Sprintf("%+v", rsp))
    }

    关于ModifyStudioLayout接口的相关信息,请参见修改虚拟演播厅布局

  • 查询虚拟演播厅布局
    func TestDescribeStudioLayouts(t *testing.T) {
       studioClient, err := client.NewClient(&openapi.Config{
          AccessKeyId:     tea.String("xxxx"),
          AccessKeySecret: tea.String("xxxx"),
          RegionId:        tea.String("cn-shanghai"),
       })
       if err != nil {
          t.Fatal(err)
       }
    
       rsp, err := studioClient.DescribeStudioLayouts(&client.DescribeStudioLayoutsRequest{
            CasterId: tea.String("xxxx"),
            // 布局ID, 多个布局ID用英文逗号(,)隔开,不填则返回该导播台下所有布局。
            //LayoutId: tea.String("xxxx"),
        })
        if err != nil {
            t.Fatal(err)
        }
        println(fmt.Sprintf("%+v", rsp))
    }

    关于DescribeStudioLayouts接口的相关信息,请参见接口的相关信息,请参见查询虚拟演播厅布局