From b17ad90b49f57c32ebb0eec297cbb72f28386bfe Mon Sep 17 00:00:00 2001 From: Hommy <16620803786@163.com> Date: Mon, 1 Dec 2025 22:47:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/add_audios.md | 489 ++------------------------------------------- 1 file changed, 18 insertions(+), 471 deletions(-) diff --git a/docs/add_audios.md b/docs/add_audios.md index c9716d2..373db28 100644 --- a/docs/add_audios.md +++ b/docs/add_audios.md @@ -1,19 +1,6 @@ # ADD_AUDIOS API 接口文档 -## 📋 目录 - -- [🔧 接口信息](#-接口信息) -- [🎯 功能描述](#-功能描述) -- [📥 请求参数](#-请求参数) -- [📤 响应格式](#-响应格式) -- [💻 使用示例](#-使用示例) -- [❌ 错误码说明](#-错误码说明) -- [⚠️ 注意事项](#️-注意事项) -- [🔄 工作流程](#-工作流程) -- [➡️ 下一步操作](#️-下一步操作) -- [🔗 相关接口](#-相关接口) - -## 🔧 接口信息 +## 接口信息 ``` POST /openapi/capcut-mate/v1/add_audios @@ -32,11 +19,11 @@ POST /openapi/capcut-mate/v1/add_audios ```json { "draft_url": "https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/get_draft?draft_id=2025092811473036584258", - "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/audio1.mp3\",\"start\":0,\"end\":5000000,\"duration\":10000000,\"volume\":0.8,\"fade_in\":1000000,\"fade_out\":1000000}]" + "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/audio1.mp3\",\"start\":0,\"end\":5000000,\"duration\":10000000,\"volume\":1.0,\"audio_effect\":\"reverb\"}]" } ``` -### 主要参数 +### 参数说明 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| @@ -53,9 +40,8 @@ audio_infos是一个JSON字符串,解析后为数组,每个元素包含以 | start | number | ✅ | - | 音频开始播放时间(微秒) | | end | number | ✅ | - | 音频结束播放时间(微秒) | | duration | number | ✅ | - | 音频总时长(微秒) | -| volume | number | ❌ | 1.0 | 音量大小(0-1) | -| fade_in | number | ❌ | 0 | 淡入时长(微秒) | -| fade_out | number | ❌ | 0 | 淡出时长(微秒) | +| volume | number | ❌ | 1.0 | 音量大小(0.0-2.0) | +| audio_effect | string | ❌ | None | 音频效果名称 | ### 参数详解 @@ -72,17 +58,13 @@ audio_infos是一个JSON字符串,解析后为数组,每个元素包含以 - 1.0 = 原始音量 - 0.5 = 一半音量 - 0.0 = 静音 - - 范围:0.0 - 1.0 + - 范围:0.0 - 2.0 -#### 淡入淡出效果 +#### 音频效果 -- **fade_in**: 淡入效果时长 - - 0 = 无淡入效果 - - 建议范围:500,000 - 3,000,000微秒(0.5-3秒) - -- **fade_out**: 淡出效果时长 - - 0 = 无淡出效果 - - 建议范围:500,000 - 3,000,000微秒(0.5-3秒) +- **audio_effect**: 音频效果名称 + - None = 无音频效果 + - 示例:`"reverb"`(混响效果) ## 响应格式 @@ -134,7 +116,7 @@ curl -X POST https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/add_audios \ -H "Content-Type: application/json" \ -d '{ "draft_url": "YOUR_DRAFT_URL", - "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/intro.mp3\",\"start\":0,\"end\":3000000,\"duration\":5000000,\"volume\":1.0,\"fade_in\":500000},{\"audio_url\":\"https://assets.jcaigc.cn/bgm.mp3\",\"start\":3000000,\"end\":30000000,\"duration\":35000000,\"volume\":0.6}]" + "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/intro.mp3\",\"start\":0,\"end\":3000000,\"duration\":5000000,\"volume\":1.0},{\"audio_url\":\"https://assets.jcaigc.cn/bgm.mp3\",\"start\":3000000,\"end\":30000000,\"duration\":35000000,\"volume\":0.6}]" }' ``` @@ -145,446 +127,10 @@ curl -X POST https://capcut-mate.jcaigc.cn/openapi/capcut-mate/v1/add_audios \ -H "Content-Type: application/json" \ -d '{ "draft_url": "YOUR_DRAFT_URL", - "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/outro.mp3\",\"start\":25000000,\"end\":30000000,\"duration\":8000000,\"volume\":0.9,\"fade_in\":1000000,\"fade_out\":2000000}]" + "audio_infos": "[{\"audio_url\":\"https://assets.jcaigc.cn/outro.mp3\",\"start\":25000000,\"end\":30000000,\"duration\":8000000,\"volume\":0.9,\"audio_effect\":\"reverb\"}]" }' ``` -### JavaScript 示例 - -```javascript -const addAudios = async (draftUrl, audioConfig) => { - const response = await fetch('/openapi/capcut-mate/v1/add_audios', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - draft_url: draftUrl, - ...audioConfig - }) - }); - return response.json(); -}; - -// 基本音频添加 -const basicAudio = { - audio_infos: JSON.stringify([ - { - audio_url: "https://assets.jcaigc.cn/bgm.mp3", - start: 0, - end: 10000000, - duration: 15000000, - volume: 0.8 - } - ]) -}; - -// 音频序列 -const audioSequence = { - audio_infos: JSON.stringify([ - { - audio_url: "https://assets.jcaigc.cn/intro.mp3", - start: 0, - end: 3000000, - duration: 5000000, - volume: 1.0, - fade_in: 500000 - }, - { - audio_url: "https://assets.jcaigc.cn/main-bgm.mp3", - start: 2000000, - end: 25000000, - duration: 30000000, - volume: 0.6 - }, - { - audio_url: "https://assets.jcaigc.cn/outro.mp3", - start: 24000000, - end: 28000000, - duration: 6000000, - volume: 0.9, - fade_out: 1500000 - } - ]) -}; - -// 音效组合 -const soundEffects = { - audio_infos: JSON.stringify([ - { - audio_url: "https://assets.jcaigc.cn/applause.mp3", - start: 5000000, - end: 8000000, - duration: 4000000, - volume: 0.7 - }, - { - audio_url: "https://assets.jcaigc.cn/transition.mp3", - start: 12000000, - end: 13500000, - duration: 2000000, - volume: 0.5 - } - ]) -}; - -try { - const result1 = await addAudios(draftUrl, basicAudio); - const result2 = await addAudios(draftUrl, audioSequence); - const result3 = await addAudios(draftUrl, soundEffects); - - console.log('音频添加成功:', { - basic: result1, - sequence: result2, - effects: result3 - }); -} catch (error) { - console.error('添加失败:', error); -} -``` - -### 高级JavaScript示例 - -```javascript -class AudioManager { - constructor(baseUrl = 'https://capcut-mate.jcaigc.cn') { - this.baseUrl = baseUrl; - } - - async addAudios(draftUrl, audioConfig) { - const response = await fetch(`${this.baseUrl}/openapi/capcut-mate/v1/add_audios`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - draft_url: draftUrl, - ...audioConfig - }) - }); - return response.json(); - } - - // 创建背景音乐 - createBackgroundMusic(audioUrl, totalDuration, volume = 0.6, loop = false) { - const audios = []; - - if (loop) { - // 循环播放逻辑 - let currentTime = 0; - while (currentTime < totalDuration) { - audios.push({ - audio_url: audioUrl, - start: currentTime, - end: Math.min(currentTime + 30000000, totalDuration), // 假设30秒循环 - duration: 30000000, - volume: volume - }); - currentTime += 30000000; - } - } else { - audios.push({ - audio_url: audioUrl, - start: 0, - end: totalDuration, - duration: totalDuration, - volume: volume - }); - } - - return { - audio_infos: JSON.stringify(audios) - }; - } - - // 创建音频序列 - createAudioSequence(audioList, crossFadeDuration = 1000000) { - const audios = []; - let currentTime = 0; - - audioList.forEach((audio, index) => { - const audioInfo = { - audio_url: audio.url, - start: currentTime, - end: currentTime + audio.playDuration, - duration: audio.totalDuration, - volume: audio.volume || 1.0 - }; - - // 添加交叉淡入淡出 - if (index > 0) { - audioInfo.fade_in = crossFadeDuration; - // 调整前一个音频的淡出 - if (audios[index - 1]) { - audios[index - 1].fade_out = crossFadeDuration; - } - } - - // 最后一个音频淡出 - if (index === audioList.length - 1) { - audioInfo.fade_out = audio.fadeOut || crossFadeDuration; - } - - audios.push(audioInfo); - currentTime += audio.playDuration - (index > 0 ? crossFadeDuration : 0); - }); - - return { - audio_infos: JSON.stringify(audios) - }; - } - - // 创建音效轨道 - createSoundEffects(effects) { - const audios = effects.map(effect => ({ - audio_url: effect.url, - start: effect.startTime, - end: effect.startTime + effect.duration, - duration: effect.duration, - volume: effect.volume || 0.7, - fade_in: effect.fadeIn || 0, - fade_out: effect.fadeOut || 0 - })); - - return { - audio_infos: JSON.stringify(audios) - }; - } - - // 创建旁白音频 - createNarration(narrationList) { - const audios = narrationList.map(narration => ({ - audio_url: narration.url, - start: narration.startTime, - end: narration.startTime + narration.duration, - duration: narration.duration, - volume: narration.volume || 0.9, - fade_in: 200000, // 0.2秒淡入 - fade_out: 200000 // 0.2秒淡出 - })); - - return { - audio_infos: JSON.stringify(audios) - }; - } - - // 批量处理音频 - async batchProcessAudios(draftUrl, audioConfigs) { - const results = []; - - for (const config of audioConfigs) { - try { - const result = await this.addAudios(draftUrl, config); - results.push(result); - - // 添加延迟避免请求过快 - await new Promise(resolve => setTimeout(resolve, 100)); - } catch (error) { - console.error('音频处理失败:', error); - results.push({ error: error.message }); - } - } - - return results; - } -} - -// 使用示例 -const audioManager = new AudioManager(); - -// 创建背景音乐 -const bgm = audioManager.createBackgroundMusic( - "https://assets.jcaigc.cn/bgm.mp3", - 60000000, // 60秒 - 0.6, - true // 循环播放 -); - -// 创建音频序列 -const sequence = audioManager.createAudioSequence([ - { - url: "https://assets.jcaigc.cn/intro.mp3", - playDuration: 5000000, - totalDuration: 5000000, - volume: 1.0 - }, - { - url: "https://assets.jcaigc.cn/main.mp3", - playDuration: 20000000, - totalDuration: 25000000, - volume: 0.8 - }, - { - url: "https://assets.jcaigc.cn/outro.mp3", - playDuration: 3000000, - totalDuration: 3000000, - volume: 1.0, - fadeOut: 2000000 - } -]); - -// 创建音效 -const effects = audioManager.createSoundEffects([ - { - url: "https://assets.jcaigc.cn/whoosh.mp3", - startTime: 10000000, - duration: 1500000, - volume: 0.5 - }, - { - url: "https://assets.jcaigc.cn/ding.mp3", - startTime: 25000000, - duration: 1000000, - volume: 0.8 - } -]); - -// 批量处理 -await audioManager.batchProcessAudios(draftUrl, [bgm, sequence, effects]); -``` - -### Python 示例 - -```python -import requests -import json -from typing import List, Dict, Optional - -class AudioProcessor: - def __init__(self, base_url="https://capcut-mate.jcaigc.cn"): - self.base_url = base_url - - def add_audios(self, draft_url: str, audio_config: Dict) -> Dict: - response = requests.post( - f'{self.base_url}/openapi/capcut-mate/v1/add_audios', - headers={'Content-Type': 'application/json'}, - json={ - "draft_url": draft_url, - **audio_config - } - ) - return response.json() - - def create_background_music(self, audio_url: str, total_duration: int, - volume: float = 0.6, loop: bool = False) -> Dict: - """创建背景音乐""" - audios = [] - - if loop: - current_time = 0 - audio_duration = 30000000 # 假设30秒循环 - - while current_time < total_duration: - end_time = min(current_time + audio_duration, total_duration) - audios.append({ - "audio_url": audio_url, - "start": current_time, - "end": end_time, - "duration": audio_duration, - "volume": volume - }) - current_time += audio_duration - else: - audios.append({ - "audio_url": audio_url, - "start": 0, - "end": total_duration, - "duration": total_duration, - "volume": volume - }) - - return {"audio_infos": json.dumps(audios)} - - def create_audio_sequence(self, audio_list: List[Dict], - cross_fade_duration: int = 1000000) -> Dict: - """创建音频序列""" - audios = [] - current_time = 0 - - for i, audio in enumerate(audio_list): - audio_info = { - "audio_url": audio["url"], - "start": current_time, - "end": current_time + audio["play_duration"], - "duration": audio["total_duration"], - "volume": audio.get("volume", 1.0) - } - - # 添加交叉淡入淡出 - if i > 0: - audio_info["fade_in"] = cross_fade_duration - if audios: - audios[-1]["fade_out"] = cross_fade_duration - - # 最后一个音频淡出 - if i == len(audio_list) - 1: - audio_info["fade_out"] = audio.get("fade_out", cross_fade_duration) - - audios.append(audio_info) - current_time += audio["play_duration"] - (cross_fade_duration if i > 0 else 0) - - return {"audio_infos": json.dumps(audios)} - - def create_sound_effects(self, effects: List[Dict]) -> Dict: - """创建音效轨道""" - audios = [] - - for effect in effects: - audios.append({ - "audio_url": effect["url"], - "start": effect["start_time"], - "end": effect["start_time"] + effect["duration"], - "duration": effect["duration"], - "volume": effect.get("volume", 0.7), - "fade_in": effect.get("fade_in", 0), - "fade_out": effect.get("fade_out", 0) - }) - - return {"audio_infos": json.dumps(audios)} - -# 使用示例 -processor = AudioProcessor() - -# 背景音乐 -bgm_config = processor.create_background_music( - "https://assets.jcaigc.cn/bgm.mp3", - 60000000, # 60秒 - volume=0.6, - loop=True -) - -# 音频序列 -sequence_config = processor.create_audio_sequence([ - { - "url": "https://assets.jcaigc.cn/intro.mp3", - "play_duration": 5000000, - "total_duration": 5000000, - "volume": 1.0 - }, - { - "url": "https://assets.jcaigc.cn/main.mp3", - "play_duration": 20000000, - "total_duration": 25000000, - "volume": 0.8 - } -]) - -# 音效 -effects_config = processor.create_sound_effects([ - { - "url": "https://assets.jcaigc.cn/whoosh.mp3", - "start_time": 10000000, - "duration": 1500000, - "volume": 0.5 - } -]) - -# 添加到草稿 -draft_url = "YOUR_DRAFT_URL" -results = [] - -for config in [bgm_config, sequence_config, effects_config]: - result = processor.add_audios(draft_url, config) - results.append(result) - print(f"音频添加成功: {result['track_id']}") -``` - ## 错误码说明 | 错误码 | 错误信息 | 说明 | 解决方案 | @@ -595,7 +141,7 @@ for config in [bgm_config, sequence_config, effects_config]: | 400 | 音频配置验证失败 | 音频参数不符合要求 | 检查每个音频的参数 | | 400 | audio_url是必填项 | 音频URL缺失 | 为每个音频提供URL | | 400 | 时间范围无效 | end必须大于start | 确保结束时间大于开始时间 | -| 400 | 音量值无效 | volume不在0-1范围内 | 使用0-1之间的音量值 | +| 400 | 音量值无效 | volume不在0.0-2.0范围内 | 使用0.0-2.0之间的音量值 | | 404 | 草稿不存在 | 指定的草稿URL无效 | 检查草稿URL是否正确 | | 404 | 音频资源不存在 | 音频URL无法访问 | 检查音频URL是否可访问 | | 500 | 音频处理失败 | 内部处理错误 | 联系技术支持 | @@ -607,9 +153,8 @@ for config in [bgm_config, sequence_config, effects_config]: 3. **音频格式**: 确保音频文件格式被支持(如MP3、WAV、AAC等) 4. **文件大小**: 大音频文件可能影响处理速度 5. **网络访问**: 音频URL必须可以正常访问 -6. **音量范围**: 音量值必须在0.0-1.0范围内 -7. **淡入淡出**: 淡入淡出时长不能超过音频播放时长 -8. **轨道限制**: 同一时间段可能存在音频重叠 +6. **音量范围**: 音量值必须在0.0-2.0范围内 +7. **轨道限制**: 同一时间段可能存在音频重叠 ## 工作流程 @@ -619,7 +164,7 @@ for config in [bgm_config, sequence_config, effects_config]: 4. 获取并解密草稿内容 5. 创建音频轨道 6. 添加音频片段到轨道 -7. 应用音量和淡入淡出效果 +7. 应用音量和音频效果 8. 保存并加密草稿 9. 返回处理结果 @@ -631,6 +176,8 @@ for config in [bgm_config, sequence_config, effects_config]: - [保存草稿](./save_draft.md) - [生成视频](./gen_video.md) +--- +
📚 **项目资源**