The intelligent production and creation service provides professional online editing capabilities for standard templates. To handle repetitive tasks and custom enhancements in video production, you can use custom templates and replace media assets to produce videos in batches. This topic describes how to integrate the standard template editing web software development kit (SDK).
Integration instructions
Standard templates are created from video editing projects. Therefore, the standard template editing feature is integrated into the video editing web SDK. To use standard template editing, integrate the video editing web SDK and pass the mode parameter during initialization. For more information about how to integrate and initialize the video editing web SDK, see Integrate the video editing Web SDK.
window.AliyunVideoEditor.init({
mode: 'template'
......
});config property descriptions
Because standard templates are created from video editing projects, the config properties of the video editing web SDK also apply to standard template editing. For more information, see config property descriptions. In addition, the following parameters are added to the config properties for standard template editing:
Parameter | Type | Required | Description | Introduced in |
updateTemplate | (data: {coverUrl: string; duration: number; timeline: Timeline; isAuto: boolean}) => Promise<{projectId: string}>; | Yes | The parameter for the Save Template button in the standard template editing interface. This parameter saves the template's timeline. The input parameters are the project's thumbnail URL, duration in seconds, Timeline data, and an autosave flag. The template is autosaved once per minute. The returned Promise object must resolve with the project ID. | 3.7.0 |
init() sample code
The web SDK handles only interface interactions and does not initiate requests. You must implement the request logic that is called by the web SDK. This logic must send the request to your server. Your server then uses your AccessKey information (AccessKey ID and AccessKey secret) to forward the request to the relevant Alibaba Cloud OpenAPI.
// Note: The web SDK does not provide the request method. This is only an example. You can use your preferred network request library, such as axios.
window.AliyunVideoEditor.init({
container: document.getElementById('aliyun-video-editor'),
locale: 'en-US',
mode: 'template', // Enable standard template edit mode.
getEditingProjectMaterials: () => {
if (templateId) {
// The templateId is saved by the caller.
// For more information about the API, see https://help.aliyun.com/document_detail/277452.html
return request('GetTemplate', {
TemplateId: templateId,
RelatedMediaidFlag: 1 // If you add this parameter, the fields used to attach media assets are returned.
})
.then(res => {
const { RelatedMediaids } = res.data.Template;
const MediaIds = Object.values(JSON.parse(RelatedMediaids)).reduce(
(acc, cur) => acc.concat(cur),
[]
);
// Obtain resources that correspond to media asset IDs in batches.
// Use GetMediaInfo to query a single media asset. For more information, see https://help.aliyun.com/document_detail/197842.htm
return request('BatchGetMediaInfos', {
MediaIds,
AdditionType: 'FileInfo'
});
})
.then(res => {
return transMediaList(res.data.MediaInfos); // You must transform the data. For more information, see the following code.
});
}
return Promise.resolve([]);
},
searchMedia: mediaType => {
// mediaType indicates the media asset tab that the user is on. The value can be video, audio, or image. You can display addable media assets of the same type based on this parameter.
return new Promise(resolve => {
// The caller must implement the interface for displaying, selecting, and adding media assets. callDialog is only an example and is not provided by the web SDK.
// For more information about how to display media assets, see https://help.aliyun.com/document_detail/197964.html
callDialog({
onSubmit: async materials => {
// The materials are a list of media assets obtained by calling the ListMediaBasicInfos operation and transformed by transMediaList.
// For more information about the API, see https://help.aliyun.com/document_detail/277452.html
const res = await request('GetTemplate', {
TemplateId: templateId, // The templateId is saved by the caller.
RelatedMediaidFlag: 1 // If you add this parameter, the fields used to attach media assets are returned.
});
const { Template } = res.data;
const MediaIdsMap = JSON.parse(Template.RelatedMediaids); // Parse the currently attached media assets.
// Add the selected media assets.
materials.forEach(({ mediaType: type, mediaId }) => {
if (!MediaIdsMap[type]) {
MediaIdsMap[type] = [];
}
if (!MediaIdsMap[type].includes(mediaId)) {
MediaIdsMap[type].push(mediaId);
}
});
// Save the updated media assets.
// For more information about the API, see https://help.aliyun.com/document_detail/340673.html
await request('UpdateTemplate', {
TemplateId: templateId, // The templateId is saved by the caller.
RelatedMediaids: JSON.stringify(MediaIdsMap)
});
resolve(materials);
}
});
});
},
deleteEditingProjectMaterials: async (mediaId, mediaType) => {
// For more information about the API, see https://help.aliyun.com/document_detail/277452.html
const res = await request('GetTemplate', {
TemplateId: templateId, // The templateId is saved by the caller.
RelatedMediaidFlag: 1 // If you add this parameter, the fields used to attach media assets are returned.
});
const { Template } = res.data;
const MediaIdsMap = JSON.parse(Template.RelatedMediaids); // Parse the currently attached media assets.
// Remove the media asset to be deleted.
if (MediaIdsMap[mediaType] && MediaIdsMap[mediaType].includes(mediaId)) {
MediaIdsMap[mediaType].splice(MediaIdsMap[mediaType].indexOf(mediaId), 1);
// Save the updated media assets.
// For more information about the API, see https://help.aliyun.com/document_detail/340673.html
await request('UpdateTemplate', {
TemplateId: templateId, // The templateId is saved by the caller.
RelatedMediaids: JSON.stringify(MediaIdsMap)
});
return true;
}
return false;
},
getEditingProject: async () => {
// For more information about the API, see https://help.aliyun.com/document_detail/277452.html
const res = await request('GetTemplate', {
TemplateId: templateId // The templateId is saved by the caller.
});
const config = res.data.Template.Config;
return {
timeline: config ? JSON.parse(Config) : undefined
};
},
updateTemplate: async ({ coverUrl, timeline, isAuto }) => {
const updateParams = {
TemplateId: templateId, // The templateId is saved by the caller.
CoverURL: coverUrl,
Config: JSON.stringify(timeline)
};
// Save the updates.
// For more information about the API, see https://help.aliyun.com/document_detail/340673.html
await request('UpdateTemplate', updateParams);
}
// The updateEditingProject parameter is not used in template mode and does not need to be passed.
// The produceEditingProjectVideo parameter is not used in template mode and does not need to be passed.
});
/**
* Transform the server-side media asset information into the format required by the web SDK.
*/
function transMediaList(data) {
if (!data) return [];
if (Array.isArray(data)) {
return data.map(item => {
const basicInfo = item.MediaBasicInfo;
const fileBasicInfo = item.FileInfoList[0].FileBasicInfo;
const mediaId = basicInfo.MediaId;
const result = {
mediaId
};
const mediaType = basicInfo.MediaType;
result.mediaType = mediaType;
if (mediaType === 'video') {
result.video = {
title: fileBasicInfo.FileName,
duration: Number(fileBasicInfo.Duration),
// The width, height, and bitrate of the source video. This data is used to recommend synthetic data. If you do not pass these parameters or set them to 0, no data is recommended.
width: Number(fileBasicInfo.Width) || 0,
height: Number(fileBasicInfo.Height) || 0,
bitrate: Number(fileBasicInfo.Bitrate) || 0,
coverUrl: basicInfo.CoverURL
};
const spriteImages = basicInfo.SpriteImages;
if (spriteImages) {
try {
const spriteArr = JSON.parse(spriteImages);
const sprite = spriteArr[0];
const config = JSON.parse(sprite.Config);
result.video.spriteConfig = {
num: config.Num,
lines: config.SpriteSnapshotConfig?.Lines,
cols: config.SpriteSnapshotConfig?.Columns,
cellWidth: config.SpriteSnapshotConfig?.CellWidth,
cellHeight: config.SpriteSnapshotConfig?.CellHeight
};
result.video.sprites = sprite.SnapshotUrlList;
} catch (e) {
console.log(e);
}
}
} else if (mediaType === 'audio') {
result.audio = {
title: fileBasicInfo.FileName,
duration: Number(fileBasicInfo.Duration),
coverURL: '' // You can specify a default thumbnail for the audio file.
};
} else if (mediaType === 'image') {
result.image = {
title: fileBasicInfo.FileName,
coverUrl: fileBasicInfo.FileUrl,
// The width and height of the image. This data is used to recommend synthetic data. If you do not pass these parameters or set them to 0, no data is recommended.
width: Number(fileBasicInfo.Width) || 0,
height: Number(fileBasicInfo.Height) || 0
};
}
return result;
});
} else {
return [data];
}
}