createMediaSmartCoverJob
Generate intelligent video thumbnails by analyzing content to select optimal cover frames for media files stored in cloud storage.
Instructions
创建媒体智能封面任务
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| objectKey | Yes | 对象在存储桶里的路径 |
Input Schema (JSON Schema)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false,
"properties": {
"objectKey": {
"description": "对象在存储桶里的路径",
"type": "string"
}
},
"required": [
"objectKey"
],
"type": "object"
}
Implementation Reference
- src/server.ts:448-466 (registration)MCP tool registration for 'createMediaSmartCoverJob', including inline schema (objectKey: string), description, and handler function that delegates to CIMediaService.createMediaSmartCoverJobserver.tool( 'createMediaSmartCoverJob', '创建媒体智能封面任务', { objectKey: z.string().describe('对象在存储桶里的路径'), }, async ({ objectKey }) => { const res = await CIMediaInstance.createMediaSmartCoverJob(objectKey); return { content: [ { type: 'text', text: JSON.stringify(res.data, null, 2), }, ], isError: !res.isSuccess, }; }, );
- src/services/ci/media.service.ts:13-136 (handler)Core handler logic in CIMediaService.createMediaSmartCoverJob: submits SmartCover job to Tencent COS CI via POST /jobs, generates output path, polls status up to 10 times until success or failure.async createMediaSmartCoverJob(objectKey: string) { try { var host = this.bucket + '.ci.' + this.region + '.myqcloud.com/jobs'; var url = 'https://' + host; const lastDotIndex = objectKey.lastIndexOf('.'); const base = lastDotIndex === -1 ? objectKey : objectKey.substring(0, lastDotIndex); const outPutObject = `${base}_\${jobid}_\${number}`; var body = COS.util.json2xml({ Request: { Tag: 'SmartCover', Input: { Object: objectKey, // 存在cos里的路径 }, Operation: { Output: { Bucket: this.bucket, Region: this.region, Object: outPutObject, // 转码后存到cos的路径 }, SmartCover: { Count: 1, }, }, }, }); const createResult = await new Promise((resolve, reject) => { this.cos.request( { Key: 'jobs', Method: 'POST', // 固定值 Url: url, Body: body, ContentType: 'application/xml', }, (error, data) => (error ? reject(error) : resolve(data)), ); }); try { const jobsDetail = (createResult as any).Response.JobsDetail; const initialCode = jobsDetail.Code; const initialState = jobsDetail.State; if (initialCode == 'Failed') { return { isSuccess: false, message: '智能封面任务失败', data: createResult, }; } if (initialState == 'Success') { return { isSuccess: true, message: '智能封面任务成功', data: createResult, }; } else { const jobId = jobsDetail.JobId; // 开始轮询 let pollResult: any; const maxAttempts = 10; const interval = 4000; for (let attempt = 0; attempt < maxAttempts; attempt++) { // 首次立即执行,后续等待间隔 if (attempt > 0) await new Promise((r) => setTimeout(r, interval)); try { // 查询任务状态 const { data: getResult } = await this.describeMediaJob(jobId); const describeJobsDetail = (getResult as any).Response.JobsDetail; const describeJobCode = describeJobsDetail.Code; const describeJobState = describeJobsDetail.State; // 处理终态 if ( describeJobCode === 'Success' && describeJobState == 'Success' ) { pollResult = getResult; break; } else if (describeJobCode === 'Failed') { return { isSuccess: false, message: '智能封面任务失败', data: getResult, }; } } catch (err) { // lastError = err as Error; // 记录错误继续重试 } } if (!pollResult) { return { isSuccess: false, message: `轮询超时(${maxAttempts}次未完成)`, data: createResult, }; } return { isSuccess: true, message: '智能封面任务成功', data: pollResult, }; } } catch (error) { return { isSuccess: false, message: '智能封面任务失败', data: error, }; } } catch (error) { return { isSuccess: false, message: '智能封面任务失败', data: error, }; } }