Skip to content

Commit

Permalink
feat(live/transcoding): transcoding resource support new fields
Browse files Browse the repository at this point in the history
  • Loading branch information
jinyangyang222 committed Dec 13, 2024
1 parent c88adf3 commit 191d986
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 24 deletions.
51 changes: 46 additions & 5 deletions docs/resources/live_transcoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,22 @@ Changing this parameter will create a new resource.

* `video_encoding` - (Required, String) Specifies the video codec. The valid values are **H264** and **H265**.

* `templates` - (Required, List) Specifies the video quality templates.
The [object](#templates_resource) structure is documented below. A maximum of `4` templates can be added.
For resolution and bitrate settings in the presets,
please refer to the [document](https://support.huaweicloud.com/intl/en-us/usermanual-live/live01000802.html).
* `templates` - (Required, List) Specifies the video quality templates. A maximum of `4` templates can be added.
The [templates](#transcoding_templates) structure is documented below.
For resolution and bitrate settings in the presets,
please refer to the [document](https://support.huaweicloud.com/intl/en-us/usermanual-live/live01000802.html).

* `trans_type` - (Optional, String) Specifies the transcoding stream trigger mode.
The valid values are as follows:
+ **play**: Pull stream triggers transcoding.
+ **publish**: Push stream triggers transcoding.

Defaults to **play**.

* `low_bitrate_hd` - (Optional, Bool) Specifies whether to enable low bitrate HD rates. If enabled
the output media will have a lower bitrate with the same image quality. Defaults to **false**.

<a name="templates_resource"></a>
<a name="transcoding_templates"></a>
The `templates` block supports:

* `name` - (Required, String) Specifies the template name. The name can contain a maximum of 64 characters, and only
Expand All @@ -77,6 +84,40 @@ contains letters, digits and hyphens (-).
* `frame_rate` - (Optional, Int) Specifies the frame rate of the transcoded video, in fps. Value range: `0` ~ `30`.
Value 0 indicates that the frame rate remains unchanged.

* `protocol` - (Optional, String) Specifies the protocol type supported for transcoding output.
The valid value is **RTMP**. Defaults to **RTMP**.

* `i_frame_interval` - (Optional, String) Specifies the maximum I-frame interval in frames.
The value ranges from `0` to `500`, includes `0` and `500`. Defaults to `50`.

-> If you want to set the i-frame interval through `i_frame_interval`, please set the `gop` to `0` or do not pass the
`gop` parameter.

* `gop` - (Optional, String) Specifies the interval time for I-frames, in seconds.
The value ranges from `0` to `10`, includes `0` and `10`. Defaults to `2`.

-> When `gop` is not `0`, the i-frame interval is set with the `gop` parameter, and the `i_frame_interval` field does
not take effect.

* `bitrate_adaptive` - (Optional, String) Specifies the adaptive bitrate.
The valid values are as follows:
+ **off**: Disable rate adaptation and output the target rate according to the set rate.
+ **minimum**: Output the target bitrate based on the minimum value of the set bitrate and source file bitrate.
+ **adaptive**: Adaptive output of target bitrate based on source file bitrate.

Defaults to **off**.

* `i_frame_policy` - (Optional, String) Specifies the encoding output I-frame strategy.
The valid values are as follows:
+ **auto**: I-frame output according to the set `gop` duration.
+ **strictSync**: The encoded output I-frame is completely consistent with the source, and the `gop` parameter is
invalid after setting this value.

Defaults to **auto**.

-> In multi bitrate scenarios, it is recommended to enable I-frame random source to ensure alignment of multi bitrate
I-frames.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,18 @@ func TestAccTranscoding_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "domain_name", pushDomainName),
resource.TestCheckResourceAttr(rName, "app_name", "live"),
resource.TestCheckResourceAttr(rName, "video_encoding", "H264"),
resource.TestCheckResourceAttr(rName, "trans_type", "play"),
resource.TestCheckResourceAttr(rName, "low_bitrate_hd", "false"),
resource.TestCheckResourceAttr(rName, "templates.#", "1"),
resource.TestCheckResourceAttr(rName, "templates.0.name", "t1"),
resource.TestCheckResourceAttr(rName, "templates.0.width", "300"),
resource.TestCheckResourceAttr(rName, "templates.0.height", "400"),
resource.TestCheckResourceAttr(rName, "templates.0.bitrate", "300"),
resource.TestCheckResourceAttr(rName, "templates.0.protocol", "RTMP"),
resource.TestCheckResourceAttr(rName, "templates.0.i_frame_interval", "500"),
resource.TestCheckResourceAttr(rName, "templates.0.gop", "0"),
resource.TestCheckResourceAttr(rName, "templates.0.bitrate_adaptive", "adaptive"),
resource.TestCheckResourceAttr(rName, "templates.0.i_frame_policy", "strictSync"),
),
},
{
Expand All @@ -64,19 +70,27 @@ func TestAccTranscoding_basic(t *testing.T) {
resource.TestCheckResourceAttr(rName, "domain_name", pushDomainName),
resource.TestCheckResourceAttr(rName, "app_name", "live"),
resource.TestCheckResourceAttr(rName, "video_encoding", "H264"),
resource.TestCheckResourceAttr(rName, "trans_type", "play"),
resource.TestCheckResourceAttr(rName, "low_bitrate_hd", "true"),
resource.TestCheckResourceAttr(rName, "templates.#", "2"),
resource.TestCheckResourceAttr(rName, "templates.1.name", "t2"),
resource.TestCheckResourceAttr(rName, "templates.1.width", "600"),
resource.TestCheckResourceAttr(rName, "templates.1.height", "800"),
resource.TestCheckResourceAttr(rName, "templates.1.bitrate", "300"),
resource.TestCheckResourceAttr(rName, "templates.1.protocol", "RTMP"),
resource.TestCheckResourceAttr(rName, "templates.1.gop", "10"),
resource.TestCheckResourceAttr(rName, "templates.1.bitrate_adaptive", "minimum"),
resource.TestCheckResourceAttr(rName, "templates.1.i_frame_policy", "auto"),
),
},
{
ResourceName: rName,
ImportState: true,
ImportStateVerify: true,
ImportStateId: fmt.Sprintf("%s/live", pushDomainName),
ImportStateVerifyIgnore: []string{
"trans_type",
},
},
},
})
Expand All @@ -93,12 +107,18 @@ resource "huaweicloud_live_transcoding" "test" {
domain_name = huaweicloud_live_domain.ingestDomain.name
app_name = "live"
video_encoding = "H264"
trans_type = "play"
templates {
name = "t1"
width = 300
height = 400
bitrate = 300
name = "t1"
width = 300
height = 400
bitrate = 300
protocol = "RTMP"
i_frame_interval = 500
gop = 0
bitrate_adaptive = "adaptive"
i_frame_policy = "strictSync"
}
}
`, pushDomainName)
Expand All @@ -115,20 +135,30 @@ resource "huaweicloud_live_transcoding" "test" {
domain_name = huaweicloud_live_domain.ingestDomain.name
app_name = "live"
video_encoding = "H264"
trans_type = "play"
low_bitrate_hd = true
templates {
name = "t1"
width = 300
height = 400
bitrate = 300
name = "t1"
width = 300
height = 400
bitrate = 300
protocol = "RTMP"
i_frame_interval = 500
gop = 0
bitrate_adaptive = "adaptive"
i_frame_policy = "strictSync"
}
templates {
name = "t2"
width = 600
height = 800
bitrate = 300
name = "t2"
width = 600
height = 800
bitrate = 300
protocol = "RTMP"
gop = 10
bitrate_adaptive = "minimum"
i_frame_policy = "auto"
}
}
`, pushDomainName)
Expand Down
114 changes: 107 additions & 7 deletions huaweicloud/services/live/resource_huaweicloud_live_transcoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,44 @@ func ResourceTranscoding() *schema.Resource {
Type: schema.TypeInt,
Required: true,
},

