This topic describes the sample code that is provided by OpenAPI Explorer to call the API operations that are related to the production studio service. You can write code to encapsulate your call logic as needed.

Process of using a production studio

The following steps constitute the process of using a production studio:
  1. Create a production studio
  2. Set the production studio
  3. Add a video source
  4. Add a layout
  5. Optional. Add a component

    You can add components as needed to apply real-time subtitles, logo images, and banner text to video sources.

  6. Start the production studio
  7. Set the playback scenes
  8. Stop the production studio
  9. Delete the production studio

Sample code

Note For more information about the API operations, see API.

The sample code in this topic is written in Go.

  • Create a production studio
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        uuid "github.com/satori/go.uuid"
        "testing"
    )
    
    // Create a production studio.
    func CreateCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // Set the request parameters for creating a production studio.
        createCasterRequest := live.CreateCreateCasterRequest()
        createCasterRequest.ClientToken = uuid.NewV1().String()
        createCasterRequest.CasterName = "Production Studio for Testing" // If the setting does not take effect, specify this parameter by calling the SetCasterConfig operation.
        createCasterRequest.ChargeType = "PostPaid"
        createCasterRequest.NormType = "1"
        _, err = liveClient.CreateCaster(createCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the request parameters of the CreateCaster operation, see CreateCaster.

  • Set the production studio
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // Set the production studio.
    func SetCasterConfig(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // Set the request parameters for setting the production studio.
        createSetCasterConfig := live.CreateSetCasterConfigRequest()
        createSetCasterConfig.CasterId = "xxxxxx"
        createSetCasterConfig.CasterName = "Production Studio for Testing"
        createSetCasterConfig.ChannelEnable = "1"
        createSetCasterConfig.Delay = "0"
        createSetCasterConfig.DomainName = "xxxxxxxx"
        createSetCasterConfig.ProgramEffect = "1"
        createSetCasterConfig.ProgramName = "test loop play"
        // Configure the transcoding settings. You can specify the screen rotation and resolution of videos.
        // References:SetCasterConfig
        // CasterTemplate: the transcoding settings of the production studio. Valid values:
        // The value of lp_ld, lp_sd, lp_hd, or lp_ud indicates that the transcoded videos are in low definition, standard definition, high definition, or ultra-high definition. 
        // The value of lp_ld_v, lp_sd_v, lp_hd_v, or lp_ud_v indicates that the transcoded videos are in low definition, standard definition, high definition, or ultra-high definition in portrait mode. 
        createSetCasterConfig.TranscodeConfig = `{"CasterTemplate": "lp_ld"}`
        // Configure the recording settings.
        // For more information about JSON field, see the description of the AddLiveAppRecordConfig operation at 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)
        }
    }

    For more information about the SetCasterConfig operation, see SetCasterConfig.

  • Add a video source and specify a channel for the video source
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // Add a video source.
    func AddCasterVideoResource(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // Add a video source to the production studio.
        addCasterVideoResourceRequest := live.CreateAddCasterVideoResourceRequest()
        addCasterVideoResourceRequest.CasterId = "xxxx"
        addCasterVideoResourceRequest.ResourceName = "Video Source for Testing"
        addCasterVideoResourceRequest.LiveStreamUrl = "xxxxxxxxxxxx"
        addCasterVideoResourceRequest.PtsCallbackInterval = "1000"
        addCasterVideoResourceResp, err := liveClient.AddCasterVideoResource(addCasterVideoResourceRequest)
        if err != nil {
            t.Fatal(err)
        }
        resourceID := addCasterVideoResourceResp.ResourceId
    
        // Specify a channel for the vide source.
        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)
        }
    }

    For more information about the AddCasterVideoResource operation, see AddCasterVideoResource.

  • Add a layout
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // Add a layout for the production studio.
    func AddCasterLayout(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // Add a layout for the production studio.
        addCasterLayoutRequest := live.CreateAddCasterLayoutRequest()
        addCasterLayoutRequest.CasterId = "xxx"
        addCasterLayoutRequest.BlendList = &[]string{"RV01"} // The location ID of the video layer.
        addCasterLayoutRequest.MixList = &[]string{"RV01"} // The location ID of the audio layer.
        addCasterLayoutRequest.AudioLayer = &[]live.AddCasterLayoutAudioLayer{
            {
                VolumeRate:         "1",
                ValidChannel:       "all",
                FixedDelayDuration: "0",
            },
        }
        addCasterLayoutRequest.VideoLayer = &[]live.AddCasterLayoutVideoLayer{
            {
                FillMode:           "fit",
                HeightNormalized:   "1",
                WidthNormalized:    "1",
                PositionRefer:      "topLeft",
                PositionNormalized: &[]string{"0", "0"},
                FixedDelayDuration: "0",
            },
        }
        _, err = liveClient.AddCasterLayout(addCasterLayoutRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the AddCasterLayout operation, see AddCasterLayout.

  • Add a real-time subtitle component and apply the component to a playback scene
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    
    // Add a real-time subtitle component and apply the component to a playback scene.
    func AddETComponent(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
        // Before you apply a real-time subtitle component, make sure that the following conditions are met: A production studio is created. A live stream is added to the production studio as a video source. The locationID parameter is set to RV01 for the video source.
        // Note: Real-time subtitle components are available only for live streams.
        casterID := "xxxxx"
        // Add a component.
        r := live.CreateAddCasterComponentRequest()
        r.CasterId = casterID
        r.ComponentType = "caption"
        r.ComponentName = "Real-time Subtitles for Testing"
        r.Effect = "none"
        r.LocationId = "RC01"
        r.ComponentLayer = `{"HeightNormalized":"1","WidthNormalized":"1","PositionRefer":"topLeft","PositionNormalized":["0.05", "0.7"]}`
        // For more information about the subtitle settings, see the CaptionLayerContent parameter of the AddCasterComponent operation at AddCasterComponent.
        // The sample code involves the following fields that are not described in related documents on the International site (alibabacloud.com):
        // BoxWidthNormalized: the normalized value of the background width of the text. The value of this field equals the background width divided by the font size. The maximum background width is 16, even if the background width calculated based on this field is greater than 16. Default value: 0. 
        // BoxColor: the color of the text background. The value is in the 0xRGBA format. The value of 0xff0000ff indicates that the text background is non-transparent and in red. By default, this field is left empty. In this case, the setting does not take effect. 
        // ShadowxWidthNormalized: the normalized value of the X-coordinate of the text shadow. The value of this field equals the X-coordinate divided by the font size. The maximum X-coordinate is 16, even if the X-coordinate calculated based on this field is greater than 16. Default value: 0. 
        // ShadowyWidthNormalized: the normalized value of the Y-coordinate of the text shadow. The value of this field equals the Y-coordinate divided by the font size. The maximum Y-coordinate is 16, even if the Y-coordinate calculated based on this field is greater than 16. Default value: 0. 
        // ShadowColor: the color of the text shadow. The value is in the 0xRGBA format. The value of 0xff0000ff indicates that the text shadow is non-transparent and in red. By default, this field is left empty. In this case, the setting does not take effect. 
        r.CaptionLayerContent = `{
            "SizeNormalized": 0.05,
            "Color": "0xFFFFFF",
            "LocationId": "RV01",
            "BorderColor": "0x696969",
            "BorderWidthNormalized": 0.1,
            "BoxColor": "0xffffff",
            "BoxWidthNormalized": 0.7,
            "ShadowColor": "0x3c3c3c",
            "ShadowxWidthNormalized": 0.4,
            "ShadowyWidthNormalized": 0.4,
            "SourceLan": "cn",
            "TargetLan": "en",
            "PtsOffset": -1000,
            "SourceLanPerLineWordCount": 28,
            "TargetLanPerLineWordCount": 60,
            "ShowSourceLan": true,
            "ShowTargetLan": true,
            "Truncation": false,
            "AppearDuration": 20000,
            "AppearMode": "Movie"
        }`
        addCasterComponentResp, err := liveClient.AddCasterComponent(r)
        if err != nil {
            t.Fatal(err)
        }
    
        // Apply the component to a specific playback scene.
        setCasterSceneConfigRequest := live.CreateUpdateCasterSceneConfigRequest()
        setCasterSceneConfigRequest.LayoutId = "xxxxx"
        setCasterSceneConfigRequest.CasterId = casterID
        setCasterSceneConfigRequest.SceneId = "xxxx"
        setCasterSceneConfigRequest.ComponentId = &[]string{addCasterComponentResp.ComponentId}
        _, err = liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the AddCasterComponent operation, see AddCasterComponent.

    For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.

  • Start the production studio and set the playback scenes
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
        "time"
    )
    
    // Start the production studio and set the playback scenes.
    func StartCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        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)
        }
    
        // Suspend code execution before the required resources are loaded. If you immediately start the production studio, specific resources may fail to be loaded.
        time.Sleep(time.Second)
    
        // Set the playback scenes.
        // Optional. Set a PVW scene.
        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)
        }
        // Required. Set a PGM scene.
        setCasterSceneConfigRequest.SceneId = startCasterResp.PgmSceneInfos.SceneInfo[0].SceneId
        _, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the StartCaster operation, see StartCaster.

    For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.

  • Switch layouts
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    // Switch layouts.
    func ChangeLayout(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
        casterID := "xxxxxx"
    
        // Switch layouts for a playback scene.
        setCasterSceneConfigRequest := live.CreateUpdateCasterSceneConfigRequest()
        setCasterSceneConfigRequest.LayoutId = "xxxxxxxxxxxx"
        setCasterSceneConfigRequest.CasterId = casterID
        setCasterSceneConfigRequest.SceneId = "xxxxxxxxxxxxxx"
        _, err = liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.

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

    For more information about the StopCaster operation, see StopCaster.

  • Delete the production studio
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "testing"
    )
    // Stop and delete the production studio.
    func DeleteCaster(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("", "", "")
        if err != nil {
            t.Fatal(err)
        }
        // Delete the production studio.
        deleteCasterRequest := live.CreateDeleteCasterRequest()
        deleteCasterRequest.CasterId = "xxxxxxx"
        _, err = liveClient.DeleteCaster(deleteCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }

    For more information about the DeleteCaster operation, see DeleteCaster.

  • Create and play an episode list
    package caster
    
    import (
        "github.com/aliyun/alibaba-cloud-sdk-go/services/live"
        "github.com/aliyun/alibaba-cloud-sdk-go/services/vod"
        uuid "github.com/satori/go.uuid"
        "strconv"
        "testing"
        "time"
    )
    
    // Use the simplest code to create and play an episode list.
    func CreateProgramAndStartup(t *testing.T) {
        liveClient, err := live.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
        vodClient, err := vod.NewClientWithAccessKey("xxx", "xxx", "xxx")
        if err != nil {
            t.Fatal(err)
        }
    
        // Create a production studio.
        createCasterRequest := live.CreateCreateCasterRequest()
        createCasterRequest.ClientToken = uuid.NewV1().String()
        createCasterRequest.CasterName = "Production Studio for Testing"
        createCasterRequest.ChargeType = "PostPaid"
        createCasterRequest.NormType = "0"
        createCasterResp, err := liveClient.CreateCaster(createCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
        casterID := createCasterResp.CasterId
    
        // Configure the production studio.
        createSetCasterConfig := live.CreateSetCasterConfigRequest()
        createSetCasterConfig.CasterId = casterID
        createSetCasterConfig.CasterName = "Production Studio for Testing"
        createSetCasterConfig.ChannelEnable = "0"
        createSetCasterConfig.Delay = "0"
        createSetCasterConfig.DomainName = "xxxxxxxxxxx"
        createSetCasterConfig.ProgramEffect = "1"
        createSetCasterConfig.ProgramName = "Program Name"
        createSetCasterConfig.TranscodeConfig = `{"LiveTemplate":["lld"], "CasterTemplate": "lp_ld"}`
        _, err = liveClient.SetCasterConfig(createSetCasterConfig)
        if err != nil {
            t.Fatal(err)
        }
    
        // Add a video source to the production studio.
        materialVideoID := "xxxxxxxx"
        locationID := "RV01"
        addCasterVideoResourceRequest := live.CreateAddCasterVideoResourceRequest()
        addCasterVideoResourceRequest.CasterId = casterID
        addCasterVideoResourceRequest.ResourceName = "Video Source for Testing"
        addCasterVideoResourceRequest.PtsCallbackInterval = "1000"
        addCasterVideoResourceRequest.LocationId = locationID
        addCasterVideoResourceRequest.MaterialId = materialVideoID
    
        addCasterVideoResourceResp, err := liveClient.AddCasterVideoResource(addCasterVideoResourceRequest)
        if err != nil {
            t.Fatal(err)
        }
        resourceID := addCasterVideoResourceResp.ResourceId
    
        // Create an episode list.
        baseTimeNow := time.Now().UTC().Add(time.Minute)
        req := vod.CreateGetMezzanineInfoRequest()
        req.VideoId = materialVideoID
        mezzanineInfoResp, err := vodClient.GetMezzanineInfo(req)
        duration, _ := strconv.ParseFloat(mezzanineInfoResp.Mezzanine.Duration, 64)
        startTime := baseTimeNow.Format("2006-01-02T15:04:05Z")
        baseTimeNow = baseTimeNow.Add(time.Duration(duration) * time.Second)
        endTime := baseTimeNow.Format("2006-01-02T15:04:05Z")
        episode := make([]live.AddCasterProgramEpisode, 0, 1)
        episode = append(episode, live.AddCasterProgramEpisode{
            EpisodeType: "Resource",
            EpisodeName: mezzanineInfoResp.Mezzanine.FileName,
            ResourceId:  resourceID,
            StartTime:   startTime,
            EndTime:     endTime,
            SwitchType:  "TimeFirst", // ContentFirst
        })
        program := live.CreateAddCasterProgramRequest()
        program.Episode = &episode
        program.CasterId = casterID
        _, err = liveClient.AddCasterProgram(program)
        if err != nil {
            t.Fatal(err)
        }
    
        // Start the production studio.
        startCasterRequest := live.CreateStartCasterRequest()
        startCasterRequest.CasterId = casterID
        _, err = liveClient.StartCaster(startCasterRequest)
        if err != nil {
            t.Fatal(err)
        }
    }