EASY_CREATE_MATERIAL API 接口文档

📄 API_EASY_CREATE_MATERIAL.md 🕒 8/10/2025, 6:49:34 PM 📏 11KB

EASY_CREATE_MATERIAL API 接口文档

接口信息

POST /api/drafts/easy_create_material

功能描述

在现有草稿中添加多种类型的素材内容,包括音频、视频、图片和文字。该接口可以一次性向草稿添加多种媒体素材,自动处理素材的时长、尺寸等属性,并智能管理不同类型的媒体轨道。是视频创作的核心接口之一。

请求参数

{
  "text": "Hello World",
  "img_url": "https://s.coze.cn/t/JTa5Ne6_liY/",
  "video_url": "https://example.com/video.mp4",
  "audio_url": "https://example.com/audio.mp3",
  "draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
  "text_color": "#ffffff",
  "font_size": 15,
  "text_transform_y": 100
}

参数说明

参数名 类型 必填 默认值 说明
draft_url string - 目标草稿的完整URL
audio_url string - 音频文件URL,不能为空或"null"
text string - 要添加的文字内容
img_url string - 图片文件URL
video_url string - 视频文件URL
text_color string "#ffffff" 文字颜色(十六进制格式)
font_size number 15 字体大小
text_transform_y number 0 文字Y轴位置偏移

素材类型说明

素材类型 支持格式 自动处理
音频 MP3, WAV, AAC 自动获取时长
视频 MP4, AVI, MOV 固定时长5秒
图片 JPEG, PNG, GIF 自动获取尺寸
文字 UTF-8文本 支持样式设置

响应格式

成功响应 (200)

{
  "status": "success",
  "message": "素材创建成功",
  "data": {
    "draft_url": "https://ts.fyshark.com/#/cozeToJianyin?drafId=...",
    "processed_materials": {
      "audio": { "duration": 23184000, "added": true },
      "video": { "duration": 5000000, "added": true },
      "image": { "width": 1024, "height": 1024, "added": true },
      "text": { "content": "Hello World", "added": true }
    }
  }
}

错误响应 (4xx/5xx)

{
  "status": "error",
  "message": "错误信息",
  "error": "详细错误描述",
  "draft_url": "原始草稿URL"
}

使用示例

cURL 示例

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://example.com/audio.mp3",
    "draft_url": "YOUR_DRAFT_URL"
  }'

2. 完整素材添加(所有类型)

curl -X POST https://jy-api.fyshark.com/api/drafts/easy_create_material \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Sample 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. 自定义文字样式

curl -X POST https://jy-api.fyshark.com/api/drafts/easy_create_material \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Stylized Text",
    "audio_url": "https://example.com/audio.mp3",
    "draft_url": "YOUR_DRAFT_URL",
    "text_color": "#00ff00",
    "font_size": 24,
    "text_transform_y": -100
  }'

JavaScript 示例

const addMaterials = async (materialsData, draftUrl) => {
  const response = await fetch('/api/drafts/easy_create_material', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      ...materialsData,
      draft_url: draftUrl
    })
  });

  const result = await response.json();
  return result;
};

// 使用示例
const materials = {
  text: "My Content",
  img_url: "https://example.com/image.jpg",
  audio_url: "https://example.com/audio.mp3",
  text_color: "#3366cc",
  font_size: 18
};

try {
  const result = await addMaterials(materials, draftUrl);
  console.log('素材添加成功:', result.data);
} catch (error) {
  console.error('添加失败:', error);
}

高级JavaScript示例

class MaterialsManager {
  constructor(baseUrl = 'https://jy-api.fyshark.com') {
    this.baseUrl = baseUrl;
  }

  async addMaterials(config) {
    const {
      draftUrl,
      audio = {},
      video = {},
      image = {},
      text = {}
    } = config;

    const payload = {
      draft_url: draftUrl,
      audio_url: audio.url,
      video_url: video.url,
      img_url: image.url,
      text: text.content,
      text_color: text.color || "#ffffff",
      font_size: text.size || 15,
      text_transform_y: text.offsetY || 0
    };

    const response = await fetch(`${this.baseUrl}/api/drafts/easy_create_material`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });

    return response.json();
  }

  // 便捷方法:只添加音频和文字
  async addAudioText(draftUrl, audioUrl, textContent, textStyle = {}) {
    return this.addMaterials({
      draftUrl,
      audio: { url: audioUrl },
      text: {
        content: textContent,
        color: textStyle.color,
        size: textStyle.size,
        offsetY: textStyle.offsetY
      }
    });
  }

  // 便捷方法:添加完整的多媒体内容
  async addFullMedia(draftUrl, audioUrl, videoUrl, imageUrl, textContent) {
    return this.addMaterials({
      draftUrl,
      audio: { url: audioUrl },
      video: { url: videoUrl },
      image: { url: imageUrl },
      text: { content: textContent }
    });
  }
}

// 使用示例
const manager = new MaterialsManager();

// 添加音频和文字
await manager.addAudioText(
  draftUrl,
  "https://example.com/audio.mp3",
  "Hello World",
  { color: "#ff6600", size: 20, offsetY: 100 }
);

// 添加完整媒体
await manager.addFullMedia(
  draftUrl,
  "https://example.com/audio.mp3",
  "https://example.com/video.mp4",
  "https://example.com/image.jpg",
  "Complete Media Content"
);

