diff --git a/docs/resources/live_transcoding.md b/docs/resources/live_transcoding.md
index f0e4701b86b..564f391760e 100644
--- a/docs/resources/live_transcoding.md
+++ b/docs/resources/live_transcoding.md
@@ -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**.
-
+
The `templates` block supports:
* `name` - (Required, String) Specifies the template name. The name can contain a maximum of 64 characters, and only
@@ -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:
diff --git a/huaweicloud/services/acceptance/live/resource_huaweicloud_live_transcoding_test.go b/huaweicloud/services/acceptance/live/resource_huaweicloud_live_transcoding_test.go
index d17a9949b9d..e3e748b6178 100644
--- a/huaweicloud/services/acceptance/live/resource_huaweicloud_live_transcoding_test.go
+++ b/huaweicloud/services/acceptance/live/resource_huaweicloud_live_transcoding_test.go
@@ -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"),
),
},
{
@@ -64,12 +70,17 @@ 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"),
),
},
{
@@ -77,6 +88,9 @@ func TestAccTranscoding_basic(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
ImportStateId: fmt.Sprintf("%s/live", pushDomainName),
+ ImportStateVerifyIgnore: []string{
+ "trans_type",
+ },
},
},
})
@@ -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)
@@ -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)
diff --git a/huaweicloud/services/live/resource_huaweicloud_live_transcoding.go b/huaweicloud/services/live/resource_huaweicloud_live_transcoding.go
index 920d7670dde..88bced93d5b 100644
--- a/huaweicloud/services/live/resource_huaweicloud_live_transcoding.go
+++ b/huaweicloud/services/live/resource_huaweicloud_live_transcoding.go
@@ -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,
@@ -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 {
+ 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
+ }
}
}
@@ -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
}
@@ -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(),
}
}
@@ -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 ""
+}