"frame_rate": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"protocol": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"i_frame_interval": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"gop": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"bitrate_adaptive": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"i_frame_policy": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
},
},

// This field is not returned by API, so the Computed attribute is not added.
"trans_type": {
Type: schema.TypeString,
Optional: true,
},
"low_bitrate_hd": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -262,6 +290,40 @@ func buildTranscodingParams(d *schema.ResourceData) (*model.StreamTranscodingTem
VideoFrameRate: utils.Int32(int32(template["frame_rate"].(int))),
Codec: &codec,
Hdlb: &hdlb,
IFrameInterval: convertStringValueToInt32(template["i_frame_interval"].(string)),
Gop: convertStringValueToInt32(template["gop"].(string)),
}

if protocol := template["protocol"].(string); protocol != "" {
rtmpValue := model.GetQualityInfoProtocolEnum().RTMP
switch protocol {

Check failure on line 299 in huaweicloud/services/live/resource_huaweicloud_live_transcoding.go

View workflow job for this annotation

GitHub Actions / golangci

singleCaseSwitch: should rewrite switch statement to if statement (gocritic)
case "RTMP":
qualityInfo[i].Protocol = &rtmpValue
}
}
if bitrateAdaptive := template["bitrate_adaptive"].(string); bitrateAdaptive != "" {
minimumValue := model.GetQualityInfoBitrateAdaptiveEnum().MINIMUM
adaptiveValue := model.GetQualityInfoBitrateAdaptiveEnum().ADAPTIVE
switch bitrateAdaptive {
case "off":
// There is no enumeration value for **off** in the HuaweiCloud SDK, but the default value for the API
// is **off**, so this processing is done here.
qualityInfo[i].BitrateAdaptive = nil
case "minimum":
qualityInfo[i].BitrateAdaptive = &minimumValue
case "adaptive":
qualityInfo[i].BitrateAdaptive = &adaptiveValue
}
}
if iFramePolicy := template["i_frame_policy"].(string); iFramePolicy != "" {
autoValue := model.GetQualityInfoIFramePolicyEnum().AUTO
strictSyncValue := model.GetQualityInfoIFramePolicyEnum().STRICT_SYNC
switch iFramePolicy {
case "auto":
qualityInfo[i].IFramePolicy = &autoValue
case "strictSync":
qualityInfo[i].IFramePolicy = &strictSyncValue
}
}
}

