Files
capcut-mate/docs/get_draft.md
T
2025-11-18 11:19:36 +08:00

597 lines
18 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GET_DRAFT API 接口文档
## 📋 目录
- [🔧 接口信息](#-接口信息)
- [🎯 功能描述](#-功能描述)
- [📖 更多文档](#-更多文档)
- [📥 请求参数](#-请求参数)
- [📤 响应格式](#-响应格式)
- [💻 使用示例](#-使用示例)
- [❌ 错误码说明](#-错误码说明)
- [⚠️ 注意事项](#-注意事项)
- [🔗 相关接口](#-相关接口)
## 🔧 接口信息
```
GET /openapi/capcut-mate/v1/get_draft
```
## 功能描述
获取草稿文件列表。该接口用于获取指定草稿ID对应的所有文件列表,可以查看草稿中包含的素材文件、配置文件等信息。通常用于草稿内容的预览、文件管理或状态检查。
## 更多文档
📖 更多详细文档和教程请访问:[https://docs.jcaigc.cn](https://docs.jcaigc.cn)
## 请求参数
### Query参数
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|--------|------|------|--------|------|
| draft_id | string | ✅ | - | 草稿ID,长度为20-32位字符 |
### 参数详解
#### draft_id
- **类型**: 字符串
- **必填**: 是
- **长度**: 20-32位字符
- **格式**: 通常为UUID格式或类似的唯一标识符
- **示例**: `2f52a63b-8c6a-4417-8b01-1b2a569ccb6c`
- **获取方式**: 通常从draft_url中提取或由create_draft接口返回
#### draft_id提取方法
从draft_url中提取draft_id
```javascript
// 示例draft_url:
// https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258"2f52a63b-8c6a-4417-8b01-1b2a569ccb6c"
```
## 响应格式
### 成功响应 (200)
```json
{
"files": [
"2f52a63b-8c6a-4417-8b01-1b2a569ccb6c.json",
"video_123456789.mp4",
"audio_987654321.mp3",
"image_555666777.jpg",
"thumbnail_888999000.png"
]
}
```
### 响应字段说明
| 字段名 | 类型 | 说明 |
|--------|------|------|
| files | array | 草稿相关的文件列表 |
### 文件类型说明
返回的文件列表可能包含以下类型:
| 文件类型 | 扩展名 | 说明 |
|----------|--------|------|
| 草稿配置文件 | .json | 草稿的主要配置文件,包含所有编辑信息 |
| 视频文件 | .mp4, .avi, .mov | 草稿中使用的视频素材 |
| 音频文件 | .mp3, .wav, .aac | 草稿中使用的音频素材 |
| 图片文件 | .jpg, .png, .gif | 草稿中使用的图片素材 |
| 缩略图文件 | .png, .jpg | 素材的缩略图文件 |
| 临时文件 | .tmp | 处理过程中的临时文件 |
### 错误响应 (4xx/5xx)
```json
{
"detail": "错误信息描述"
}
```
## 使用示例
### cURL 示例
#### 1. 基本获取草稿文件列表
```bash
curl -X GET "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2f52a63b-8c6a-4417-8b01-1b2a569ccb6c" \
-H "Content-Type: application/json"
```
#### 2. 使用完整的draft_id
```bash
curl -X GET "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=7e8f9a0b-1c2d-3e4f-5g6h-7i8j9k0l1m2n" \
-H "Content-Type: application/json"
```
### JavaScript 示例
```javascript
const getDraft = async (draftId) => {
const response = await fetch(`/v1/get_draft?draft_id=${draftId}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
return response.json();
};
// 使用示例
const draftId = "2f52a63b-8c6a-4417-8b01-1b2a569ccb6c";
const result = await getDraft(draftId);
console.log('草稿文件列表:', result.files);
// 从draft_url提取draft_id
function extractDraftId(draftUrl) {
const match = draftUrl.match(/\/([^\/]+)\.json$/);
return match ? match[1] : null;
}
const draftUrl = "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258";
const extractedId = extractDraftId(draftUrl);
if (extractedId) {
const files = await getDraft(extractedId);
console.log('文件列表:', files);
}
```
### 高级JavaScript示例
```javascript
class DraftManager {
constructor(baseUrl = 'https://capcut-mate.jcaigc.cn') {
this.baseUrl = baseUrl;
}
async getDraft(draftId) {
const response = await fetch(`${this.baseUrl}/v1/get_draft?draft_id=${draftId}`, {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) {
throw new Error(`获取草稿失败: ${response.statusText}`);
}
return response.json();
}
// 从draft_url提取draft_id
extractDraftId(draftUrl) {
try {
const url = new URL(draftUrl);
const draftIdParam = url.searchParams.get('drafId');
if (draftIdParam) {
const match = draftIdParam.match(/\/([^\/]+)\.json$/);
return match ? match[1] : null;
}
return null;
} catch (error) {
console.error('URL解析失败:', error);
return null;
}
}
// 分析文件类型
analyzeFiles(files) {
const analysis = {
total: files.length,
types: {
config: [],
video: [],
audio: [],
image: [],
thumbnail: [],
other: []
}
};
files.forEach(file => {
const ext = file.split('.').pop()?.toLowerCase();
switch (ext) {
case 'json':
analysis.types.config.push(file);
break;
case 'mp4':
case 'avi':
case 'mov':
case 'mkv':
analysis.types.video.push(file);
break;
case 'mp3':
case 'wav':
case 'aac':
case 'flac':
analysis.types.audio.push(file);
break;
case 'jpg':
case 'jpeg':
case 'png':
case 'gif':
case 'bmp':
if (file.includes('thumbnail')) {
analysis.types.thumbnail.push(file);
} else {
analysis.types.image.push(file);
}
break;
default:
analysis.types.other.push(file);
}
});
return analysis;
}
// 获取草稿详细信息
async getDraftDetails(draftUrl) {
const draftId = this.extractDraftId(draftUrl);
if (!draftId) {
throw new Error('无法从URL中提取草稿ID');
}
const result = await this.getDraft(draftId);
const analysis = this.analyzeFiles(result.files);
return {
draftId,
draftUrl,
files: result.files,
analysis
};
}
// 批量获取多个草稿信息
async getBatchDrafts(draftUrls) {
const results = {};
for (const [name, url] of Object.entries(draftUrls)) {
try {
const details = await this.getDraftDetails(url);
results[name] = details;
// 添加延迟避免请求过快
await new Promise(resolve => setTimeout(resolve, 100));
} catch (error) {
console.error(`获取草稿失败 ${name}:`, error);
results[name] = { error: error.message };
}
}
return results;
}
// 监控草稿文件变化
async monitorDraftChanges(draftId, callback, intervalMs = 5000) {
let lastFileList = [];
const checkChanges = async () => {
try {
const result = await this.getDraft(draftId);
const currentFiles = result.files.sort();
// 检查文件列表是否发生变化
if (JSON.stringify(currentFiles) !== JSON.stringify(lastFileList)) {
const changes = {
added: currentFiles.filter(f => !lastFileList.includes(f)),
removed: lastFileList.filter(f => !currentFiles.includes(f)),
current: currentFiles
};
callback(changes);
lastFileList = currentFiles;
}
} catch (error) {
console.error('监控草稿变化失败:', error);
}
};
// 初始检查
await checkChanges();
// 定期检查
const interval = setInterval(checkChanges, intervalMs);
// 返回停止监控的函数
return () => clearInterval(interval);
}
}
// 使用示例
const draftManager = new DraftManager();
// 获取单个草稿详情
const draftUrl = "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258";
const details = await draftManager.getDraftDetails(draftUrl);
console.log('草稿详情:', {
id: details.draftId,
totalFiles: details.analysis.total,
videoCount: details.analysis.types.video.length,
audioCount: details.analysis.types.audio.length,
imageCount: details.analysis.types.image.length
});
// 批量获取草稿信息
const multipleDrafts = {
"project1": "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258",
"project2": "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258"
};
const batchResults = await draftManager.getBatchDrafts(multipleDrafts);
console.log('批量草稿信息:', batchResults);
// 监控草稿文件变化
const draftId = "2f52a63b-8c6a-4417-8b01-1b2a569ccb6c";
const stopMonitoring = await draftManager.monitorDraftChanges(draftId, (changes) => {
console.log('草稿文件发生变化:', changes);
if (changes.added.length > 0) {
console.log('新增文件:', changes.added);
}
if (changes.removed.length > 0) {
console.log('删除文件:', changes.removed);
}
});
// 30秒后停止监控
setTimeout(() => {
stopMonitoring();
console.log('停止监控草稿变化');
}, 30000);
```
### Python 示例
```python
import requests
import re
import time
import threading
from urllib.parse import urlparse, parse_qs
from typing import Dict, List, Optional, Callable
class DraftManager:
def __init__(self, base_url: str = "https://api.assets.jcaigc.cn"):
self.base_url = base_url
def get_draft(self, draft_id: str) -> Dict:
"""获取草稿文件列表"""
response = requests.get(
f'{self.base_url}/openapi/capcut-mate/v1/get_draft',
params={'draft_id': draft_id},
headers={'Content-Type': 'application/json'}
)
response.raise_for_status()
return response.json()
def extract_draft_id(self, draft_url: str) -> Optional[str]:
"""从draft_url提取draft_id"""
try:
parsed_url = urlparse(draft_url)
query_params = parse_qs(parsed_url.fragment.split('?')[1] if '?' in parsed_url.fragment else '')
draft_id_param = query_params.get('drafId', [None])[0]
if draft_id_param:
match = re.search(r'/([^/]+)\.json$', draft_id_param)
return match.group(1) if match else None
return None
except Exception as e:
print(f"URL解析失败: {e}")
return None
def analyze_files(self, files: List[str]) -> Dict:
"""分析文件类型"""
analysis = {
'total': len(files),
'types': {
'config': [],
'video': [],
'audio': [],
'image': [],
'thumbnail': [],
'other': []
}
}
for file in files:
ext = file.split('.')[-1].lower() if '.' in file else ''
if ext == 'json':
analysis['types']['config'].append(file)
elif ext in ['mp4', 'avi', 'mov', 'mkv']:
analysis['types']['video'].append(file)
elif ext in ['mp3', 'wav', 'aac', 'flac']:
analysis['types']['audio'].append(file)
elif ext in ['jpg', 'jpeg', 'png', 'gif', 'bmp']:
if 'thumbnail' in file:
analysis['types']['thumbnail'].append(file)
else:
analysis['types']['image'].append(file)
else:
analysis['types']['other'].append(file)
return analysis
def get_draft_details(self, draft_url: str) -> Dict:
"""获取草稿详细信息"""
draft_id = self.extract_draft_id(draft_url)
if not draft_id:
raise ValueError('无法从URL中提取草稿ID')
result = self.get_draft(draft_id)
analysis = self.analyze_files(result['files'])
return {
'draft_id': draft_id,
'draft_url': draft_url,
'files': result['files'],
'analysis': analysis
}
def get_batch_drafts(self, draft_urls: Dict[str, str]) -> Dict:
"""批量获取草稿信息"""
results = {}
for name, url in draft_urls.items():
try:
details = self.get_draft_details(url)
results[name] = details
time.sleep(0.1) # 避免请求过快
except Exception as e:
print(f"获取草稿失败 {name}: {e}")
results[name] = {'error': str(e)}
return results
def monitor_draft_changes(self, draft_id: str, callback: Callable, interval_seconds: int = 5) -> str:
"""监控草稿文件变化"""
last_file_list = []
stop_event = threading.Event()
def check_changes():
nonlocal last_file_list
while not stop_event.is_set():
try:
result = self.get_draft(draft_id)
current_files = sorted(result['files'])
if current_files != last_file_list:
changes = {
'added': [f for f in current_files if f not in last_file_list],
'removed': [f for f in last_file_list if f not in current_files],
'current': current_files
}
callback(changes)
last_file_list = current_files
except Exception as e:
print(f"监控草稿变化失败: {e}")
stop_event.wait(interval_seconds)
# 初始检查
try:
result = self.get_draft(draft_id)
last_file_list = sorted(result['files'])
except Exception as e:
print(f"初始检查失败: {e}")
# 启动监控线程
thread = threading.Thread(target=check_changes, daemon=True)
thread.start()
# 返回停止函数
def stop_monitoring():
stop_event.set()
thread.join(timeout=1)
return stop_monitoring
# 使用示例
manager = DraftManager()
# 获取单个草稿
draft_url = "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258"
details = manager.get_draft_details(draft_url)
print(f"草稿ID: {details['draft_id']}")
print(f"文件总数: {details['analysis']['total']}")
print(f"视频文件: {len(details['analysis']['types']['video'])}个")
print(f"音频文件: {len(details['analysis']['types']['audio'])}个")
print(f"图片文件: {len(details['analysis']['types']['image'])}个")
# 批量获取草稿
multiple_drafts = {
"project1": "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258",
"project2": "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258"
}
batch_results = manager.get_batch_drafts(multiple_drafts)
for name, result in batch_results.items():
if 'error' not in result:
print(f"{name}: {result['analysis']['total']} 个文件")
# 监控草稿变化
def on_change(changes):
print(f"草稿文件发生变化:")
if changes['added']:
print(f"新增: {changes['added']}")
if changes['removed']:
print(f"删除: {changes['removed']}")
draft_id = "2f52a63b-8c6a-4417-8b01-1b2a569ccb6c"
stop_monitoring = manager.monitor_draft_changes(draft_id, on_change)
# 30秒后停止监控
time.sleep(30)
stop_monitoring()
print("停止监控")
```
## 错误码说明
| 错误码 | 错误信息 | 说明 | 解决方案 |
|--------|----------|------|----------|
| 400 | draft_id是必填项 | 缺少draft_id参数 | 提供有效的draft_id |
| 400 | draft_id长度无效 | draft_id长度不在20-32位范围内 | 检查draft_id格式是否正确 |
| 400 | draft_id格式无效 | draft_id格式不正确 | 确保使用正确的草稿ID格式 |
| 404 | 草稿不存在 | 指定的草稿ID无法找到 | 确认草稿ID是否正确且存在 |
| 500 | 获取文件列表失败 | 内部服务错误 | 联系技术支持或稍后重试 |
| 503 | 服务不可用 | 系统维护中 | 稍后重试 |
## 注意事项
1. **参数格式**: 确保draft_id格式正确且长度在20-32位之间
2. **ID提取**: 从draft_url正确提取draft_id
3. **文件类型**: 返回的文件列表包含多种类型的文件
4. **权限验证**: 确保有权限访问指定的草稿
5. **实时性**: 文件列表可能不是实时更新的,存在一定延迟
6. **文件状态**: 列表中的文件可能处于不同的处理状态
## 工作流程
1. 验证draft_id参数
2. 检查draft_id格式和长度
3. 查找指定的草稿
4. 获取草稿关联的所有文件
5. 返回文件列表
## 最佳实践
1. **ID验证**: 在调用前验证draft_id的有效性
2. **错误处理**: 妥善处理草稿不存在的情况
3. **文件分析**: 对返回的文件列表进行分类分析
4. **缓存策略**: 对于频繁查询的草稿,考虑适当缓存
5. **监控变化**: 对于需要实时更新的场景,实现变化监控
## 相关接口
- [创建草稿](./create_draft.md)
- [保存草稿](./save_draft.md)
- [添加视频](./add_videos.md)
- [添加音频](./add_audios.md)
- [添加图片](./add_images.md)
- [生成视频](./gen_video.md)
---
<div align="right">
📚 **项目资源**
**GitHub**: [https://github.com/Hommy-master/capcut-mate](https://github.com/Hommy-master/capcut-mate)
**Gitee**: [https://gitee.com/taohongmin-gitee/capcut-mate](https://gitee.com/taohongmin-gitee/capcut-mate)
</div>