This document provides a complete, runnable demo for managing a production studio in general mode through OpenAPI.
API workflow
The entire process for managing a general-mode production studio follows this sequence:
You must add a video source before you add a layout. Otherwise, the layout will not be applied.
(Optional) Add a component
Such as real-time subtitles, images, and text.
Sample code
For more information about the API operations, see List of operations by function.
The following sample code uses the Go SDK. For more information, see Use the Go SDK.
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 more information about the request parameters of the CreateCaster operation, 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 more information about the SetCasterConfig operation, see SetCasterConfig.
Add a video source and bind it to a channel
// Add a video source. func AddCasterVideoResource(liveClient *live20161101.Client, casterId *string) error { // Create a video source for the production studio. addCasterVideoResourceRequest := &live20161101.AddCasterVideoResourceRequest{} addCasterVideoResourceRequest.CasterId = casterId addCasterVideoResourceRequest.ResourceName = tea.String("Video source for testing") addCasterVideoResourceRequest.LiveStreamUrl = tea.String("xxxxx") addCasterVideoResourceRequest.PtsCallbackInterval = tea.Int32(1000) addCasterVideoResourceResp, err := liveClient.AddCasterVideoResource(addCasterVideoResourceRequest) if err != nil { return errors.New("AddCasterVideoResource failed: " + err.Error()) } resourceId := addCasterVideoResourceResp.Body.ResourceId // Bind the video source to a channel. setCasterChannelRequest := &live20161101.SetCasterChannelRequest{} setCasterChannelRequest.CasterId = casterId setCasterChannelRequest.PlayStatus = tea.Int32(1) setCasterChannelRequest.ChannelId = tea.String("RV01") setCasterChannelRequest.ResourceId = resourceId _, err = liveClient.SetCasterChannel(setCasterChannelRequest) if err != nil { return errors.New("SetCasterChannel failed: " + err.Error()) } return nil }For more information about the AddCasterVideoResource operation, see AddCasterVideoResource.
Add a layout
// Add a layout. func AddCasterLayout(liveClient *live20161101.Client, casterId *string) (*live20161101.AddCasterLayoutResponse, error) { // Create a layout. addCasterLayoutRequest := &live20161101.AddCasterLayoutRequest{} addCasterLayoutRequest.CasterId = casterId addCasterLayoutRequest.BlendList = []*string{tea.String("RV01")} // The position of the video. addCasterLayoutRequest.MixList = []*string{tea.String("RV01")} // The position of the video. audioLayer := &live20161101.AddCasterLayoutRequestAudioLayer{} audioLayer.VolumeRate = tea.Float32(1) audioLayer.ValidChannel = tea.String("all") audioLayer.FixedDelayDuration = tea.Int32(0) addCasterLayoutRequest.AudioLayer = []*live20161101.AddCasterLayoutRequestAudioLayer{ audioLayer, } videoLayer := &live20161101.AddCasterLayoutRequestVideoLayer{ FillMode: tea.String("fit"), HeightNormalized: tea.Float32(1), WidthNormalized: tea.Float32(1), PositionRefer: tea.String("topLeft"), PositionNormalized: []*float32{tea.Float32(0), tea.Float32(0)}, FixedDelayDuration: tea.Int32(0), } addCasterLayoutRequest.VideoLayer = []*live20161101.AddCasterLayoutRequestVideoLayer{ videoLayer, } addCasterLayoutResponse, err := liveClient.AddCasterLayout(addCasterLayoutRequest) if err != nil { return nil, errors.New("AddCasterLayout failed: " + err.Error()) } return addCasterLayoutResponse, nil }For more information, see AddCasterLayout.
Start the production studio and set the playback scenes
// Start the production studio and set the playback scenes. func StartCaster(liveClient *live20161101.Client, casterId *string, layoutId *string) (*live20161101.StartCasterResponse, error) { // Start the production studio. startCasterRequest := &live20161101.StartCasterRequest{ CasterId: casterId, } startCasterResp, err := liveClient.StartCaster(startCasterRequest) if err != nil { return nil, errors.New("StartCaster failed: " + err.Error()) } // It takes time to load resources. If you start the production studio immediately, the resources may fail to be loaded. Therefore, you need to pause the process for a while. time.Sleep(time.Second) // Set the playback scenes. // PVW (Optional) setCasterSceneConfigRequest := &live20161101.SetCasterSceneConfigRequest{ CasterId: casterId, LayoutId: layoutId, SceneId: startCasterResp.Body.PvwSceneInfos.SceneInfo[0].SceneId, } _, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest) if err != nil { return nil, errors.New("SetCasterSceneConfig failed: " + err.Error()) } // PGM (Required) setCasterSceneConfigRequest.SceneId = startCasterResp.Body.PgmSceneInfos.SceneInfo[0].SceneId _, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest) if err != nil { return nil, errors.New("SetCasterSceneConfig failed: " + err.Error()) } return startCasterResp, nil }For more information about the StartCaster operation, see StartCaster.
For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.
Add a real-time subtitle component and apply it to a scene
// Add a real-time subtitle component and apply it to a scene. func AddETComponent(liveClient *live20161101.Client, casterId *string, layoutId *string, pgmSceneId *string) error { // Prerequisites: A production studio is created, a live stream is added as a video source, and the locationID is RV01. // Note: Real-time subtitles are valid only for live streams. // Create a component. r := &live20161101.AddCasterComponentRequest{ CasterId: casterId, ComponentType: tea.String("caption"), ComponentName: tea.String("Real-time subtitles for testing"), Effect: tea.String("none"), LocationId: tea.String("RV01"), ComponentLayer: tea.String(`{"HeightNormalized":"1","WidthNormalized":"1","PositionRefer":"topLeft","PositionNormalized":["0.05", "0.7"]}`), // For more information about the caption fields, see the description of the CaptionLayerContent parameter in the AddCasterComponent topic. // The following fields are added. Note that the official documentation is not updated. // BoxWidthNormalized: The normalized width of the text background. This value is calculated based on the font size, which is boxWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0. // BoxColor: The color of the text background. The value is in the 0xRGBA format. For example, 0xff0000ff indicates opaque red. The default value is "", which indicates that this parameter is invalid. // ShadowxWidthNormalized: The normalized value of the x-coordinate of the text shade. This value is calculated based on the font size, which is shadowxWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0. // ShadowyWidthNormalized: The normalized value of the y-coordinate of the text shade. This value is calculated based on the font size, which is shadowyWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0. // ShadowColor: The color of the text shade. The value is in the 0xRGBA format. For example, 0xff0000ff indicates opaque red. The default value is "", which indicates that this parameter is invalid. CaptionLayerContent: tea.String(`{ "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 { return errors.New("AddCasterComponent failed: " + err.Error()) } // Apply the component to the specified scene. setCasterSceneConfigRequest := &live20161101.UpdateCasterSceneConfigRequest{ CasterId: casterId, LayoutId: layoutId, SceneId: pgmSceneId, ComponentId: []*string{addCasterComponentResp.Body.ComponentId}, } _, err = liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest) if err != nil { return errors.New("UpdateCasterSceneConfig failed: " + err.Error()) } return nil }For more information about the AddCasterComponent operation, see AddCasterComponent.
For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.
Switch the layout
// Switch the layout. func ChangeLayout(liveClient *live20161101.Client, casterId *string, pgmSceneId *string, newLayoutId *string) error { // Change the layout ID of the scene. setCasterSceneConfigRequest := &live20161101.UpdateCasterSceneConfigRequest{ CasterId: casterId, SceneId: pgmSceneId, LayoutId: newLayoutId, } _, err := liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest) if err != nil { return errors.New("UpdateCasterSceneConfig failed: " + err.Error()) } return nil }For more information about the SetCasterSceneConfig operation, see SetCasterSceneConfig.
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 more information about the StopCaster operation, see StopCaster.
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 more information about the DeleteCaster operation, see DeleteCaster.
package main
import (
"errors"
"log"
"sync"
"time"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
live20161101 "github.com/alibabacloud-go/live-20161101/v2/client"
"github.com/alibabacloud-go/tea/tea"
"github.com/google/uuid"
"gopkg.in/ini.v1"
)
type LiveClient struct {
instance *live20161101.Client
once sync.Once
}
var liveClientInstance = &LiveClient{}
func GetClientInstance() (*live20161101.Client, error) {
section, err := getAccessKey()
if err != nil {
return nil, err
}
liveClientInstance.once.Do(func() {
cfg := &openapi.Config{
Endpoint: tea.String("live.aliyuncs.com"),
AccessKeyId: tea.String(section.Key("access_key_id").String()),
AccessKeySecret: tea.String(section.Key("access_key_secret").String()),
}
liveClientInstance.instance, err = live20161101.NewClient(cfg)
if err != nil {
err = errors.New("Live client initialization failed: " + err.Error())
}
})
if err != nil {
return nil, err
}
return liveClientInstance.instance, nil
}
func getAccessKey() (*ini.Section, error) {
cfg, err := ini.Load("conf/config.ini")
if err != nil {
return nil, errors.New("ERROR: Can not open file " + err.Error())
}
section, err := cfg.GetSection("")
if err != nil {
return nil, errors.New("ERROR: Can not find section " + err.Error())
}
return section, nil
}
// 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
}
// Set 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
}
// Add a video source.
func AddCasterVideoResource(liveClient *live20161101.Client, casterId *string) error {
// Create a video source for the production studio.
addCasterVideoResourceRequest := &live20161101.AddCasterVideoResourceRequest{}
addCasterVideoResourceRequest.CasterId = casterId
addCasterVideoResourceRequest.ResourceName = tea.String("Video source for testing")
addCasterVideoResourceRequest.LiveStreamUrl = tea.String("xxxxx")
addCasterVideoResourceRequest.PtsCallbackInterval = tea.Int32(1000)
addCasterVideoResourceResp, err := liveClient.AddCasterVideoResource(addCasterVideoResourceRequest)
if err != nil {
return errors.New("AddCasterVideoResource failed: " + err.Error())
}
resourceId := addCasterVideoResourceResp.Body.ResourceId
// Bind the video source to a channel.
setCasterChannelRequest := &live20161101.SetCasterChannelRequest{}
setCasterChannelRequest.CasterId = casterId
setCasterChannelRequest.PlayStatus = tea.Int32(1)
setCasterChannelRequest.ChannelId = tea.String("RV01")
setCasterChannelRequest.ResourceId = resourceId
_, err = liveClient.SetCasterChannel(setCasterChannelRequest)
if err != nil {
return errors.New("SetCasterChannel failed: " + err.Error())
}
return nil
}
// Add a layout.
func AddCasterLayout(liveClient *live20161101.Client, casterId *string) (*live20161101.AddCasterLayoutResponse, error) {
// Create a layout.
addCasterLayoutRequest := &live20161101.AddCasterLayoutRequest{}
addCasterLayoutRequest.CasterId = casterId
addCasterLayoutRequest.BlendList = []*string{tea.String("RV01")} // The position of the video.
addCasterLayoutRequest.MixList = []*string{tea.String("RV01")} // The position of the video.
audioLayer := &live20161101.AddCasterLayoutRequestAudioLayer{}
audioLayer.VolumeRate = tea.Float32(1)
audioLayer.ValidChannel = tea.String("all")
audioLayer.FixedDelayDuration = tea.Int32(0)
addCasterLayoutRequest.AudioLayer = []*live20161101.AddCasterLayoutRequestAudioLayer{
audioLayer,
}
videoLayer := &live20161101.AddCasterLayoutRequestVideoLayer{
FillMode: tea.String("fit"),
HeightNormalized: tea.Float32(1),
WidthNormalized: tea.Float32(1),
PositionRefer: tea.String("topLeft"),
PositionNormalized: []*float32{tea.Float32(0), tea.Float32(0)},
FixedDelayDuration: tea.Int32(0),
}
addCasterLayoutRequest.VideoLayer = []*live20161101.AddCasterLayoutRequestVideoLayer{
videoLayer,
}
addCasterLayoutResponse, err := liveClient.AddCasterLayout(addCasterLayoutRequest)
if err != nil {
return nil, errors.New("AddCasterLayout failed: " + err.Error())
}
return addCasterLayoutResponse, nil
}
// Add a real-time subtitle component and apply it to a scene.
func AddETComponent(liveClient *live20161101.Client, casterId *string, layoutId *string, pgmSceneId *string) error {
// Prerequisites: A production studio is created, a live stream is added as a video source, and the locationID is RV01.
// Note: Real-time subtitles are valid only for live streams.
// Create a component.
r := &live20161101.AddCasterComponentRequest{
CasterId: casterId,
ComponentType: tea.String("caption"),
ComponentName: tea.String("Real-time subtitles for testing"),
Effect: tea.String("none"),
LocationId: tea.String("RV01"),
ComponentLayer: tea.String(`{"HeightNormalized":"1","WidthNormalized":"1","PositionRefer":"topLeft","PositionNormalized":["0.05", "0.7"]}`),
// For more information about the caption fields, see the description of the CaptionLayerContent parameter in the AddCasterComponent topic.
// The following fields are added. Note that the official documentation is not updated.
// BoxWidthNormalized: The normalized width of the text background. This value is calculated based on the font size, which is boxWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0.
// BoxColor: The color of the text background. The value is in the 0xRGBA format. For example, 0xff0000ff indicates opaque red. The default value is "", which indicates that this parameter is invalid.
// ShadowxWidthNormalized: The normalized value of the x-coordinate of the text shade. This value is calculated based on the font size, which is shadowxWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0.
// ShadowyWidthNormalized: The normalized value of the y-coordinate of the text shade. This value is calculated based on the font size, which is shadowyWidth/font_size. If the calculated value exceeds 16, the value 16 is used. Default value: 0.
// ShadowColor: The color of the text shade. The value is in the 0xRGBA format. For example, 0xff0000ff indicates opaque red. The default value is "", which indicates that this parameter is invalid.
CaptionLayerContent: tea.String(`{
"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 {
return errors.New("AddCasterComponent failed: " + err.Error())
}
// Apply the component to the specified scene.
setCasterSceneConfigRequest := &live20161101.UpdateCasterSceneConfigRequest{
CasterId: casterId,
LayoutId: layoutId,
SceneId: pgmSceneId,
ComponentId: []*string{addCasterComponentResp.Body.ComponentId},
}
_, err = liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest)
if err != nil {
return errors.New("UpdateCasterSceneConfig failed: " + err.Error())
}
return nil
}
// Start the production studio and set the playback scenes.
func StartCaster(liveClient *live20161101.Client, casterId *string, layoutId *string) (*live20161101.StartCasterResponse, error) {
// Start the production studio.
startCasterRequest := &live20161101.StartCasterRequest{
CasterId: casterId,
}
startCasterResp, err := liveClient.StartCaster(startCasterRequest)
if err != nil {
return nil, errors.New("StartCaster failed: " + err.Error())
}
// It takes time to load resources. If you start the production studio immediately, the resources may fail to be loaded. Therefore, you need to pause the process for a while.
time.Sleep(time.Second)
// Set the playback scenes.
// PVW (Optional)
setCasterSceneConfigRequest := &live20161101.SetCasterSceneConfigRequest{
CasterId: casterId,
LayoutId: layoutId,
SceneId: startCasterResp.Body.PvwSceneInfos.SceneInfo[0].SceneId,
}
_, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
if err != nil {
return nil, errors.New("SetCasterSceneConfig failed: " + err.Error())
}
// PGM (Required)
setCasterSceneConfigRequest.SceneId = startCasterResp.Body.PgmSceneInfos.SceneInfo[0].SceneId
_, err = liveClient.SetCasterSceneConfig(setCasterSceneConfigRequest)
if err != nil {
return nil, errors.New("SetCasterSceneConfig failed: " + err.Error())
}
return startCasterResp, nil
}
// Switch the layout.
func ChangeLayout(liveClient *live20161101.Client, casterId *string, pgmSceneId *string, newLayoutId *string) error {
// Change the layout ID of the scene.
setCasterSceneConfigRequest := &live20161101.UpdateCasterSceneConfigRequest{
CasterId: casterId,
SceneId: pgmSceneId,
LayoutId: newLayoutId,
}
_, err := liveClient.UpdateCasterSceneConfig(setCasterSceneConfigRequest)
if err != nil {
return errors.New("UpdateCasterSceneConfig failed: " + err.Error())
}
return nil
}
// 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
}
// 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
}
func main() {
liveClient, err := GetClientInstance()
if err != nil {
panic(err)
}
// Create a production studio.
createCasterResponse, err := CreateCaster(liveClient)
if err != nil {
panic(err)
}
casterId := createCasterResponse.Body.CasterId
log.Println("CasterId: ", *casterId)
// Set the production studio.
domainName := tea.String("example.aliyundoc.com") // Set the domain name.
SetCasterConfig(liveClient, casterId, domainName)
// Add a video source. You need to add the video source in the function.
AddCasterVideoResource(liveClient, casterId)
// Add a layout.
addCasterLayoutResponse, err := AddCasterLayout(liveClient, casterId)
if err != nil {
panic(err)
}
layoutId := addCasterLayoutResponse.Body.LayoutId
// Start the production studio and set the playback scenes.
startCasterResp, err := StartCaster(liveClient, casterId, layoutId)
if err != nil {
panic(err)
}
// (Optional) Add a real-time subtitle component and apply it to the PGM scene.
pgmSceneId := startCasterResp.Body.PgmSceneInfos.SceneInfo[0].SceneId
AddETComponent(liveClient, casterId, layoutId, pgmSceneId)
// (Optional) Switch the layout.
// newLayoutId := tea.String("xxxx")
// ChangeLayout(liveClient, casterId, pgmSceneId, newLayoutId)
time.Sleep(time.Minute * 10)
// Stop the production studio.
StopCaster(liveClient, casterId)
// Delete the production studio.
DeleteCaster(liveClient, casterId)
}