import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.ice20201109.Client;
import com.aliyun.ice20201109.models.*;
import com.aliyun.teaopenapi.models.Config;
import java.util.*;
// 成功視頻
// http://oushu-test-shanghai.oss-cn-shanghai.aliyuncs.com/ice_output/46b29eb5775f4f758846171ab79bfca7.mp4
/**
* 需要maven引入二方包依賴:
* <dependency>
* <groupId>com.aliyun</groupId>
* <artifactId>ice20201109</artifactId>
* <version>2.1.0</version>
* </dependency>
* <dependency>
* <groupId>com.alibaba</groupId>
* <artifactId>fastjson</artifactId>
* <version>1.2.9</version>
* </dependency>
*/
public class BatchProduceAlignment {
static final String regionId = "cn-shanghai";
static final String bucket = "第三步建立的bucket";
private Client iceClient;
public static void main(String[] args) {
try {
BatchProduceAlignment batchProduce = new BatchProduceAlignment();
batchProduce.initClient();
batchProduce.run();
} catch (Exception e) {
System.out.println("Produce failed. Exception: " + e.toString());
}
}
public void initClient() throws Exception {
// 阿里雲帳號AccessKey擁有所有API的存取權限,建議您使用RAM使用者進行API訪問或日常營運。
// 本樣本以將AccessKey ID和 AccessKey Secret儲存在環境變數為例說明。配置方法請參見:https://www.alibabacloud.com/help/zh/sdk/developer-reference/v2-manage-access-credentials
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
Config config = new Config();
config.setCredential(credentialClient);
// 如需寫入程式碼AccessKey ID和AccessKey Secret,代碼如下,但強烈建議不要把AccessKey ID和AccessKey Secret儲存到工程代碼裡,否則可能導致AccessKey泄露,威脅您帳號下所有資源的安全。
// config.accessKeyId = <第二步建立的AccessKey ID>;
// config.accessKeySecret = <第二步建立的AccessKey Secret>;
config.endpoint = "ice." + regionId + ".aliyuncs.com";
config.regionId = regionId;
iceClient = new Client(config);
}
public void run() throws Exception {
// 文字素材
String text = "人們懂得用五味雜陳形容人生,因為懂得味道是每個人心中固守的情懷。在這個時代,每一個人都經歷了太多的苦痛和喜悅,人們總會將苦澀藏在心裡,而把幸福變成食物,呈現在四季的餐桌之上";
// 視頻素材
String[] videoArray = new String[]{
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f1.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f2.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f3.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f4.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f5.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f6.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f7.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f8.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f9.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f10.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f11.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f12.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f13.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f14.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f15.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f16.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f17.mp4",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f18.mp4"
};
// 背景音樂素材
String[] bgMusicArray = new String[]{
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m1.wav",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m2.wav",
"https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m3.wav"
};
// 視頻標題
String title = "舌尖上的美食";
// 產生的成片數
int produceCount = 3;
// 批量提交任務
List<String> jobIds = new ArrayList<String>();
for (int i = 0; i < produceCount; i++) {
String jobId = produceSingleVideo(title, text, videoArray, bgMusicArray);
jobIds.add(jobId);
}
// 輪詢任務狀態直到全部結束
System.out.println("waiting job finished...");
while (true) {
Thread.sleep(3000);
boolean allFinished = true;
for (int i = 0; i < jobIds.size(); i++) {
String jobId = jobIds.get(i);
GetMediaProducingJobRequest req = new GetMediaProducingJobRequest();
req.setJobId(jobId);
GetMediaProducingJobResponse response = iceClient.getMediaProducingJob(req);
GetMediaProducingJobResponseBody.GetMediaProducingJobResponseBodyMediaProducingJob mediaProducingJob = response.getBody().getMediaProducingJob();
String status = mediaProducingJob.getStatus();
System.out.println("jobId: " + mediaProducingJob.getJobId() + ", status:" + status);
if ("Failed".equalsIgnoreCase(status)) {
System.out.println("jobfailed. jobInfo: " + JSONObject.toJSONString(mediaProducingJob));
throw new Exception("Produce failed. jobid: " + mediaProducingJob.getJobId());
}
if (!"Success".equalsIgnoreCase(status)) {
allFinished = false;
break;
}
}
if (allFinished) {
System.out.println("all job finished.");
break;
}
}
}
public String produceSingleVideo(String title, String text, String[] videoArray, String[] bgMusicArray) throws Exception {
text = text.replace(",", "。");
text = text.replace("\n", "。");
String[] sentenceArray = text.split("。");
JSONArray videoClipArray = new JSONArray();
JSONArray audioClipArray = new JSONArray();
List<String> videoList = Arrays.asList(videoArray);
Collections.shuffle(videoList);
for (int i = 0; i < sentenceArray.length; i++) {
String sentence = sentenceArray[i];
String clipId = "clip" + i;
String videoUrl = videoList.get(i);
String videoClip = "{\"MediaURL\":\""+videoUrl+"\",\"ReferenceClipId\":\""+clipId+"\",\"Effects\":[{\"Type\":\"Background\",\"SubType\":\"Blur\",\"Radius\":0.1}]}";
videoClipArray.add(JSONObject.parseObject(videoClip));
String audioClip = "{\"Type\":\"AI_TTS\",\"Content\":\"" + sentence + "\",\"Voice\":\"zhichu\",\"ClipId\":\""+clipId+"\",\"Effects\":[{\"Type\":\"AI_ASR\",\"Font\":\"Alibaba PuHuiTi\",\"Alignment\":\"TopCenter\",\"Y\":0.75,\"FontSize\":55,\"FontColor\":\"#ffffff\",\"AdaptMode\":\"AutoWrap\",\"TextWidth\":0.8,\"Outline\":2,\"OutlineColour\":\"#000000\"}]}";
audioClipArray.add(JSONObject.parseObject(audioClip));
}
String subtitleTrack = "{\"SubtitleTrackClips\":[{\"Type\":\"Text\",\"Font\":\"HappyZcool-2016\",\"Content\":\""+title+"\",\"FontSize\":80,\"FontColor\":\"#ffffff\",\"Y\":0.15,\"Alignment\":\"TopCenter\",\"EffectColorStyle\":\"CS0004-000005\",\"FontFace\":{\"Bold\":true,\"Italic\":false,\"Underline\":false}}]}";
int bgMusicIndex = (int)(Math.random() * bgMusicArray.length);
String bgMusicUrl = bgMusicArray[bgMusicIndex];
String timeline = "{\"VideoTracks\":[{\"VideoTrackClips\":"+videoClipArray.toJSONString()+"}],\"AudioTracks\":[{\"AudioTrackClips\":"+audioClipArray.toJSONString()+"},{\"AudioTrackClips\":[{\"MediaURL\":\""+bgMusicUrl+"\"}]}],\"SubtitleTracks\":[" + subtitleTrack + "]}";
//
String targetFileName = UUID.randomUUID().toString().replace("-", "");
String outputMediaUrl = "http://" + bucket + ".oss-" + regionId + ".aliyuncs.com/ice_output/" + targetFileName + ".mp4";
int width = 720;
int height = 1280;
String outputMediaConfig = "{\"MediaURL\":\"" + outputMediaUrl + "\",\"Width\":"+width+",\"Height\":"+height+"}";
SubmitMediaProducingJobRequest request = new SubmitMediaProducingJobRequest();
request.setTimeline(timeline);
request.setOutputMediaConfig(outputMediaConfig);
SubmitMediaProducingJobResponse response = iceClient.submitMediaProducingJob(request);
System.out.println("start job. jobid: " + response.getBody().getJobId() + ", outputMediaUrl: " + outputMediaUrl);
return response.getBody().getJobId();
}
}