Python 示例 (可选)

import requests
import json

class MaterialsCreator:
    def __init__(self, base_url="https://jy-api.fyshark.com"):
        self.base_url = base_url

    def add_materials(self, draft_url, **kwargs):
        data = {"draft_url": draft_url}
        data.update(kwargs)
        
        response = requests.post(
            f'{self.base_url}/api/drafts/easy_create_material',
            headers={'Content-Type': 'application/json'},
            json=data
        )
        return response.json()

# 使用示例
creator = MaterialsCreator()

result = creator.add_materials(
    draft_url="YOUR_DRAFT_URL",
    text="Python Generated Content",
    audio_url="https://example.com/audio.mp3",
    text_color="#0066cc",
    font_size=16
)

print(f"结果: {result}")

错误码说明

错误码 错误信息 说明 解决方案
400 draft_url是必填项 缺少草稿URL参数 提供有效的草稿URL
400 音频链接不能为空 audio_url为空或"null" 提供有效的音频URL
400 参数格式错误 参数类型不正确 检查参数类型和格式
404 草稿不存在 指定的草稿URL无效 检查草稿URL是否正确
404 音频文件不存在 音频URL无法访问 检查音频URL有效性
404 图片文件不存在 图片URL无法访问 检查图片URL有效性
500 音频时长获取失败 音频文件解析错误 检查音频文件格式
500 图片尺寸获取失败 图片文件解析错误 使用标准图片格式
500 草稿处理失败 内部处理错误 联系技术支持

注意事项

  1. 必需参数: draft_url和audio_url是必填项,其他素材可选
  2. URL有效性: 确保所有提供的媒体URL可以正常访问
  3. 文件格式: 使用标准的媒体文件格式以确保兼容性
  4. 网络连接: 接口需要下载媒体文件进行处理,确保网络稳定
  5. 处理时间: 大文件的处理可能需要较长时间
  6. 文字编码: 文字内容使用UTF-8编码,支持中英文混合

工作流程

  1. 验证必填参数(draft_url, audio_url)
  2. 获取并解密现有草稿内容
  3. 处理音频素材:
    • 下载音频文件
    • 解析音频时长
    • 添加到音频轨道
  4. 处理视频素材(如果提供):
    • 创建视频素材
    • 添加到视频轨道
  5. 处理图片素材(如果提供):
    • 下载图片文件
    • 获取图片尺寸
    • 添加到视频轨道(作为图片轨道)
  6. 处理文字素材(如果提供):
    • 生成文字样式
    • 设置颜色、大小、位置
    • 添加到文字轨道
  7. 加密并保存更新后的草稿

技术特性

智能轨道管理

自动化处理

样式系统

最佳实践

媒体文件建议

const mediaGuidelines = {
  audio: {
    formats: ['mp3', 'wav', 'aac'],
    maxSize: '50MB',
    quality: '128kbps以上'
  },
  video: {
    formats: ['mp4', 'avi', 'mov'],
    maxSize: '100MB',
    resolution: '1080p以下'
  },
  image: {
    formats: ['jpg', 'png', 'gif'],
    maxSize: '10MB',
    resolution: '4K以下'
  }
};

错误处理策略

const addMaterialsWithFallback = async (config) => {
  try {
    const result = await addMaterials(config);
    return result;
  } catch (error) {
    // 如果图片失败,重试不包含图片
    if (error.message.includes('图片')) {
      console.warn('图片处理失败,重试不包含图片的版本');
      const { img_url, ...configWithoutImage } = config;
      return addMaterials(configWithoutImage);
    }
    throw error;
  }
};

批量处理

const batchAddMaterials = async (materialsConfigs, draftUrl) => {
  const results = [];
  let currentDraftUrl = draftUrl;
  
  for (const config of materialsConfigs) {
    try {
      const result = await addMaterials({
        ...config,
        draft_url: currentDraftUrl
      });
      
      if (result.status === 'success') {
        currentDraftUrl = result.data.draft_url;
        results.push({ config, result, success: true });
      }
    } catch (error) {
      results.push({ config, error, success: false });
    }
  }
  
  return { results, finalDraftUrl: currentDraftUrl };
};

性能优化

媒体文件预检查

const validateMediaUrls = async (urls) => {
  const checks = urls.map(async (url) => {
    try {
      const response = await fetch(url, { method: 'HEAD' });
      return { url, valid: response.ok, size: response.headers.get('content-length') };
    } catch (error) {
      return { url, valid: false, error: error.message };
    }
  });
  
  return Promise.all(checks);
};

// 使用预检查
const urlChecks = await validateMediaUrls([audioUrl, imageUrl, videoUrl]);
const validUrls = urlChecks.filter(check => check.valid);

并发限制

const processWithConcurrencyLimit = async (configs, limit = 3) => {
  const chunks = [];
  for (let i = 0; i < configs.length; i += limit) {
    chunks.push(configs.slice(i, i + limit));
  }
  
  const results = [];
  for (const chunk of chunks) {
    const chunkResults = await Promise.allSettled(
      chunk.map(config => addMaterials(config))
    );
    results.push(...chunkResults);
  }
  
  return results;
};

相关接口

更新日志


📖 文档版本: v1.3.0
🔄 最后更新: 2025-08-01
👤 维护者: Developer