Expand All @@ -270,6 +332,17 @@ func buildTranscodingParams(d *schema.ResourceData) (*model.StreamTranscodingTem
AppName: d.Get("app_name").(string),
QualityInfo: qualityInfo,
}
if transType := d.Get("trans_type").(string); transType != "" {
playValue := model.GetStreamTranscodingTemplateTransTypeEnum().PLAY
publishValue := model.GetStreamTranscodingTemplateTransTypeEnum().PUBLISH
switch transType {
case "play":
req.TransType = &playValue
case "publish":
req.TransType = &publishValue
}
}

return &req, nil
}

Expand All @@ -279,11 +352,16 @@ func setTemplatesToState(d *schema.ResourceData, qualityInfo *[]model.QualityInf
rst := make([]map[string]interface{}, len(qualitys))
for i, v := range qualitys {
rst[i] = map[string]interface{}{
"name": v.TemplateName,
"width": v.Width,
"height": v.Height,
"bitrate": v.Bitrate,
"frame_rate": v.VideoFrameRate,
"name": v.TemplateName,
"width": v.Width,
"height": v.Height,
"bitrate": v.Bitrate,
"frame_rate": v.VideoFrameRate,
"protocol": v.Protocol.Value(),
"i_frame_interval": parseInt32ValueToString(v.IFrameInterval),
"gop": parseInt32ValueToString(v.Gop),
"bitrate_adaptive": v.BitrateAdaptive.Value(),
"i_frame_policy": v.IFramePolicy.Value(),
}
}

Expand Down Expand Up @@ -311,3 +389,25 @@ func parseTranscodingId(id string) (domainName string, appName string, err error
}
return idArrays[0], idArrays[1], nil
}

func convertStringValueToInt32(value string) *int32 {
if value == "0" {
return utils.Int32(0)
}

parsedValue := utils.StringToInt(&value)
if parsedValue != nil {
//nolint:gosec
return utils.Int32IgnoreEmpty(int32(*parsedValue))
}

return nil
}

func parseInt32ValueToString(value *int32) string {
if value != nil {
return fmt.Sprintf("%v", *value)
}

return ""
}

0 comments on commit 191d986

Please sign in to comment.