Add visible watermarks such as company logos or TV station logos to your videos to enhance brand visibility and protect copyrights. ApsaraVideo Media Processing (MPS) supports image watermarks, animated watermarks, and text watermarks. This topic provides examples on how to call MPS SDK for Go operations to create a watermark template, submit a text watermark job, and submit an image watermark job.
Prerequisites
An SDK client is initialized. For more information, see Initialize a client.
Create a watermark template
A watermark template defines watermark attributes such as size and location, which simplifies watermark management. Call the AddWaterMarkTemplate operation to create a watermark template.
-
Watermark templates apply only to image watermarks, not to text watermarks.
-
A watermark template defines only watermark attributes such as location and size, not watermark content. Specify the watermark content when you submit a watermark job.
-
A successful AddWaterMarkTemplate call returns a watermark template ID. You can also create a watermark template and obtain the template ID in the MPS console. For more information, see Manage watermark templates.
-
If the error message "The resource "WatermarkTemplate" quota has been used up" is returned, your quota for watermark templates is used up. In this case, you can submit a ticket to apply for a higher quota.
/**
* 创建水印模板
* @param client
* @return
*/
func AddWaterMarkTemplate(client *mts.Client) (*mts.AddWaterMarkTemplateResponse, error) {
request := mts.CreateAddWaterMarkTemplateRequest()
//Watermark parameter details, refer to https://help.aliyun.com/document_detail/29253.htm?spm=a2c4g.602851.0.0.4ab731bckAeLdq#section-k53-tt4-8b0
config := map[string]string{
"Dx": "10",
"Dy": "5",
"ReferPos": "TopRight",
}
configJson, _ := json.Marshal(config)
request.Config = string(configJson)
request.Name = "test name"
return client.AddWaterMarkTemplate(request)
}
Submit a watermark job
Adding a watermark changes the video image, which requires re-encoding. Call the SubmitJobs operation to submit a watermark job.
-
When you submit a watermark job by using the SDK, URL-encode the watermark file path. Otherwise, the job fails. For more information, see URL encoding.
-
Ensure that the file name is valid. Otherwise, the file cannot be found and the job fails. For more information, see Parameter details.
-
Record the job ID after submission for subsequent operations.
Submit a text watermark job
/**
* Submit a text watermark job
* @param client
* @return
*/
func SubmitTextJobs(client *mts.Client) (*mts.SubmitJobsResponse, error) {
request := mts.CreateSubmitJobsRequest()
// Construct an input object. Make sure that the value of the Location parameter is the region in which the client is deployed.
input := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("mps-test/demo/test.mp4"),
}
inputJson, _ := json.Marshal(input)
request.Input = string(inputJson)
// Specify an output bucket.
request.OutputBucket = "<your bucket name>"
// Specify the region in which the output bucket resides. Format: oss-cn-****. Example: oss-cn-beijing.
request.OutputLocation = "oss-cn-beijing"
// Configure the output settings of the text watermark.
// Specify the text to be used as the watermark for the Content parameter. The specified text must be Base64-encoded.
waterMark := map[string]string{
"Type": "Text",
"TextWaterMark": `{"Content":"5rWL6K+V5paH5a2X5rC05Y2w","FontName":"SimSun","FontSize":"16","Top":2,"Left":10}`,
}
waterMarks := [...]map[string]string{waterMark}
// Construct an output object.
output := map[string]interface{}{
"OutputObject": url.QueryEscape("mps-test/demo/test-out.mp4"),
"TemplateId": templateId,
"WaterMarks": waterMarks,
}
outputs := [...]map[string]interface{}{output}
outputsJson, _ := json.Marshal(outputs)
request.Outputs = string(outputsJson)
// PipelineId
request.PipelineId = pipelineId
return client.SubmitJobs(request)
}
Submit an image watermark job
/**
* Submit an image watermark job
* @param client
* @return
*/
func SubmitImageJobs(client *mts.Client) (*mts.SubmitJobsResponse, error) {
request := mts.CreateSubmitJobsRequest()
// Construct an input object. Make sure that the value of the Location parameter is the region in which the client is deployed.
input := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("mps-test/demo/test.mp4"),
}
inputJson, _ := json.Marshal(input)
request.Input = string(inputJson)
// Specify an output bucket.
request.OutputBucket = "<your bucket name>"
// Specify the region in which the output bucket resides. Format: oss-cn-****. Example: oss-cn-beijing.
request.OutputLocation = "oss-cn-beijing"
// Specify the image to be used as the watermark.
// You can specify a static PNG image, an animated PNG image, a MOV file, or a GIF file based on your business requirements. The file name extension of an animated PNG image must be apng. If the image to be used as the watermark is a non-static image, the file name extension must be in lowercase.
inputFile := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("Dynamic logo.apng"),
}
inputFileJson, _ := json.Marshal(inputFile)
// Configure the output settings of the image watermark.
// A watermark array consists of up to four watermarks. An output video can contain up to four watermarks.
waterMark := map[string]string{
"WaterMarkTemplateId": "23d7a99796fad2bc****",
"Type": "Image",
"Width": "200",
"Height": "100",
"InputFile": string(inputFileJson),
}
waterMarks := [...]map[string]string{waterMark}
// Construct an output object.
output := map[string]interface{}{
"OutputObject": url.QueryEscape("mps-test/demo/test-out.mp4"),
"TemplateId": templateId,
"WaterMarks": waterMarks,
}
outputs := [...]map[string]interface{}{output}
outputsJson, _ := json.Marshal(outputs)
request.Outputs = string(outputsJson)
// PipelineId
request.PipelineId = pipelineId
return client.SubmitJobs(request)
}
Sample code
package main
import (
"encoding/json"
"fmt"
"net/url"
mts "github.com/aliyun/alibaba-cloud-sdk-go/services/mts"
)
/**
* 创建水印模板
* @param client
* @return
*/
func AddWaterMarkTemplate(client *mts.Client) (*mts.AddWaterMarkTemplateResponse, error) {
request := mts.CreateAddWaterMarkTemplateRequest()
//Watermark parameter details, refer to https://help.aliyun.com/document_detail/29253.htm?spm=a2c4g.602851.0.0.4ab731bckAeLdq#section-k53-tt4-8b0
config := map[string]string{
"Dx": "10",
"Dy": "5",
"ReferPos": "TopRight",
}
configJson, _ := json.Marshal(config)
request.Config = string(configJson)
request.Name = "test name"
return client.AddWaterMarkTemplate(request)
}
/**
* 提交文字水印转码作业
* @param client
* @return
*/
func SubmitTextJobs(client *mts.Client) (*mts.SubmitJobsResponse, error) {
request := mts.CreateSubmitJobsRequest()
//Buildinput, ensure Location region is consistent with service client region
input := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("mps-test/demo/test.mp4"),
}
inputJson, _ := json.Marshal(input)
request.Input = string(inputJson)
//Specify outputBucket
request.OutputBucket = "<your bucket name>"
//OutputBucket region, format: oss-cn-****, for example Beijing oss-cn-beijing
request.OutputLocation = "oss-cn-beijing"
//Build text watermark output configuration
//Content is the text watermark content, content needs to be Base64 encoded
waterMark := map[string]string{
"Type": "Text",
"TextWaterMark": `{"Content":"5rWL6K+V5paH5a2X5rC05Y2w","FontName":"SimSun","FontSize":"16","Top":2,"Left":10}`,
}
waterMarks := [...]map[string]string{waterMark}
//Build an output object
output := map[string]interface{}{
"OutputObject": url.QueryEscape("mps-test/demo/test-out.mp4"),
"TemplateId": templateId,
"WaterMarks": waterMarks,
}
outputs := [...]map[string]interface{}{output}
outputsJson, _ := json.Marshal(outputs)
request.Outputs = string(outputsJson)
// PipelineId
request.PipelineId = pipelineId
return client.SubmitJobs(request)
}
/**
* 提交图片水印转码作业
* @param client
* @return
*/
func SubmitImageJobs(client *mts.Client) (*mts.SubmitJobsResponse, error) {
request := mts.CreateSubmitJobsRequest()
//Buildinput, ensure Location region is consistent with service client region
input := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("mps-test/demo/test.mp4"),
}
inputJson, _ := json.Marshal(input)
request.Input = string(inputJson)
//Specify outputBucket
request.OutputBucket = "<your bucket name>"
//OutputBucket region, format: oss-cn-****, for example Beijing oss-cn-beijing
request.OutputLocation = "oss-cn-beijing"
//Add image watermark material
//ImageObject can be replaced with png static images, png animated images (file extension should be apng), mov, gif files as needed. When the material is not a static image, the file extension should be lowercase
inputFile := map[string]string{
"Location": "oss-cn-beijing",
"Bucket": "<your bucket name>",
"Object": url.QueryEscape("动态logo.apng"),
}
inputFileJson, _ := json.Marshal(inputFile)
//Build image watermark output configuration
//Watermark array size limit is 4, meaning the same output supports up to 4 watermarks
waterMark := map[string]string{
"WaterMarkTemplateId": "23d7a9549d796****",
"Type": "Image",
"Width": "200",
"Height": "100",
"InputFile": string(inputFileJson),
}
waterMarks := [...]map[string]string{waterMark}
//Build an output object
output := map[string]interface{}{
"OutputObject": url.QueryEscape("mps-test/demo/test-out.mp4"),
"TemplateId": templateId,
"WaterMarks": waterMarks,
}
outputs := [...]map[string]interface{}{output}
outputsJson, _ := json.Marshal(outputs)
request.Outputs = string(outputsJson)
// PipelineId
request.PipelineId = pipelineId
return client.SubmitJobs(request)
}
const (
//TemplateID, refer to preset template reference https://help.aliyun.com/document_detail/29256.html
templateId = "S00000001-200010"
//PipelineID, can be viewed in MPS console > Global Settings > Pipelines
pipelineId = "bee7a5b5bfe40a0cbf****"
)
func main() {
//Initialize client
client, err := InitMtsClient()
if err != nil {
panic(err)
}
response, err := SubmitImageJobs(client)
if err != nil {
panic(err)
}
fmt.Println("RequestId is:", response.RequestId)
//fmt.Println("JobId is:", response.JobResultList.JobResult[0].Job.JobId)
}