JY API 草稿与素材创建接口使用指南
📋 概述
本文档详细介绍如何使用JY API的十个核心接口:
create_draft
- 创建空白草稿easy_create_material
- 在草稿中添加素材add_audios
- 批量添加音频到草稿add_captions
- 批量添加字幕到草稿add_effects
- 批量添加特效到草稿add_images
- 批量添加图片到草稿add_keyframes
- 批量添加关键帧动画到草稿add_masks
- 批量添加遮罩效果到草稿add_sticker
- 添加贴纸装饰到草稿add_videos
- 批量添加视频到草稿
这些接口配合使用可以实现完整的视频草稿创建、多媒体素材添加、专业级动画制作、视觉效果处理、装饰元素添加和高级视频合成工作流程。
🌐 服务器信息
- 基础URL:
https://jy-api.fyshark.com
- API版本: v1.0.0
- 内容类型:
application/json
📑 接口目录
- 创建草稿接口 (create_draft)
- 创建素材接口 (easy_create_material)
- 批量添加音频接口 (add_audios)
- 批量添加字幕接口 (add_captions)
- 批量添加特效接口 (add_effects)
- 批量添加图片接口 (add_images)
- 批量添加关键帧接口 (add_keyframes)
- 批量添加遮罩接口 (add_masks)
- 添加贴纸接口 (add_sticker)
- 批量添加视频接口 (add_videos)
- 完整工作流程示例
- 错误处理
- 最佳实践
1. 创建草稿接口 (create_draft)
接口信息
POST /api/drafts/create_draft
功能描述
创建一个空白的视频草稿,设置基本的画布尺寸和配置。这是整个工作流程的第一步。
请求参数
{
"width": 1080, // 可选,草稿宽度,默认1080
"height": 1920, // 可选,草稿高度,默认1920
"user_id": 12345 // 可选,用户ID,如果提供会保存草稿记录
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
width | number | 否 | 1080 | 草稿画布宽度(像素) |
height | number | 否 | 1920 | 草稿画布高度(像素) |
user_id | number | 否 | - | 用户ID,用于草稿记录关联 |
响应格式
成功响应 (200)
{
"status": "success",
"message": "草稿创建成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=https://video-snot-12220.oss-cn-shanghai.aliyuncs.com/2025-08-01/draft/a97ada87-d30e-4c26-8a91-b9595e319822.json",
"tip_url": "快速入门必看指南,请访问:https://www.51aigc.cc/#/cozeTutorial/detail/13",
"record_saved": false
}
}
错误响应 (500)
{
"status": "error",
"message": "创建草稿失败",
"error": "具体错误信息"
}
使用示例
1. 基本创建(使用默认尺寸)
curl -X POST https://jy-api.fyshark.com/api/drafts/create_draft \
-H "Content-Type: application/json" \
-d '{}'
2. 指定尺寸创建
curl -X POST https://jy-api.fyshark.com/api/drafts/create_draft \
-H "Content-Type: application/json" \
-d '{
"width": 720,
"height": 1280
}'
3. 包含用户ID的创建
curl -X POST https://jy-api.fyshark.com/api/drafts/create_draft \
-H "Content-Type: application/json" \
-d '{
"width": 1080,
"height": 1920,
"user_id": 12345
}'
4. JavaScript 示例
const createDraft = async (width = 1080, height = 1920, userId = null) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/create_draft', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
width,
height,
user_id: userId
})
});
const result = await response.json();
if (result.status === 'success') {
console.log('草稿创建成功:', result.data.draft_url);
return result.data.draft_url;
} else {
throw new Error(result.message);
}
};
// 使用示例
try {
const draftUrl = await createDraft(1080, 1920, 12345);
console.log('新草稿URL:', draftUrl);
} catch (error) {
console.error('创建失败:', error.message);
}
2. 创建素材接口 (easy_create_material)
接口信息
POST /api/drafts/easy_create_material
功能描述
在现有草稿中添加音频、视频、图片和文字素材。支持多种媒体类型的组合添加,自动处理素材的时长、尺寸和样式。
请求参数
{
"text": "示例文字", // 可选,文字内容
"img_url": "https://example.com/image.jpg", // 可选,图片URL
"video_url": "https://example.com/video.mp4", // 可选,视频URL
"audio_url": "https://example.com/audio.mp3", // 必填,音频URL
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...", // 必填,目标草稿URL
"text_color": "#ffffff", // 可选,文字颜色,默认白色
"font_size": 15, // 可选,字体大小,默认15
"text_transform_y": 100 // 可选,文字Y轴位置偏移
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
audio_url | string | ✅ | - | 音频文件URL,系统会自动获取时长 |
draft_url | string | ✅ | - | 目标草稿的完整URL |
text | string | 否 | - | 要添加的文字内容 |
img_url | string | 否 | - | 图片URL,系统会自动获取尺寸 |
video_url | string | 否 | - | 视频URL |
text_color | string | 否 | "#ffffff" | 文字颜色,十六进制格式 |
font_size | number | 否 | 15 | 字体大小 |
text_transform_y | number | 否 | - | 文字在Y轴的位置偏移 |
响应格式
成功响应 (200)
{
"status": "success",
"message": "素材创建成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=..."
}
}
错误响应
{
"status": "error",
"message": "错误信息",
"draft_url": "原始草稿URL(如果提供)"
}
常见错误信息
"draft_url是必填项"
- 缺少必要的草稿URL参数"音频链接不能为空"
- 音频URL为空或为"null""音频链接无效或无法获取音频时长"
- 音频文件无法访问或解析"草稿处理失败"
- 草稿内容获取或处理失败
使用示例
1. 基本素材添加(音频+文字)
curl -X POST https://jy-api.fyshark.com/api/drafts/easy_create_material \
-H "Content-Type: application/json" \
-d '{
"text": "Hello World",
"audio_url": "https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/24631f7d1dd449e594097b6586b7d1b0.mp3",
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=YOUR_DRAFT_URL"
}'
2. 完整素材添加(所有类型)
curl -X POST https://jy-api.fyshark.com/api/drafts/easy_create_material \
-H "Content-Type: application/json" \
-d '{
"text": "完整测试",
"img_url": "https://s.coze.cn/t/JTa5Ne6_liY/",
"video_url": "https://example.com/video.mp4",
"audio_url": "https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/24631f7d1dd449e594097b6586b7d1b0.mp3",
"draft_url": "YOUR_DRAFT_URL",
"text_color": "#ff0000",
"font_size": 20,
"text_transform_y": 150
}'
3. JavaScript 示例
const addMaterialToDraft = async (draftUrl, materials) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/easy_create_material', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
draft_url: draftUrl,
...materials
})
});
const result = await response.json();
if (result.status === 'success') {
console.log('素材添加成功:', result.data.draft_url);
return result.data.draft_url;
} else {
throw new Error(result.message);
}
};
// 使用示例
const materials = {
text: "我的视频标题",
audio_url: "https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/24631f7d1dd449e594097b6586b7d1b0.mp3",
img_url: "https://s.coze.cn/t/JTa5Ne6_liY/",
text_color: "#00ff00",
font_size: 18
};
try {
const updatedDraftUrl = await addMaterialToDraft(draftUrl, materials);
console.log('更新后的草稿:', updatedDraftUrl);
} catch (error) {
console.error('添加素材失败:', error.message);
}
3. 批量添加音频接口 (add_audios)
接口信息
POST /api/drafts/add_audios
功能描述
向现有草稿中批量添加音频轨道和音频片段。支持多个音频文件的同时添加,每个音频可以设置不同的时间范围、音量和音效。
请求参数
{
"audio_infos": "[{\"audio_url\":\"https://example.com/audio.mp3\",\"duration\":23184000,\"end\":23184000,\"start\":0,\"volume\":1.0}]",
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=..."
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
audio_infos | string | ✅ | - | JSON字符串格式的音频信息数组 |
draft_url | string | ✅ | - | 目标草稿的完整URL |
audio_infos 数组元素说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
audio_url | string | ✅ | - | 音频文件URL |
duration | number | ✅ | - | 音频总时长(微秒) |
start | number | ✅ | - | 音频片段开始时间(微秒) |
end | number | ✅ | - | 音频片段结束时间(微秒) |
volume | number | 否 | 1.0 | 音频音量(0.0-2.0) |
audio_effect | string | 否 | - | 音频效果名称 |
响应格式
成功响应 (200)
{
"status": "success",
"message": "音频添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"track_id": "audio_track_123",
"audio_ids": ["audio_001", "audio_002"]
}
}
错误响应
{
"status": "error",
"message": "音频信息验证失败",
"errors": ["audio_infos[0].audio_url is required"]
}
使用示例
1. 基本音频添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_audios \
-H "Content-Type: application/json" \
-d '{
"audio_infos": "[{\"audio_url\":\"https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/sami/tts/fe9baa8f474e4a20a293b7228707ff9c.mp3\",\"duration\":23184000,\"end\":23184000,\"start\":0}]",
"draft_url": "YOUR_DRAFT_URL"
}'
2. 多音频批量添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_audios \
-H "Content-Type: application/json" \
-d '{
"audio_infos": "[{\"audio_url\":\"https://example.com/audio1.mp3\",\"duration\":10000000,\"start\":0,\"end\":10000000,\"volume\":0.8},{\"audio_url\":\"https://example.com/audio2.mp3\",\"duration\":15000000,\"start\":5000000,\"end\":15000000,\"volume\":1.2}]",
"draft_url": "YOUR_DRAFT_URL"
}'
3. JavaScript 示例
const addAudios = async (audioInfos, draftUrl) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_audios', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
audio_infos: JSON.stringify(audioInfos),
draft_url: draftUrl
})
});
const result = await response.json();
return result;
};
// 使用示例
const audioInfos = [
{
audio_url: "https://example.com/audio1.mp3",
duration: 23184000,
start: 0,
end: 23184000,
volume: 1.0
},
{
audio_url: "https://example.com/audio2.mp3",
duration: 15000000,
start: 5000000,
end: 15000000,
volume: 0.8
}
];
try {
const result = await addAudios(audioInfos, draftUrl);
console.log('音频添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
4. 批量添加字幕接口 (add_captions)
接口信息
POST /api/drafts/add_captions
功能描述
向现有草稿中添加字幕轨道和字幕片段。支持丰富的字幕样式设置,包括关键词高亮、字体样式、边框效果、对齐方式、透明度和动画效果等。
请求参数
{
"captions": "[{\"start\":0,\"end\":10000000,\"text\":\"你好,剪映\",\"keyword\":\"好\",\"keyword_color\":\"#457616\",\"keyword_font_size\":15}]",
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"text_color": "#ff1837",
"border_color": "#fe8a80",
"alignment": 2,
"alpha": 0.5
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
captions | string | ✅ | - | JSON字符串格式的字幕信息数组 |
draft_url | string | ✅ | - | 目标草稿的完整URL |
text_color | string | 否 | "#ffffff" | 文本颜色(十六进制) |
border_color | string | 否 | - | 边框颜色(十六进制) |
alignment | number | 否 | 1 | 文本对齐方式(0-5) |
alpha | number | 否 | 1.0 | 文本透明度(0.0-1.0) |
响应格式
成功响应 (200)
{
"status": "success",
"message": "字幕添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"track_id": "text_track_123",
"text_ids": ["text_001", "text_002"],
"segment_ids": ["seg_001", "seg_002"],
"segment_infos": [
{
"id": "seg_001",
"start": 0,
"end": 10000000
}
]
}
}
使用示例
1. 基本字幕添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_captions \
-H "Content-Type: application/json" \
-d '{
"captions": "[{\"start\":0,\"end\":10000000,\"text\":\"你好,剪映\",\"keyword\":\"好\",\"keyword_color\":\"#457616\"}]",
"draft_url": "YOUR_DRAFT_URL",
"text_color": "#ff1837",
"alignment": 2
}'
2. 带动画效果的字幕
curl -X POST https://jy-api.fyshark.com/api/drafts/add_captions \
-H "Content-Type: application/json" \
-d '{
"captions": "[{\"start\":0,\"end\":10000000,\"text\":\"欢迎使用字幕功能\",\"in_animation\":\"fade_in\",\"out_animation\":\"fade_out\"}]",
"draft_url": "YOUR_DRAFT_URL",
"text_color": "#ffffff",
"alpha": 0.8
}'
3. JavaScript 示例
const addCaptions = async (captionsData, draftUrl, options = {}) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_captions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
captions: JSON.stringify(captionsData),
draft_url: draftUrl,
text_color: options.textColor || "#ffffff",
border_color: options.borderColor,
alignment: options.alignment || 1,
alpha: options.alpha || 1.0
})
});
const result = await response.json();
return result;
};
// 使用示例
const captions = [
{
start: 0,
end: 10000000,
text: "你好,剪映",
keyword: "好|剪映",
keyword_color: "#457616",
keyword_font_size: 15
},
{
start: 10000000,
end: 20000000,
text: "欢迎使用字幕功能",
in_animation: "fade_in",
out_animation: "fade_out"
}
];
try {
const result = await addCaptions(captions, draftUrl, {
textColor: "#ff1837",
borderColor: "#fe8a80",
alignment: 2,
alpha: 0.8
});
console.log('字幕添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
高级功能
关键词高亮
{
"text": "你好,剪映",
"keyword": "好|剪映",
"keyword_color": "#ff0000",
"keyword_font_size": 18
}
动画效果
{
"in_animation": "fade_in",
"out_animation": "fade_out",
"in_animation_duration": 1000000,
"out_animation_duration": 1000000
}
5. 批量添加特效接口 (add_effects)
接口信息
POST /api/drafts/add_effects
功能描述
向现有草稿中添加视频特效轨道和特效片段。支持批量添加多种视频特效,包括边框特效、滤镜特效、动态特效等,为视频内容增加丰富的视觉效果。
请求参数
{
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"effect_infos": "[{\"effect_title\":\"录制边框 III\",\"end\":5000000,\"start\":0}]"
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
effect_infos | string | ✅ | - | JSON字符串格式的特效信息数组 |
响应格式
成功响应 (200)
{
"status": "success",
"message": "特效添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"track_id": "effect_track_123",
"effect_ids": ["effect_001", "effect_002"],
"segment_ids": ["seg_001", "seg_002"]
}
}
使用示例
1. 基本特效添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_effects \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"effect_infos": "[{\"effect_title\":\"录制边框 III\",\"end\":5000000,\"start\":0}]"
}'
2. 多特效添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_effects \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"effect_infos": "[{\"effect_title\":\"录制边框\",\"end\":10000000,\"start\":2000000},{\"effect_title\":\"淡入效果\",\"end\":5000000,\"start\":0}]"
}'
3. JavaScript 示例
const addEffects = async (effectsData, draftUrl) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_effects', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
effect_infos: JSON.stringify(effectsData),
draft_url: draftUrl
})
});
const result = await response.json();
return result;
};
// 使用示例
const effects = [
{
effect_title: "录制边框 III",
start: 0,
end: 5000000
},
{
effect_title: "复古滤镜",
start: 2000000,
end: 8000000
}
];
try {
const result = await addEffects(effects, draftUrl);
console.log('特效添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
常见特效类型
边框特效
{
"effect_title": "录制边框 III",
"start": 0,
"end": 10000000
}
滤镜特效
{
"effect_title": "复古滤镜",
"start": 0,
"end": 15000000
}
动态特效
{
"effect_title": "粒子效果",
"start": 5000000,
"end": 20000000
}
6. 批量添加图片接口 (add_images)
接口信息
POST /api/drafts/add_images
功能描述
向现有草稿中批量添加图片素材,支持丰富的视觉效果设置。该接口可以一次性添加多张图片到视频轨道,支持透明度控制、动画效果、缩放变换、位置调整以及转场效果,为视频创作提供强大的图片处理能力。
请求参数
{
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"image_infos": "[{\"image_url\":\"https://s.coze.cn/t/XpufYwc2_u4/\",\"width\":1024,\"height\":1024,\"start\":0,\"end\":1000000}]",
"alpha": 0.5,
"scale_x": 1.0,
"scale_y": 1.0,
"transform_x": 0,
"transform_y": 0
}
参数说明
参数 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
image_infos | string | ✅ | - | JSON字符串格式的图片信息数组 |
alpha | number | ❌ | 1.0 | 全局透明度,范围0-1 |
scale_x | number | ❌ | 1.0 | X轴缩放比例 |
scale_y | number | ❌ | 1.0 | Y轴缩放比例 |
transform_x | number | ❌ | 0 | X轴位置偏移(像素) |
transform_y | number | ❌ | 0 | Y轴位置偏移(像素) |
响应格式
成功响应 (200)
{
"status": "success",
"message": "图片添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"track_id": "video_track_123",
"image_ids": ["image_001", "image_002"],
"segment_ids": ["seg_001", "seg_002"],
"segment_infos": [
{
"id": "seg_001",
"start": 0,
"end": 1000000
}
]
}
}
使用示例
1. 基本图片添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_images \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"image_infos": "[{\"image_url\":\"https://s.coze.cn/t/XpufYwc2_u4/\",\"width\":1024,\"height\":1024,\"start\":0,\"end\":1000000}]"
}'
2. 带动画效果的多图片
curl -X POST https://jy-api.fyshark.com/api/drafts/add_images \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"image_infos": "[{\"image_url\":\"https://example.com/image1.jpg\",\"width\":800,\"height\":600,\"start\":0,\"end\":2000000,\"in_animation\":\"淡入\",\"out_animation\":\"淡出\"},{\"image_url\":\"https://example.com/image2.jpg\",\"width\":1024,\"height\":1024,\"start\":2500000,\"end\":4500000}]",
"alpha": 0.8,
"scale_x": 1.2,
"scale_y": 1.2
}'
3. JavaScript 示例
const addImages = async (imagesData, draftUrl, options = {}) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_images', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
image_infos: JSON.stringify(imagesData),
draft_url: draftUrl,
...options
})
});
const result = await response.json();
return result;
};
// 使用示例
const images = [
{
image_url: "https://example.com/image1.jpg",
width: 1024,
height: 1024,
start: 0,
end: 2000000,
in_animation: "淡入",
in_animation_duration: 500000
},
{
image_url: "https://example.com/image2.jpg",
width: 800,
height: 600,
start: 2500000,
end: 4500000,
transition: "淡入淡出",
transition_duration: 1000000
}
];
const options = {
alpha: 0.9,
scale_x: 1.1,
scale_y: 1.1,
transform_y: 100
};
try {
const result = await addImages(images, draftUrl, options);
console.log('图片添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
图片动画类型
入场动画
{
"in_animation": "淡入",
"in_animation_duration": 500000
}
出场动画
{
"out_animation": "淡出",
"out_animation_duration": 500000
}
循环动画
{
"loop_animation": "呼吸",
"loop_animation_duration": 2000000
}
转场效果
{
"transition": "淡入淡出",
"transition_duration": 1000000
}
7. 批量添加关键帧接口 (add_keyframes)
接口信息
POST /api/drafts/add_keyframes
功能描述
向现有草稿中的指定片段添加关键帧动画。关键帧动画是视频编辑中的高级功能,通过在时间轴上设置不同时间点的属性值,系统会自动计算中间过渡效果,创造出平滑的动画变化。支持位置、缩放、旋转、透明度等多种属性的关键帧动画。
请求参数
{
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"keyframes": "[{\"offset\":0,\"property\":\"KFTypePositionX\",\"segment_id\":\"d62994b4-25fe-422a-a123-87ef05038558\",\"value\":-0.1}]"
}
参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
keyframes | string | ✅ | - | JSON字符串格式的关键帧信息数组 |
keyframes 数组元素说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
segment_id | string | ✅ | - | 目标片段的唯一标识ID |
property | string | ✅ | - | 动画属性类型 |
offset | number | ✅ | - | 关键帧在片段中的时间偏移(0-1范围) |
value | number | ✅ | - | 属性在该时间点的值 |
支持的动画属性类型
属性类型 | 描述 | 值范围 | 示例 |
---|---|---|---|
KFTypePositionX | X轴位置 | -1.0 到 1.0 | 0.0 (居中), -0.5 (左移), 0.5 (右移) |
KFTypePositionY | Y轴位置 | -1.0 到 1.0 | 0.0 (居中), -0.5 (上移), 0.5 (下移) |
KFTypeScaleX | X轴缩放 | 0.1 到 10.0 | 1.0 (原始), 0.5 (缩小), 2.0 (放大) |
KFTypeScaleY | Y轴缩放 | 0.1 到 10.0 | 1.0 (原始), 0.5 (缩小), 2.0 (放大) |
KFTypeRotation | 旋转角度 | -360 到 360 | 0 (无旋转), 90 (顺时针90度) |
KFTypeAlpha | 透明度 | 0.0 到 1.0 | 1.0 (不透明), 0.5 (半透明), 0.0 (透明) |
响应格式
成功响应 (200)
{
"status": "success",
"message": "关键帧添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"keyframes_added": 3,
"affected_segments": ["segment_001", "segment_002"]
}
}
使用示例
1. 基本位置动画
curl -X POST https://jy-api.fyshark.com/api/drafts/add_keyframes \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"keyframes": "[{\"offset\":0,\"property\":\"KFTypePositionX\",\"segment_id\":\"your-segment-id\",\"value\":-0.5},{\"offset\":1,\"property\":\"KFTypePositionX\",\"segment_id\":\"your-segment-id\",\"value\":0.5}]"
}'
2. 缩放呼吸动画
curl -X POST https://jy-api.fyshark.com/api/drafts/add_keyframes \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"keyframes": "[{\"offset\":0,\"property\":\"KFTypeScaleX\",\"segment_id\":\"your-segment-id\",\"value\":0.8},{\"offset\":0.5,\"property\":\"KFTypeScaleX\",\"segment_id\":\"your-segment-id\",\"value\":1.2},{\"offset\":1,\"property\":\"KFTypeScaleX\",\"segment_id\":\"your-segment-id\",\"value\":1.0}]"
}'
3. JavaScript 示例
const addKeyframes = async (keyframesData, draftUrl) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_keyframes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
keyframes: JSON.stringify(keyframesData),
draft_url: draftUrl
})
});
const result = await response.json();
return result;
};
// 使用示例 - 位置移动动画
const positionKeyframes = [
{
segment_id: "your-segment-id",
property: "KFTypePositionX",
offset: 0,
value: -0.5 // 开始位置:左侧
},
{
segment_id: "your-segment-id",
property: "KFTypePositionX",
offset: 1,
value: 0.5 // 结束位置:右侧
}
];
try {
const result = await addKeyframes(positionKeyframes, draftUrl);
console.log('关键帧添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
关键帧动画类型
位置动画
{
"property": "KFTypePositionX",
"offset": 0,
"value": -0.5
}
缩放动画
{
"property": "KFTypeScaleX",
"offset": 0.5,
"value": 1.2
}
旋转动画
{
"property": "KFTypeRotation",
"offset": 1,
"value": 360
}
透明度动画
{
"property": "KFTypeAlpha",
"offset": 0,
"value": 0.0
}
8. 批量添加遮罩接口 (add_masks)
接口信息
POST /api/drafts/add_masks
功能描述
向现有草稿中的指定片段添加遮罩效果。遮罩是视频编辑中的重要功能,通过遮罩可以控制图像的可见区域,创造出各种视觉效果。支持多种遮罩类型(线性、镜面、圆形、矩形、爱心、星形),每种遮罩都可以精确配置位置、大小、羽化、旋转等属性。
请求参数
{
"X": 100,
"Y": 30,
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"feather": 22,
"name": "线性",
"rotation": 20,
"segment_ids": [
"1381ae8d-4acf-49af-b3cc-26e3c5ff648b"
],
"width": 512,
"height": 512,
"invert": false,
"roundCorner": 0
}
参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
segment_ids | array | ✅ | - | 要应用遮罩的片段ID数组 |
name | string | ❌ | "线性" | 遮罩类型名称 |
X | number | ❌ | 0 | 遮罩中心X坐标(像素) |
Y | number | ❌ | 0 | 遮罩中心Y坐标(像素) |
width | number | ❌ | 512 | 遮罩宽度(像素) |
height | number | ❌ | 512 | 遮罩高度(像素) |
feather | number | ❌ | 0 | 羽化程度(0-100) |
rotation | number | ❌ | 0 | 旋转角度(度) |
invert | boolean | ❌ | false | 是否反转遮罩 |
roundCorner | number | ❌ | 0 | 圆角半径(0-100) |
支持的遮罩类型
遮罩名称 | 描述 | 适用场景 |
---|---|---|
线性 | 线性渐变遮罩 | 线性过渡效果、渐变显示隐藏 |
镜面 | 镜像对称遮罩 | 对称效果、镜像反射 |
圆形 | 圆形遮罩 | 聚光灯效果、圆形裁剪 |
矩形 | 矩形遮罩 | 窗口效果、矩形裁剪 |
爱心 | 爱心形状遮罩 | 浪漫场景、特殊形状裁剪 |
星形 | 星形遮罩 | 闪光效果、装饰性裁剪 |
响应格式
成功响应 (200)
{
"status": "success",
"message": "遮罩添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"masks_added": 2,
"affected_segments": ["segment_001", "segment_002"],
"mask_ids": ["mask_001", "mask_002"]
}
}
使用示例
1. 基本线性遮罩
curl -X POST https://jy-api.fyshark.com/api/drafts/add_masks \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"segment_ids": ["your-segment-id"],
"name": "线性",
"X": 100,
"Y": 50,
"feather": 20
}'
2. 圆形聚光灯遮罩
curl -X POST https://jy-api.fyshark.com/api/drafts/add_masks \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"segment_ids": ["your-segment-id"],
"name": "圆形",
"X": 200,
"Y": 200,
"width": 300,
"height": 300,
"feather": 50
}'
3. JavaScript 示例
const addMasks = async (maskConfig, draftUrl) => {
const response = await fetch('https://jy-api.fyshark.com/api/drafts/add_masks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
draft_url: draftUrl,
...maskConfig
})
});
const result = await response.json();
return result;
};
// 使用示例 - 线性渐变遮罩
const linearMask = {
segment_ids: ["your-segment-id"],
name: "线性",
X: 100,
Y: 50,
width: 600,
height: 100,
feather: 25,
rotation: 0
};
// 使用示例 - 圆形聚光灯效果
const spotlightMask = {
segment_ids: ["your-segment-id"],
name: "圆形",
X: 200,
Y: 200,
width: 300,
height: 300,
feather: 40,
invert: false
};
try {
const result = await addMasks(linearMask, draftUrl);
console.log('遮罩添加成功:', result.data);
} catch (error) {
console.error('添加失败:', error);
}
遮罩效果类型
线性遮罩
{
"name": "线性",
"X": 100,
"Y": 50,
"feather": 25
}
圆形遮罩
{
"name": "圆形",
"X": 200,
"Y": 200,
"width": 300,
"height": 300
}
矩形遮罩
{
"name": "矩形",
"X": 150,
"Y": 100,
"width": 400,
"height": 200,
"roundCorner": 20
}
装饰遮罩
{
"name": "爱心",
"X": 250,
"Y": 200,
"rotation": 15,
"invert": true
}
9. 添加贴纸接口 (add_sticker)
接口信息
- URL:
POST /api/drafts/add_sticker
- 功能: 向现有草稿中添加贴纸装饰元素
请求参数
{
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"sticker_id": "7326810673609018675",
"start": 0,
"end": 5000000,
"scale": 2,
"transform_x": 500,
"transform_y": 900
}
参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
sticker_id | string | ✅ | - | 贴纸的唯一标识ID |
start | number | ✅ | - | 贴纸开始时间(微秒) |
end | number | ✅ | - | 贴纸结束时间(微秒) |
scale | number | ❌ | 1.0 | 贴纸缩放比例 |
transform_x | number | ❌ | 0 | X轴位置偏移(像素) |
transform_y | number | ❌ | 0 | Y轴位置偏移(像素) |
使用示例
基本贴纸添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_sticker \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"sticker_id": "7326810673609018675",
"start": 0,
"end": 5000000
}'
带缩放和位置的贴纸
curl -X POST https://jy-api.fyshark.com/api/drafts/add_sticker \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"sticker_id": "7326810673609018675",
"start": 0,
"end": 5000000,
"scale": 2,
"transform_x": 500,
"transform_y": 900
}'
JavaScript示例
const addSticker = async (draftUrl, stickerConfig) => {
const response = await fetch('/api/drafts/add_sticker', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...stickerConfig
})
});
return response.json();
};
// 角落装饰贴纸
const cornerSticker = {
sticker_id: "7326810673609018675",
start: 0,
end: 10000000,
scale: 0.8,
transform_x: 400,
transform_y: -300
};
// 中心强调贴纸
const centerSticker = {
sticker_id: "7326810673609018675",
start: 5000000,
end: 8000000,
scale: 2.0,
transform_x: 0,
transform_y: 0
};
await addSticker(draftUrl, cornerSticker);
await addSticker(draftUrl, centerSticker);
响应格式
{
"status": "success",
"message": "贴纸添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"sticker_id": "7326810673609018675",
"track_id": "track-uuid",
"segment_id": "segment-uuid",
"duration": 5000000
}
}
应用场景
- 装饰效果: 在视频角落添加小贴纸
- 强调内容: 在关键时刻添加大贴纸
- 主题装饰: 根据视频主题选择相应贴纸
- 品牌标识: 添加品牌相关的贴纸元素
注意事项
- 时间单位: start和end使用微秒(1秒 = 1,000,000微秒)
- 坐标系统: transform_x和transform_y以画布中心为原点
- 缩放范围: 建议scale值在0.1-5.0之间
- 性能考虑: 建议单个视频贴纸数量不超过10个
10. 批量添加视频接口 (add_videos)
接口信息
- URL:
POST /api/drafts/add_videos
- 功能: 批量向现有草稿中添加视频素材,支持遮罩、转场、音量控制等高级功能
请求参数
{
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"video_infos": "[{\"video_url\":\"https://example.com/video1.mp4\",\"width\":1920,\"height\":1080,\"start\":0,\"end\":5000000,\"duration\":10000000,\"mask\":\"圆形\",\"transition\":\"淡入淡出\",\"transition_duration\":500000,\"volume\":0.8}]",
"alpha": 0.8,
"scale_x": 1.2,
"scale_y": 1.2,
"transform_x": 100,
"transform_y": 200
}
参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
draft_url | string | ✅ | - | 目标草稿的完整URL |
video_infos | string | ✅ | - | 视频信息数组的JSON字符串 |
alpha | number | ❌ | 1.0 | 全局透明度(0-1) |
scale_x | number | ❌ | 1.0 | X轴缩放比例 |
scale_y | number | ❌ | 1.0 | Y轴缩放比例 |
transform_x | number | ❌ | 0 | X轴位置偏移(像素) |
transform_y | number | ❌ | 0 | Y轴位置偏移(像素) |
video_infos 数组中每个视频的参数
字段名 | 类型 | 必填 | 说明 |
---|---|---|---|
video_url | string | ✅ | 视频文件的URL地址 |
width | number | ✅ | 视频宽度(像素) |
height | number | ✅ | 视频高度(像素) |
start | number | ✅ | 视频开始播放时间(微秒) |
end | number | ✅ | 视频结束播放时间(微秒) |
duration | number | ✅ | 视频总时长(微秒) |
mask | string | ❌ | 遮罩类型(圆形、爱心、星形、矩形、线性、镜面) |
transition | string | ❌ | 转场效果名称 |
transition_duration | number | ❌ | 转场持续时间(100000-2500000微秒) |
volume | number | ❌ | 音量大小(0-1) |
使用示例
基本视频添加
curl -X POST https://jy-api.fyshark.com/api/drafts/add_videos \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"video_infos": "[{\"video_url\":\"https://example.com/video1.mp4\",\"width\":1920,\"height\":1080,\"start\":0,\"end\":5000000,\"duration\":10000000}]"
}'
多视频序列
curl -X POST https://jy-api.fyshark.com/api/drafts/add_videos \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"video_infos": "[{\"video_url\":\"https://example.com/intro.mp4\",\"width\":1920,\"height\":1080,\"start\":0,\"end\":3000000,\"duration\":5000000,\"transition\":\"淡入淡出\"},{\"video_url\":\"https://example.com/main.mp4\",\"width\":1920,\"height\":1080,\"start\":3000000,\"end\":13000000,\"duration\":15000000,\"volume\":0.8}]",
"alpha": 1.0
}'
画中画效果
curl -X POST https://jy-api.fyshark.com/api/drafts/add_videos \
-H "Content-Type: application/json" \
-d '{
"draft_url": "YOUR_DRAFT_URL",
"video_infos": "[{\"video_url\":\"https://example.com/background.mp4\",\"width\":1920,\"height\":1080,\"start\":0,\"end\":10000000,\"duration\":15000000},{\"video_url\":\"https://example.com/overlay.mp4\",\"width\":640,\"height\":360,\"start\":2000000,\"end\":8000000,\"duration\":10000000,\"mask\":\"圆形\"}]",
"scale_x": 0.8,
"scale_y": 0.8,
"transform_x": 200,
"transform_y": -150
}'
JavaScript示例
const addVideos = async (draftUrl, videoConfig) => {
const response = await fetch('/api/drafts/add_videos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...videoConfig
})
});
return response.json();
};
// 视频序列配置
const videoSequence = {
video_infos: JSON.stringify([
{
video_url: "https://example.com/intro.mp4",
width: 1920,
height: 1080,
start: 0,
end: 3000000,
duration: 5000000,
transition: "淡入淡出",
transition_duration: 500000
},
{
video_url: "https://example.com/main.mp4",
width: 1920,
height: 1080,
start: 3000000,
end: 15000000,
duration: 20000000,
volume: 0.8
}
]),
alpha: 1.0
};
// 画中画配置
const pipConfig = {
video_infos: JSON.stringify([
{
video_url: "https://example.com/background.mp4",
width: 1920,
height: 1080,
start: 0,
end: 10000000,
duration: 15000000
},
{
video_url: "https://example.com/overlay.mp4",
width: 640,
height: 360,
start: 2000000,
end: 8000000,
duration: 10000000,
mask: "圆形"
}
]),
scale_x: 0.3,
scale_y: 0.3,
transform_x: 300,
transform_y: -200,
alpha: 0.9
};
try {
const result1 = await addVideos(draftUrl, videoSequence);
const result2 = await addVideos(draftUrl, pipConfig);
console.log('视频添加成功:', {
sequence: result1.data,
pip: result2.data
});
} catch (error) {
console.error('添加失败:', error);
}
响应格式
{
"status": "success",
"message": "视频批量添加成功",
"data": {
"draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
"track_id": "video-track-uuid",
"video_ids": ["video1-uuid", "video2-uuid"],
"segment_ids": ["segment1-uuid", "segment2-uuid"],
"videos_count": 2,
"total_duration": 10000000
}
}
应用场景
- 视频拼接: 创建连续的视频序列
- 画中画效果: 实现多视角同时显示
- 分屏展示: 同时展示多个视频内容
- 转场动画: 使用转场创建平滑切换
- 视频叠加: 实现复杂的视频合成效果
- 音量控制: 精确控制每个视频的音量
注意事项
- JSON格式: video_infos必须是合法的JSON字符串
- 时间单位: 所有时间参数使用微秒(1秒 = 1,000,000微秒)
- 视频格式: 确保视频文件格式被支持
- 网络访问: 视频URL必须可以正常访问
- 遮罩类型: 支持6种预定义遮罩类型
- 转场时长: 范围限制在100000-2500000微秒之间
- 性能考虑: 批量添加大量视频可能影响性能
11. 完整工作流程示例
工作流程图
1. 创建草稿 → 2. 获取草稿URL → 3a. 添加素材 → 4. 添加动画 → 5. 添加视效 → 6. 添加装饰 → 7. 完成制作
↘ 3b. 批量添加音频 ↗ ↘ 4a. 关键帧动画 ↗ ↘ 5a. 遮罩效果 ↗ ↘ 6a. 添加贴纸 ↗
↘ 3c. 批量添加字幕 ↗
↘ 3d. 批量添加特效 ↗
↘ 3e. 批量添加图片 ↗
↘ 3f. 批量添加视频 ↗
完整的JavaScript工作流程
class VideoCreator {
constructor(baseUrl = 'https://jy-api.fyshark.com') {
this.baseUrl = baseUrl;
}
// 步骤1: 创建草稿
async createDraft(width = 1080, height = 1920, userId = null) {
const response = await fetch(`${this.baseUrl}/api/drafts/create_draft`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ width, height, user_id: userId })
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`创建草稿失败: ${result.message}`);
}
console.log('✅ 草稿创建成功');
return result.data.draft_url;
}
// 步骤2a: 添加综合素材
async addMaterials(draftUrl, materials) {
// 验证必要参数
if (!materials.audio_url) {
throw new Error('音频URL是必需的');
}
const response = await fetch(`${this.baseUrl}/api/drafts/easy_create_material`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...materials
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加素材失败: ${result.message}`);
}
console.log('✅ 素材添加成功');
return result.data.draft_url;
}
// 步骤2b: 批量添加音频
async addAudios(draftUrl, audioInfos) {
// 验证必要参数
if (!Array.isArray(audioInfos) || audioInfos.length === 0) {
throw new Error('音频信息数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_audios`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
audio_infos: JSON.stringify(audioInfos),
draft_url: draftUrl
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加音频失败: ${result.message}`);
}
console.log('✅ 音频添加成功');
return {
draft_url: result.data.draft_url,
track_id: result.data.track_id,
audio_ids: result.data.audio_ids
};
}
// 步骤2c: 批量添加字幕
async addCaptions(draftUrl, captions, options = {}) {
// 验证必要参数
if (!Array.isArray(captions) || captions.length === 0) {
throw new Error('字幕信息数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_captions`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
captions: JSON.stringify(captions),
draft_url: draftUrl,
text_color: options.textColor || "#ffffff",
border_color: options.borderColor,
alignment: options.alignment || 1,
alpha: options.alpha || 1.0,
font: options.font,
font_size: options.fontSize || 15
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加字幕失败: ${result.message}`);
}
console.log('✅ 字幕添加成功');
return {
draft_url: result.data.draft_url,
track_id: result.data.track_id,
text_ids: result.data.text_ids,
segment_ids: result.data.segment_ids,
segment_infos: result.data.segment_infos
};
}
// 步骤2d: 批量添加特效
async addEffects(draftUrl, effects) {
// 验证必要参数
if (!Array.isArray(effects) || effects.length === 0) {
throw new Error('特效信息数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_effects`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
effect_infos: JSON.stringify(effects),
draft_url: draftUrl
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加特效失败: ${result.message}`);
}
console.log('✅ 特效添加成功');
return {
draft_url: result.data.draft_url,
track_id: result.data.track_id,
effect_ids: result.data.effect_ids,
segment_ids: result.data.segment_ids
};
}
// 步骤2e: 批量添加图片
async addImages(draftUrl, images, options = {}) {
// 验证必要参数
if (!Array.isArray(images) || images.length === 0) {
throw new Error('图片信息数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_images`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
image_infos: JSON.stringify(images),
draft_url: draftUrl,
...options
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加图片失败: ${result.message}`);
}
console.log('✅ 图片添加成功');
return {
draft_url: result.data.draft_url,
track_id: result.data.track_id,
image_ids: result.data.image_ids,
segment_ids: result.data.segment_ids,
segment_infos: result.data.segment_infos
};
}
// 步骤2f: 批量添加关键帧
async addKeyframes(draftUrl, keyframes) {
// 验证必要参数
if (!Array.isArray(keyframes) || keyframes.length === 0) {
throw new Error('关键帧信息数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_keyframes`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
keyframes: JSON.stringify(keyframes),
draft_url: draftUrl
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加关键帧失败: ${result.message}`);
}
console.log('✅ 关键帧添加成功');
return {
draft_url: result.data.draft_url,
keyframes_added: result.data.keyframes_added,
affected_segments: result.data.affected_segments
};
}
// 步骤2g: 批量添加遮罩
async addMasks(draftUrl, maskConfig) {
// 验证必要参数
if (!maskConfig.segment_ids || !Array.isArray(maskConfig.segment_ids) || maskConfig.segment_ids.length === 0) {
throw new Error('segment_ids数组不能为空');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_masks`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...maskConfig
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加遮罩失败: ${result.message}`);
}
console.log('✅ 遮罩添加成功');
return {
draft_url: result.data.draft_url,
masks_added: result.data.masks_added,
affected_segments: result.data.affected_segments,
mask_ids: result.data.mask_ids
};
}
// 步骤2h: 添加贴纸
async addSticker(draftUrl, stickerConfig) {
// 验证必要参数
if (!stickerConfig.sticker_id) {
throw new Error('sticker_id是必需的');
}
if (typeof stickerConfig.start !== 'number' || typeof stickerConfig.end !== 'number') {
throw new Error('start和end必须是数字类型(微秒)');
}
if (stickerConfig.start >= stickerConfig.end) {
throw new Error('end必须大于start');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_sticker`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...stickerConfig
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加贴纸失败: ${result.message}`);
}
console.log('✅ 贴纸添加成功');
return {
draft_url: result.data.draft_url,
sticker_id: result.data.sticker_id,
track_id: result.data.track_id,
segment_id: result.data.segment_id,
duration: result.data.duration
};
}
// 步骤2i: 批量添加视频
async addVideos(draftUrl, videoConfig) {
// 验证必要参数
if (!videoConfig.video_infos) {
throw new Error('video_infos是必需的');
}
// 验证JSON格式
let videoInfos;
try {
videoInfos = JSON.parse(videoConfig.video_infos);
} catch (e) {
throw new Error('video_infos必须是有效的JSON字符串');
}
if (!Array.isArray(videoInfos) || videoInfos.length === 0) {
throw new Error('video_infos必须是非空数组');
}
const response = await fetch(`${this.baseUrl}/api/drafts/add_videos`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
draft_url: draftUrl,
...videoConfig
})
});
const result = await response.json();
if (result.status !== 'success') {
throw new Error(`添加视频失败: ${result.message}`);
}
console.log('✅ 视频批量添加成功');
return {
draft_url: result.data.draft_url,
track_id: result.data.track_id,
video_ids: result.data.video_ids,
segment_ids: result.data.segment_ids,
videos_count: result.data.videos_count,
total_duration: result.data.total_duration
};
}
// 完整工作流程
async createVideoProject(config) {
try {
console.log('🚀 开始创建视频项目...');
// 第1步: 创建草稿
const draftUrl = await this.createDraft(
config.width,
config.height,
config.userId
);
// 第2步: 添加素材
const finalDraftUrl = await this.addMaterials(draftUrl, config.materials);
console.log('🎉 视频项目创建完成!');
console.log('📄 草稿URL:', finalDraftUrl);
return {
success: true,
draftUrl: finalDraftUrl,
message: '视频项目创建成功'
};
} catch (error) {
console.error('❌ 创建失败:', error.message);
return {
success: false,
error: error.message
};
}
}
}
// 使用示例
const videoCreator = new VideoCreator();
const projectConfig = {
width: 1080,
height: 1920,
userId: 12345,
materials: {
text: "我的第一个视频",
audio_url: "https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/24631f7d1dd449e594097b6586b7d1b0.mp3",
img_url: "https://s.coze.cn/t/JTa5Ne6_liY/",
text_color: "#ffffff",
font_size: 22,
text_transform_y: 100
}
};
// 执行完整工作流程
videoCreator.createVideoProject(projectConfig).then(result => {
if (result.success) {
console.log('项目创建成功,可以在剪映中打开:', result.draftUrl);
} else {
console.log('项目创建失败:', result.error);
}
});
Bash 脚本工作流程
#!/bin/bash
# 配置
API_BASE="https://jy-api.fyshark.com"
AUDIO_URL="https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/artist/image/24631f7d1dd449e594097b6586b7d1b0.mp3"
IMG_URL="https://s.coze.cn/t/JTa5Ne6_liY/"
echo "🚀 开始创建视频项目..."
# 步骤1: 创建草稿
echo "📝 创建草稿中..."
DRAFT_RESPONSE=$(curl -s -X POST $API_BASE/api/drafts/create_draft \
-H "Content-Type: application/json" \
-d '{"width": 1080, "height": 1920, "user_id": 12345}')
# 提取草稿URL
DRAFT_URL=$(echo $DRAFT_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin)['data']['draft_url'])")
if [ -z "$DRAFT_URL" ]; then
echo "❌ 创建草稿失败"
exit 1
fi
echo "✅ 草稿创建成功: $DRAFT_URL"
# 步骤2: 添加素材
echo "🎬 添加素材中..."
MATERIAL_RESPONSE=$(curl -s -X POST $API_BASE/api/drafts/easy_create_material \
-H "Content-Type: application/json" \
-d "{
\"text\": \"Bash脚本创建的视频\",
\"audio_url\": \"$AUDIO_URL\",
\"img_url\": \"$IMG_URL\",
\"draft_url\": \"$DRAFT_URL\",
\"text_color\": \"#00ff00\",
\"font_size\": 20
}")
# 检查结果
STATUS=$(echo $MATERIAL_RESPONSE | python3 -c "import sys, json; print(json.load(sys.stdin)['status'])")
if [ "$STATUS" = "success" ]; then
echo "🎉 视频项目创建完成!"
echo "📄 最终草稿URL: $DRAFT_URL"
else
echo "❌ 添加素材失败"
echo $MATERIAL_RESPONSE
exit 1
fi
4. 错误处理
常见错误类型
1. 参数验证错误 (400)
{
"status": "error",
"message": "draft_url是必填项"
}
解决方案: 检查请求参数是否完整和正确
2. 资源访问错误 (400)
{
"status": "error",
"message": "音频链接无效或无法获取音频时长",
"draft_url": "原始草稿URL"
}
解决方案:
- 验证音频URL是否可访问
- 确认音频文件格式是否支持
- 检查网络连接
3. 草稿处理错误 (500)
{
"status": "error",
"message": "草稿处理失败: 具体错误信息",
"draft_url": "原始草稿URL"
}
解决方案:
- 确认草稿URL格式正确
- 验证草稿文件是否存在
- 检查OSS服务是否正常
错误处理最佳实践
const handleApiCall = async (apiCall) => {
try {
const result = await apiCall();
return { success: true, data: result };
} catch (error) {
console.error('API调用失败:', error);
// 根据错误类型进行不同处理
if (error.message.includes('音频链接')) {
return {
success: false,
error: '音频文件问题,请检查URL或文件格式',
type: 'audio_error'
};
} else if (error.message.includes('草稿处理')) {
return {
success: false,
error: '草稿处理失败,请重试或检查草稿URL',
type: 'draft_error'
};
} else {
return {
success: false,
error: error.message,
type: 'unknown_error'
};
}
}
};
5. 最佳实践
5.1 参数优化建议
画布尺寸选择
const canvasSizes = {
vertical: { width: 1080, height: 1920 }, // 竖屏 (9:16)
horizontal: { width: 1920, height: 1080 }, // 横屏 (16:9)
square: { width: 1080, height: 1080 }, // 方形 (1:1)
instagram: { width: 1080, height: 1350 } // Instagram (4:5)
};
文字样式建议
const textStyles = {
title: { font_size: 28, text_color: "#ffffff" },
subtitle: { font_size: 20, text_color: "#cccccc" },
body: { font_size: 16, text_color: "#ffffff" },
caption: { font_size: 14, text_color: "#999999" }
};
5.2 性能优化
1. 音频预处理
// 在添加素材前验证音频
const validateAudio = async (audioUrl) => {
try {
const response = await fetch(audioUrl, { method: 'HEAD' });
return response.ok && response.headers.get('content-type')?.includes('audio');
} catch {
return false;
}
};
2. 批量处理
// 如果需要创建多个项目,建议复用草稿
const batchCreateProjects = async (projects) => {
const results = [];
for (const project of projects) {
try {
// 每个项目创建独立草稿
const result = await videoCreator.createVideoProject(project);
results.push(result);
// 避免请求过于频繁
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
results.push({ success: false, error: error.message });
}
}
return results;
};
5.3 安全考虑
URL 验证
const isValidUrl = (url) => {
try {
const urlObj = new URL(url);
return ['http:', 'https:'].includes(urlObj.protocol);
} catch {
return false;
}
};
// 使用前验证所有URL
const validateUrls = (materials) => {
const urlFields = ['audio_url', 'img_url', 'video_url'];
for (const field of urlFields) {
if (materials[field] && !isValidUrl(materials[field])) {
throw new Error(`无效的${field}: ${materials[field]}`);
}
}
};
5.4 监控和日志
const createWithLogging = async (config) => {
const startTime = Date.now();
try {
console.log('开始创建项目:', {
timestamp: new Date().toISOString(),
config: config
});
const result = await videoCreator.createVideoProject(config);
console.log('项目创建完成:', {
duration: Date.now() - startTime,
success: result.success,
draftUrl: result.draftUrl
});
return result;
} catch (error) {
console.error('项目创建失败:', {
duration: Date.now() - startTime,
error: error.message,
config: config
});
throw error;
}
};
📞 技术支持
接口状态检查
# 健康检查
curl https://jy-api.fyshark.com/health
# 服务信息
curl https://jy-api.fyshark.com/
调试模式
如果遇到问题,可以查看服务器日志获取详细错误信息。
联系方式
- API文档: https://jy-api.fyshark.com
- 健康检查: https://jy-api.fyshark.com/health
- 快速入门指南: https://www.51aigc.cc/#/cozeTutorial/detail/13
📈 版本历史
v1.8.0 (2025-08-01)
- 新增add_videos接口 - 批量视频添加功能
- 支持多视频序列处理和画中画效果
- 支持遮罩效果、转场动画和音量控制
- 支持透明度调整和位置变换
- 实现高级视频合成和叠加效果
- 完善的视频参数验证机制
v1.7.0 (2025-08-01)
- 新增add_sticker接口 - 贴纸装饰功能
- 支持贴纸缩放和位置变换控制
- 支持精确的时间范围设置
- 实现基于画布中心的坐标系统
- 完善的贴纸参数验证机制
v1.6.0 (2025-08-01)
- 新增add_masks接口 - 批量遮罩效果功能
- 支持6种遮罩类型(线性、镜面、圆形、矩形、爱心、星形)
- 实现精确的遮罩配置系统(位置、尺寸、羽化、旋转、反转)
- 支持多片段批量遮罩应用
- 完善的遮罩参数验证机制
v1.5.0 (2025-08-01)
- 新增add_keyframes接口 - 批量关键帧动画功能
- 支持6种主要属性类型(位置、缩放、旋转、透明度)
- 实现专业级关键帧插值动画
- 支持复杂动画组合和时间控制
- 完善的关键帧验证机制
v1.4.0 (2025-08-01)
- 新增add_images接口 - 批量图片添加功能
- 支持图片动画效果(入场、出场、循环)
- 支持转场效果和时长控制
- 支持透明度、缩放和位置变换
- 完善的图片验证机制
v1.3.0 (2025-08-01)
- 新增add_effects接口 - 批量特效添加功能
- 支持多种视频特效类型(边框、滤镜、动态等)
- 支持特效时间范围控制
- 支持特效叠加使用
- 完善的特效验证机制
v1.2.0 (2025-08-01)
- 新增add_captions接口 - 批量字幕添加功能
- 支持关键词高亮显示
- 支持丰富的文本样式(颜色、字体、边框等)
- 支持字幕动画效果(入场、出场、循环)
- 支持文本对齐和变换功能
v1.1.0 (2025-08-01)
- 新增add_audios接口 - 批量音频添加功能
- 支持音频片段时间范围设置
- 支持音量和音效控制
- 完善的参数验证机制
v1.0.0 (2025-08-01)
- 初始版本发布
- 支持create_draft和easy_create_material接口
- 完整的jy_draft包集成
- 多媒体素材处理支持
🎉 恭喜!你现在已经掌握了JY API的完整使用方法。开始创建你的第一个视频项目吧!