You can add visible watermarks such as company logos or TV station logos to your videos to enhance brand visibility, protect copyrights, and boost product recognition. ApsaraVideo Media Processing (MPS) provides the following types of watermarks: image watermark, animated watermark, and test watermark. You can select a watermark type based on your business requirements. This topic provides examples on how to call the API operations that are encapsulated in MPS SDK for Java to manage watermarks, including creating watermark templates, submitting text watermark jobs, and submitting image watermark jobs.
Prerequisites
The SDK client is initialized. For more information, see Initialize a client.
AddWaterMarkTemplate: Create a watermark template
A watermark template specifies the settings of multiple parameters, such as the parameters that determine the size and location of a watermark. You can use a watermark template to simplify watermark management. You can call the AddWaterMarkTemplate operation to create a watermark template.
A watermark template is applicable only to image watermarks and is not applicable to text watermarks.
A watermark template specifies only watermark attributes, such as the location and size, but does not specify watermark content. You need to specify watermark content when you submit a watermark job.
If a call to this operation succeeds, a watermark template ID is returned. 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 "The resource "WatermarkTemplate" quota has been used up" error message is returned, your quota for watermark templates is used up. In this case, you can submit a ticket to increase the quota.
/**
* Create a watermark template.
* @return
* @throws Exception
*/
public static void addWaterMarkTemplate() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// For more information about watermark parameters, visit https://www.alibabacloud.com/help/zh/apsaravideo-for-media-processing/latest/parameter-details-a#section-k53-tt4-8b0.
JSONObject waterMarkConfig = new JSONObject();
waterMarkConfig.put("Dx","10");
waterMarkConfig.put("Dy","5");
waterMarkConfig.put("ReferPos","TopRight");
com.aliyun.mts20140618.models.AddWaterMarkTemplateRequest addWaterMarkTemplateRequest = new com.aliyun.mts20140618.models.AddWaterMarkTemplateRequest()
// The name of the watermark.
.setName("Name")
// The job output configuration.
.setConfig(waterMarkConfig.toJSONString());
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.addWaterMarkTemplateWithOptions(addWaterMarkTemplateRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}SubmitJobs: Submit a watermark job
If you add a watermark to your video, the video images change, and you need to re-encode your video. MPS provides the SubmitJobs operation for you to submit a watermark job.
When you call the operation to submit a job, you must perform URL encoding on the path to the file that you want to use as the watermark. Otherwise, the job fails. For more information, see URL encoding.
You must specify a valid file name to ensure that the file can be found when the job runs. For more information, see Parameter details.
We recommend that you record the ID of a submitted job. This helps you with subsequent operations.
Submit a text watermark job
/**
* Submit a text watermark job.
* @return
* @throws Exception
*/
public static void submitTextWaterMarkJobs() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// Configure the output settings of watermarks.
JSONArray waterMarks = new JSONArray(); // A watermark array consists of up to four watermarks. This means that a stream can contain a maximum of four watermarks.
// Text watermarks.
JSONObject textWaterMarks = new JSONObject();
textWaterMarks.put("WaterMarkTemplateId","<your waterMarkTemplateId>");
textWaterMarks.put("Type","Text");
// Specify the text to be used as watermarks for the Content parameter. The specified text must be encoded in Base64.
textWaterMarks.put("TextWaterMark","{\"Content\":\"5rWL6K+V5paH5a2X5rC05Y2w\",\"FontName\":\"SimSun\",\"FontSize\":\"16\",\"Top\":2,\"Left\":10}");
waterMarks.add(textWaterMarks);
com.aliyun.mts20140618.models.SubmitJobsRequest submitJobsRequest = new com.aliyun.mts20140618.models.SubmitJobsRequest()
// The job input.
.setInput("{\"Bucket\":\"exampleBucket\",\"Location\":\"oss-cn-shanghai\",\"Object\":\"example.flv\",\"Referer\": \"The parameter that you set in the Object Storage Service (OSS) console to enable the hotlink protection feature\"}")
// The job output configuration.
.setOutputs("[{\"OutputObject\":\"exampleOutput.mp4\",\"TemplateId\":\"6181666213ab41b9bc21da8ff5ff****\",\"WaterMarks\":" + waterMarks.toJSONString() + ",\"UserData\":\"testid-001\"}]")
// The OSS bucket in which the output file is stored.
.setOutputBucket("exampleBucket")
// The region in which the OSS bucket resides.
.setOutputLocation("oss-cn-shanghai")
// The ID of the MPS queue.
.setPipelineId("dd3dae411e704030b921e52698e5****");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.submitJobsWithOptions(submitJobsRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}Image watermark
/**
* Submit an image watermark job.
* @return
* @throws Exception
*/
public static void submitImageWaterMarkJobs() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// Configure the output settings of watermarks.
JSONArray waterMarks = new JSONArray(); // A watermark array consists of up to four watermarks. This means that a stream can contain a maximum of four watermarks.
// Image watermarks.
JSONObject imageWaterMarks = new JSONObject();
imageWaterMarks.put("WaterMarkTemplateId","<your waterMarkTemplateId>");
imageWaterMarks.put("Type","Image");
// The width and height of the image or the animated watermark.
imageWaterMarks.put("Width","200");
imageWaterMarks.put("Height","100");
// The path to the image to be used as watermarks.
JSONObject logoFile = new JSONObject();
logoFile.put("Bucket","<your bucket name>");
logoFile.put("Location","oss-cn-shanghai");
// 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.
logoFile.put("Object", URLEncoder.encode("Dynamic logo.apng", "utf-8"));
imageWaterMarks.put("InputFile",logoFile.toJSONString());
waterMarks.add(imageWaterMarks);
com.aliyun.mts20140618.models.SubmitJobsRequest submitJobsRequest = new com.aliyun.mts20140618.models.SubmitJobsRequest()
// The job input.
.setInput("{\"Bucket\":\"exampleBucket\",\"Location\":\"oss-cn-shanghai\",\"Object\":\"example.flv\",\"Referer\": \"The parameter that you set in the Object Storage Service (OSS) console to enable the hotlink protection feature\"}")
// The job output configuration.
.setOutputs("[{\"OutputObject\":\"exampleOutput.mp4\",\"TemplateId\":\"6181666213ab41b9bc21da8ff5ff****\",\"WaterMarks\":" + waterMarks.toJSONString() + ",\"UserData\":\"testid-001\"}]")
// The OSS bucket in which the output file is stored.
.setOutputBucket("exampleBucket")
// The region in which the OSS bucket resides.
.setOutputLocation("oss-cn-shanghai")
// The ID of the MPS queue.
.setPipelineId("dd3dae411e704030b921e52698e5****");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.submitJobsWithOptions(submitJobsRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}Sample code
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.tea.TeaException;
import java.net.URLEncoder;
public class WaterMark {
/**
* <b>description</b> :
* <p>Use your AccessKey pair to initialize the client.</p>
* @return Client
*
* @throws Exception
*/
public static com.aliyun.mts20140618.Client createClient() throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// Required. Make sure that the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is configured in the code runtime environment.
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// Required. Make sure that the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is configured.
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.endpoint = "mts.cn-shanghai.aliyuncs.com";
return new com.aliyun.mts20140618.Client(config);
}
/**
* Create a watermark template.
* @return
* @throws Exception
*/
public static void addWaterMarkTemplate() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// For more information about watermark parameters, visit https://www.alibabacloud.com/help/zh/mps/developer-reference/parameter-details.
JSONObject waterMarkConfig = new JSONObject();
waterMarkConfig.put("Dx","10");
waterMarkConfig.put("Dy","5");
waterMarkConfig.put("ReferPos","TopRight");
com.aliyun.mts20140618.models.AddWaterMarkTemplateRequest addWaterMarkTemplateRequest = new com.aliyun.mts20140618.models.AddWaterMarkTemplateRequest()
// The name of the watermark.
.setName("Name")
// The job output configuration.
.setConfig(waterMarkConfig.toJSONString());
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.addWaterMarkTemplateWithOptions(addWaterMarkTemplateRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}
/**
* Submit a text watermark job.
* @return
* @throws Exception
*/
public static void submitTextWaterMarkJobs() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// Configure the output settings of watermarks.
JSONArray waterMarks = new JSONArray(); // A watermark array consists of up to four watermarks. This means that a stream can contain a maximum of four watermarks.
// Text watermarks.
JSONObject textWaterMarks = new JSONObject();
textWaterMarks.put("WaterMarkTemplateId","<your waterMarkTemplateId>");
textWaterMarks.put("Type","Text");
// Specify the text to be used as watermarks for the Content parameter. The specified text must be encoded in Base64.
textWaterMarks.put("TextWaterMark","{\"Content\":\"5rWL6K+V5paH5a2X5rC05Y2w\",\"FontName\":\"SimSun\",\"FontSize\":\"16\",\"Top\":2,\"Left\":10}");
waterMarks.add(textWaterMarks);
com.aliyun.mts20140618.models.SubmitJobsRequest submitJobsRequest = new com.aliyun.mts20140618.models.SubmitJobsRequest()
// The job input.
.setInput("{\"Bucket\":\"exampleBucket\",\"Location\":\"oss-cn-shanghai\",\"Object\":\"example.flv\",\"Referer\": \"The parameter that you set in the Object Storage Service (OSS) console to enable the hotlink protection feature\"}")
// The job output configuration.
.setOutputs("[{\"OutputObject\":\"exampleOutput.mp4\",\"TemplateId\":\"6181666213ab41b9bc21da8ff5ff****\",\"WaterMarks\":" + waterMarks.toJSONString() + ",\"UserData\":\"testid-001\"}]")
// The OSS bucket in which the output file is stored.
.setOutputBucket("exampleBucket")
// The region in which the OSS bucket resides.
.setOutputLocation("oss-cn-shanghai")
// The ID of the MPS queue.
.setPipelineId("dd3dae411e704030b921e52698e5****");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.submitJobsWithOptions(submitJobsRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}
/**
* Submit an image watermark job.
* @return
* @throws Exception
*/
public static void submitImageWaterMarkJobs() throws Exception {
com.aliyun.mts20140618.Client client = WaterMark.createClient();
// Configure the output settings of watermarks.
JSONArray waterMarks = new JSONArray(); // A watermark array consists of up to four watermarks. This means that a stream can contain a maximum of four watermarks.
// Image watermarks.
JSONObject imageWaterMarks = new JSONObject();
imageWaterMarks.put("WaterMarkTemplateId","<your waterMarkTemplateId>");
imageWaterMarks.put("Type","Image");
// The width and height of the image or the animated watermark.
imageWaterMarks.put("Width","200");
imageWaterMarks.put("Height","100");
// The path to the image to be used as watermarks.
JSONObject logoFile = new JSONObject();
logoFile.put("Bucket","<your bucket name>");
logoFile.put("Location","oss-cn-shanghai");
// 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.
logoFile.put("Object", URLEncoder.encode("Dynamic logo.apng", "utf-8"));
imageWaterMarks.put("InputFile",logoFile.toJSONString());
waterMarks.add(imageWaterMarks);
com.aliyun.mts20140618.models.SubmitJobsRequest submitJobsRequest = new com.aliyun.mts20140618.models.SubmitJobsRequest()
// The job input.
.setInput("{\"Bucket\":\"exampleBucket\",\"Location\":\"oss-cn-shanghai\",\"Object\":\"example.flv\",\"Referer\": \"The parameter that you set in the Object Storage Service (OSS) console to enable the hotlink protection feature\"}")
// The job output configuration.
.setOutputs("[{\"OutputObject\":\"exampleOutput.mp4\",\"TemplateId\":\"6181666213ab41b9bc21da8ff5ff****\",\"WaterMarks\":" + waterMarks.toJSONString() + ",\"UserData\":\"testid-001\"}]")
// The OSS bucket in which the output file is stored.
.setOutputBucket("exampleBucket")
// The region in which the OSS bucket resides.
.setOutputLocation("oss-cn-shanghai")
// The ID of the MPS queue.
.setPipelineId("dd3dae411e704030b921e52698e5****");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Write your own code to display the response of the API operation if necessary.
client.submitJobsWithOptions(submitJobsRequest, runtime);
} catch (TeaException error) {
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// In real-world business scenarios, handle exceptions carefully and avoid ignoring them in your project. The exceptions in this example are for illustrative purposes only.
// The error message.
System.out.println(error.getMessage());
// The URL for troubleshooting.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
}
public static void main(String[] args_) throws Exception {
// Create a watermark template.
WaterMark.addWaterMarkTemplate();
// Submit an image watermark job.
//WaterMark.submitImageWaterMarkJobs();
// Submit a text watermark job.
//WaterMark.submitTextWaterMarkJobs();
}
}