用Suno创作一首属于自己的歌曲:从零到精通完全指南
1. Suno AI音乐创作全景图
1.1 Suno核心技术解析
graph TB
A[Suno AI音乐创作平台] --> B[输入层]
A --> C[处理层]
A --> D[输出层]
B --> B1[文本提示]
B --> B2[旋律哼唱]
B --> B3[风格参考]
B --> B4[情绪设定]
C --> C1[歌词生成]
C --> C2[旋律创作]
C --> C3[和声编排]
C --> C4[乐器配器]
D --> D1[完整歌曲]
D --> D2[多版本]
D --> D3[音轨分离]
D --> D4[格式导出]
1.2 平台特性与限制对比
| 特性 |
Suno v3 |
Suno Chirp |
竞品对比 |
| 歌曲长度 |
1-3分钟 |
30-60秒 |
同水平 |
| 音质 |
CD级 |
良好 |
行业领先 |
| 风格支持 |
100+种 |
50+种 |
最丰富 |
| 人声质量 |
真人级 |
良好 |
业界最佳 |
| 自定义度 |
高 |
中 |
最高 |
| API支持 |
有 |
无 |
部分有 |
| 成本 |
$10-30/月 |
免费有限 |
中等 |
2. 入门篇:5分钟创作第一首歌
2.1 Suno Web端快速上手
"""
Suno AI音乐创作快速入门脚本
通过API创建你的第一首AI歌曲
"""
import requests
import json
import time
import os
from pathlib import Path
from dotenv import load_dotenv
from typing import Dict, List, Optional, Tuple
import base64
class SunoMusicCreator:
"""Suno音乐创作器"""
def __init__(self, api_key=None, session_id=None):
load_dotenv()
self.api_key = api_key or os.getenv('SUNO_API_KEY')
self.session_id = session_id or os.getenv('SUNO_SESSION_ID')
if not self.api_key and not self.session_id:
print("⚠️ 警告:未设置API密钥或Session ID,部分功能可能受限")
self.base_url = "https://api.suno.ai"
self.headers = {
"Authorization": f"Bearer {self.api_key}" if self.api_key else "",
"Content-Type": "application/json"
}
self.browser_mode = not self.api_key
if self.browser_mode:
print("🔍 使用浏览器模式(需要手动操作)")
self.output_dir = Path("suno_music")
self.output_dir.mkdir(exist_ok=True)
self.genre_library = {
"流行": ["pop", "流行", "朗朗上口", "电台热门"],
"摇滚": ["rock", "摇滚", "吉他", "鼓点强劲"],
"民谣": ["acoustic", "民谣", "吉他弹唱", "抒情"],
"嘻哈": ["hiphop", "嘻哈", "说唱", "节奏感强"],
"电子": ["electronic", "电子", "EDM", "合成器"],
"R&B": ["rnb", "节奏布鲁斯", "灵魂乐", "抒情"],
"爵士": ["jazz", "爵士", "萨克斯", "即兴"],
"古典": ["classical", "古典", "交响", "钢琴"],
"国风": ["chinese traditional", "国风", "古风", "中国风"],
"乡村": ["country", "乡村", "吉他", "田园"]
}
self.mood_library = {
"快乐": ["happy", "欢快", "兴奋", "正能量"],
"悲伤": ["sad", "悲伤", "忧郁", "抒情"],
"浪漫": ["romantic", "浪漫", "爱情", "温柔"],
"励志": ["inspiring", "励志", "振奋", "力量"],
"放松": ["relaxing", "放松", "舒缓", "平静"],
"激情": ["energetic", "激情", "动感", "活力"],
"神秘": ["mysterious", "神秘", "悬疑", "奇幻"],
"怀旧": ["nostalgic", "怀旧", "复古", "回忆"]
}
print("🎵 Suno音乐创作器初始化完成")
def create_song_from_prompt(self, prompt: str, make_instrumental: bool = False,
custom_mode: bool = False, **kwargs) -> Optional[Dict]:
"""从提示词创建歌曲"""
print(f"🎶 正在创作歌曲: '{prompt[:50]}...'")
if self.browser_mode:
print("🌐 浏览器模式:请手动操作")
print(f"提示词: {prompt}")
return self._browser_mode_instructions(prompt, **kwargs)
data = {
"prompt": prompt,
"make_instrumental": make_instrumental,
"wait_audio": kwargs.get("wait_audio", True)
}
if custom_mode:
data.update({
"title": kwargs.get("title", ""),
"tags": kwargs.get("tags", ""),
"mv": kwargs.get("mv", "chirp-v3-5"),
"continue_at": kwargs.get("continue_at", None),
"continue_clip_id": kwargs.get("continue_clip_id", None)
})
try:
endpoint = "/api/generate/v2/" if custom_mode else "/api/generate"
response = requests.post(
f"{self.base_url}{endpoint}",
headers=self.headers,
json=data,
timeout=60
)
if response.status_code == 200:
result = response.json()
if custom_mode:
clips = result.get("clips", [])
if clips:
clip_id = clips[0]["id"]
print(f"📤 歌曲任务已提交,Clip ID: {clip_id}")
audio_url = self._poll_clip_status(clip_id)
if audio_url:
audio_path = self._download_audio(audio_url, prompt)
return {
"clip_id": clip_id,
"audio_url": audio_url,
"audio_path": audio_path,
"prompt": prompt
}
else:
clip_ids = result.get("id", [])
if clip_ids:
print(f"📤 生成任务已提交,ID: {clip_ids[0]}")
return {"task_id": clip_ids[0], "prompt": prompt}
return None
else:
print(f"❌ API请求失败: {response.status_code}")
print(f"响应: {response.text}")
return None
except Exception as e:
print(f"❌ 请求过程中出错: {str(e)}")
return None
def generate_with_lyrics(self, title: str, lyrics: str, genre: str = "流行",
mood: str = "快乐", **kwargs) -> Optional[Dict]:
"""使用自定义歌词生成歌曲"""
prompt = self._build_lyrics_prompt(title, lyrics, genre, mood)
print(f"📝 使用自定义歌词生成歌曲: '{title}'")
print(f"🎵 风格: {genre}, 情绪: {mood}")
print(f"📄 歌词行数: {len(lyrics.splitlines())}")
return self.create_song_from_prompt(prompt, **kwargs)
def create_song_series(self, theme: str, num_songs: int = 3,
genres: List[str] = None) -> List[Dict]:
"""创建主题系列歌曲"""
if genres is None:
genres = ["流行", "民谣", "电子"]
results = []
print(f"\n{'='*60}")
print(f"🎼 开始创作系列歌曲: {theme}")
print(f"📊 数量: {num_songs}, 风格: {', '.join(genres)}")
print(f"{'='*60}\n")
for i in range(num_songs):
genre = genres[i % len(genres)]
mood = self._get_series_mood(theme, i, num_songs)
title = self._generate_song_title(theme, genre, mood, i+1)
lyrics = self._generate_lyrics_for_theme(theme, genre, mood)
print(f"\n▶️ 创作第 {i+1}/{num_songs} 首歌曲")
print(f" 标题: {title}")
print(f" 风格: {genre}, 情绪: {mood}")
result = self.generate_with_lyrics(
title=title,
lyrics=lyrics,
genre=genre,
mood=mood,
wait_audio=True
)
if result:
result.update({
"song_number": i+1,
"title": title,
"genre": genre,
"mood": mood,
"lyrics_preview": lyrics[:100] + "..." if len(lyrics) > 100 else lyrics
})
results.append(result)
if i < num_songs - 1:
print("⏸️ 等待25秒继续下一首...")
time.sleep(25)
self._generate_series_report(results, theme)
return results
def _build_lyrics_prompt(self, title: str, lyrics: str, genre: str, mood: str) -> str:
"""构建歌词提示词"""
genre_keywords = self.genre_library.get(genre, ["pop"])
mood_keywords = self.mood_library.get(mood, ["happy"])
prompt = f"歌曲标题:{title}\n\n"
prompt += f"风格:{genre},{', '.join(genre_keywords)}\n"
prompt += f"情绪:{mood},{', '.join(mood_keywords)}\n\n"
prompt += "歌词:\n"
prompt += lyrics + "\n\n"
prompt += "请为以上歌词创作一首完整的歌曲,包含主歌、副歌、桥段等结构,"
prompt += "确保旋律优美,节奏与情绪匹配。"
return prompt
def _generate_song_title(self, theme: str, genre: str, mood: str, number: int) -> str:
"""生成歌曲标题"""
titles = {
"爱情": ["心动时刻", "永恒誓言", "相思成海", "爱如初见"],
"友情": ["并肩同行", "青春纪念册", "友谊万岁", "最好的我们"],
"梦想": ["追光者", "星辰大海", "破晓时分", "勇往直前"],
"自然": ["风之诗", "山川入梦", "四季之歌", "听雨"],
"城市": ["霓虹之下", "地铁末班车", "城市之光", "夜未央"]
}
for key, title_list in titles.items():
if key in theme:
return f"{title_list[(number-1) % len(title_list)]} - {theme}"
default_titles = [
f"{theme}之歌",
f"关于{theme}",
f"{theme}的旋律",
f"{theme}幻想曲"
]
return default_titles[(number-1) % len(default_titles)]
def _generate_lyrics_for_theme(self, theme: str, genre: str, mood: str) -> str:
"""为主题生成歌词"""
templates = {
"流行": {
"结构": ["主歌A", "副歌", "主歌B", "副歌", "桥段", "副歌"],
"押韵": "AABB"
},
"民谣": {
"结构": ["主歌A", "主歌B", "副歌", "主歌C", "副歌"],
"押韵": "ABAB"
},
"摇滚": {
"结构": ["主歌", "副歌", "吉他独奏", "主歌", "副歌"],
"押韵": "自由"
},
"嘻哈": {
"结构": ["Intro", "Verse 1", "Hook", "Verse 2", "Hook", "Outro"],
"押韵": "多押"
}
}
template = templates.get(genre, templates["流行"])
lyric_lines = []
if "快乐" in mood or "兴奋" in mood:
lyric_lines.extend([
f"阳光洒满每个角落",
f"心中的快乐在唱歌",
f"让我们一起跳起舞",
f"忘记所有烦恼忧愁"
])
elif "悲伤" in mood or "忧郁" in mood:
lyric_lines.extend([
f"雨滴轻轻敲打窗棂",
f"回忆在夜色中蔓延",
f"逝去的时光不再回",
f"只留下思念的旋律"
])
elif "浪漫" in mood:
lyric_lines.extend([
f"星光点亮你的眼眸",
f"温柔在指尖轻轻流",
f"这一刻仿佛成永恒",
f"爱在心跳声中绽放"
])
else:
lyric_lines.extend([
f"追寻着远方的梦想",
f"脚步不停向前方",
f"即使风雨阻挡路途",
f"心中的火焰永不灭"
])
lyrics = ""
section_labels = template["结构"]
for i, section in enumerate(section_labels):
lyrics += f"[{section}]\n"
lines_in_section = 4 if "副歌" in section else 2
start_idx = (i * 2) % len(lyric_lines)
for j in range(lines_in_section):
line_idx = (start_idx + j) % len(lyric_lines)
lyrics += lyric_lines[line_idx] + "\n"
lyrics += "\n"
return lyrics.strip()
def _get_series_mood(self, theme: str, index: int, total: int) -> str:
"""获取系列歌曲情绪"""
moods = ["快乐", "浪漫", "励志", "怀旧", "放松"]
if "爱情" in theme:
mood_sequence = ["浪漫", "快乐", "悲伤", "怀旧"]
elif "梦想" in theme:
mood_sequence = ["励志", "激情", "快乐", "放松"]
elif "自然" in theme:
mood_sequence = ["放松", "神秘", "快乐", "怀旧"]
else:
mood_sequence = moods
return mood_sequence[index % len(mood_sequence)]
def _poll_clip_status(self, clip_id: str, max_attempts: int = 30) -> Optional[str]:
"""轮询Clip状态"""
print("⏳ 等待音频生成...", end="", flush=True)
for attempt in range(max_attempts):
time.sleep(10)
try:
status_response = requests.get(
f"{self.base_url}/api/clip/{clip_id}",
headers=self.headers,
timeout=10
)
if status_response.status_code == 200:
status_data = status_response.json()
status = status_data.get("status")
print(".", end="", flush=True)
if status == "complete":
print("\n✅ 音频生成完成!")
return status_data.get("audio_url")
elif status == "failed":
print(f"\n❌ 生成失败")
return None
else:
print(f"\n⚠️ 状态查询失败: {status_response.status_code}")
except Exception as e:
print(f"\n⚠️ 状态查询异常: {str(e)}")
print(f"\n❌ 生成超时({max_attempts * 10}秒)")
return None
def _download_audio(self, audio_url: str, prompt: str) -> Optional[Path]:
"""下载音频文件"""
try:
timestamp = time.strftime("%Y%m%d_%H%M%S")
safe_prompt = "".join(c for c in prompt[:30] if c.isalnum() or c in (' ', '-', '_')).rstrip()
filename = f"{timestamp}_{safe_prompt}.mp3"
filepath = self.output_dir / filename
print(f"⬇️ 下载音频到: {filepath}")
response = requests.get(audio_url, stream=True, timeout=30)
if response.status_code == 200:
total_size = int(response.headers.get('content-length', 0))
downloaded = 0
with open(filepath, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
downloaded += len(chunk)
if total_size > 0:
percent = downloaded / total_size * 100
print(f"\r下载进度: {percent:.1f}%", end="", flush=True)
print(f"\n✅ 下载完成!大小: {filepath.stat().st_size / 1024:.1f} KB")
return filepath
else:
print(f"❌ 下载失败: {response.status_code}")
return None
except Exception as e:
print(f"❌ 下载过程中出错: {str(e)}")
return None
def _browser_mode_instructions(self, prompt: str, **kwargs) -> Dict:
"""浏览器模式操作指南"""
instructions = f"""
🌐 浏览器模式操作指南
====================
由于未设置API密钥,请按以下步骤手动操作:
1. 访问 https://suno.com
2. 登录您的Suno账户
3. 点击"Create"或"生成"按钮
4. 在提示词框中输入:
{prompt}
5. 选择参数:
- 风格: {kwargs.get('style', '默认')}
- 长度: {kwargs.get('duration', '2分钟')}
- 乐器: {kwargs.get('instrumental', False)}
6. 点击"Generate"开始创作
7. 等待1-3分钟生成完成
8. 下载生成的音频文件
完成后,请将文件保存到: {self.output_dir.absolute()}/
"""
print(instructions)
instructions_file = self.output_dir / "browser_instructions.txt"
with open(instructions_file, 'w', encoding='utf-8') as f:
f.write(instructions)
return {
"mode": "browser",
"instructions_file": str(instructions_file),
"prompt": prompt
}
def _generate_series_report(self, results: List[Dict], theme: str):
"""生成系列歌曲报告"""
report_path = self.output_dir / f"{theme}_series_report.md"
with open(report_path, 'w', encoding='utf-8') as f:
f.write(f"# 系列歌曲创作报告: {theme}\n\n")
f.write(f"生成时间: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
success_count = sum(1 for r in results if r.get('audio_path'))
total_count = len(results)
f.write("## 📊 统计信息\n")
f.write(f"- 计划创作: {total_count} 首\n")
f.write(f"- 成功创作: {success_count} 首\n")
f.write(f"- 成功率: {success_count/total_count*100:.1f}%\n\n")
f.write("## 🎵 歌曲列表\n\n")
for i, result in enumerate(results, 1):
song_number = result.get('song_number', i)
title = result.get('title', f'歌曲{song_number}')
genre = result.get('genre', '未知')
mood = result.get('mood', '未知')
if result.get('audio_path'):
status_icon = "✅"
file_info = f"文件: `{Path(result['audio_path']).name}`"
else:
status_icon = "❌"
file_info = "状态: 生成失败"
f.write(f"### {status_icon} 第{song_number}首: {title}\n")
f.write(f"- **风格**: {genre}\n")
f.write(f"- **情绪**: {mood}\n")
f.write(f"- **歌词预览**: {result.get('lyrics_preview', '')}\n")
f.write(f"- **{file_info}**\n\n")
f.write("## 💡 创作建议\n\n")
if success_count == total_count:
f.write("✅ 系列创作非常成功!建议:\n")
f.write("1. 考虑制作专辑封面\n")
f.write("2. 为歌曲添加介绍文案\n")
f.write("3. 发布到音乐平台\n")
elif success_count >= total_count * 0.7:
f.write("👍 大部分歌曲创作成功,建议:\n")
f.write("1. 重新尝试失败的几首\n")
f.write("2. 调整提示词参数\n")
f.write("3. 检查网络连接\n")
else:
f.write("⚠️ 创作成功率较低,建议:\n")
f.write("1. 简化提示词\n")
f.write("2. 缩短歌曲长度\n")
f.write("3. 使用更常见的风格\n")
f.write("4. 检查API配额\n")
print(f"📊 系列报告已生成: {report_path}")
if __name__ == "__main__":
creator = SunoMusicCreator()
print("示例1: 使用提示词创作歌曲")
prompt = "创作一首关于夏天的流行歌曲,欢快节奏,有海浪声和海鸥叫声,副歌朗朗上口"
result = creator.create_song_from_prompt(prompt, wait_audio=True)
if result and result.get('audio_path'):
print(f"🎉 歌曲创作成功: {result['audio_path']}")
print("\n示例2: 使用自定义歌词创作")
custom_lyrics = """
[主歌]
清晨的阳光洒在脸上
新的一天开始了旅程
微风轻拂发梢的时候
心中充满希望的光芒
[副歌]
向前走,不回头
梦想在远方招手
每一步,都坚定
勇敢追求心中的自由
[主歌]
路上的风景虽然曲折
但每一步都值得珍藏
那些汗水浇灌的时光
终将开出最美的花朵
[副歌]
向前走,不回头
梦想在远方招手
每一步,都坚定
勇敢追求心中的自由
"""
result = creator.generate_with_lyrics(
title="勇敢前行",
lyrics=custom_lyrics,
genre="流行",
mood="励志",
wait_audio=True
)
if result and result.get('audio_path'):
print(f"🎉 自定义歌曲创作成功: {result['audio_path']}")
print("\n示例3: 创作爱情主题系列歌曲")
series_results = creator.create_song_series(
theme="爱情旅程",
num_songs=4,
genres=["流行", "民谣", "R&B", "电子"]
)
print(f"\n系列创作完成!成功 {len([r for r in series_results if r.get('audio_path')])} 首")
2.2 环境配置与访问方式
# Suno AI音乐创作环境配置指南
## 第一步:获取访问权限
### 方案A:官方Web端(推荐新手)
1. 访问 https://suno.com
2. 使用Google账号或邮箱注册
3. 每日免费额度:10 credits(约5-10首歌)
4. 升级计划:$10-30/月(无限生成)
### 方案B:API访问(开发者)
1. 访问 https://suno.com/api
2. 申请API访问权限(可能需要等待)
3. 获取API密钥
4. 查看文档和限制
### 方案C:Discord Bot(社区版)
1. 加入Suno Discord: https://discord.gg/suno
2. 在#music-generation频道使用命令
3. 免费但有排队限制
## 第二步:本地环境配置
```bash
# 1. 安装Python 3.8+
python --version
# 2. 创建虚拟环境
python -m venv suno-music
# 3. 激活虚拟环境
# Windows:
suno-music\Scripts\activate
# Mac/Linux:
source suno-music/bin/activate
# 4. 安装依赖包
pip install requests python-dotenv pandas openai
# 5. 创建环境变量文件
cat > .env << EOF
# Suno配置
SUNO_API_KEY=your_suno_api_key_here
SUNO_SESSION_ID=your_session_cookie_here # 可选
# OpenAI配置(用于歌词生成)
OPENAI_API_KEY=your_openai_key_here
# 项目配置
DEFAULT_GENRE=pop
DEFAULT_MOOD=happy
OUTPUT_FORMAT=mp3
EOF
# 6. 创建项目结构
mkdir -p suno_music/{songs,lyrics,projects}
mkdir -p assets/{covers,templates}
mkdir -p scripts/{generators,processors}
第三步:快速测试
import os
from dotenv import load_dotenv
def test_suno_environment():
load_dotenv()
print("🔍 Suno音乐创作环境测试")
print("="*50)
configs = {
"SUNO_API_KEY": "Suno API密钥",
"OPENAI_API_KEY": "OpenAI密钥(歌词生成)",
"DEFAULT_GENRE": "默认音乐风格"
}
for env_key, description in configs.items():
value = os.getenv(env_key)
if value:
print(f"✅ {description}: 已设置")
else:
print(f"⚠️ {description}: 未设置(部分功能受限)")
import os.path as op
directories = ['suno_music', 'assets', 'scripts']
for dir_name in directories:
if op.exists(dir_name):
print(f"✅ 目录 '{dir_name}': 存在")
else:
print(f"❌ 目录 '{dir_name}': 不存在")
print("="*50)
print("🎵 测试完成!开始你的音乐创作之旅吧!")
if __name__ == "__main__":
test_suno_environment()
第四步:Web端快速上手
1. 基本操作流程:
- 访问 https://suno.com 并登录
- 点击"Create"按钮
- 在文本框中输入你的想法
- 选择风格参数
- 点击"Generate"
- 等待1-3分钟生成
- 试听并下载
2. 提示词示例:
- 中文:
创作一首关于春天的民谣,吉他伴奏,温暖治愈
- 英文:
Create a pop song about summer love with catchy chorus
- 混合:
Make a Chinese traditional style song with erhu and piano
3. 实用技巧:
- 使用具体形容词:明亮、温柔、激情、梦幻
- 指定乐器:钢琴、吉他、鼓、合成器
- 描述场景:雨中漫步、星空下、城市夜晚
- 设定情绪:快乐、悲伤、浪漫、励志
## 3. 进阶篇:专业音乐创作技巧
### 3.1 歌词工程与结构设计
```python
# lyrics_engineering.py
"""
专业歌词工程系统
生成结构化、有韵律的歌词
"""
import json
import random
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
class SongStructure(Enum):
"""歌曲结构类型"""
POP_STANDARD = "流行标准" # 主歌-副歌-主歌-副歌-桥段-副歌
BALLAD = "民谣" # 主歌-主歌-副歌-主歌-副歌
ROCK = "摇滚" # 主歌-副歌-吉他独奏-主歌-副歌
HIPHOP = "嘻哈" # Intro-Verse-Hook-Verse-Hook-Outro
EDM = "电子舞曲" # Intro-Buildup-Drop-Bridge-Drop-Outro
class RhymeScheme(Enum):
"""押韵方案"""
AABB = "隔行押韵" # 行1&2押韵,行3&4押韵
ABAB = "交叉押韵" # 行1&3押韵,行2&4押韵
ABBA = "环绕押韵" # 行1&4押韵,行2&3押韵
FREE = "自由押韵" # 无固定规则
MULTI = "多押" # 嘻哈风格的多重押韵
@dataclass
class SongTheme:
"""歌曲主题"""
name: str
keywords: List[str]
common_metaphors: List[str]
emotional_range: List[str]
typical_structure: SongStructure
class LyricEngineer:
"""歌词工程师"""
def __init__(self):
# 初始化主题库
self.themes = self._initialize_themes()
# 押韵词典(简化的中文押韵)
self.rhyme_dict = {
"a": ["啊", "吧", "啦", "吗", "呀", "哈"], # a韵
"o": ["哦", "我", "多", "火", "果", "落"], # o韵
"e": ["的", "了", "呢", "么", "着", "这"], # e韵
"i": ["你", "里", "起", "意", "气", "喜"], # i韵
"u": ["路", "处", "度", "木", "诉", "悟"], # u韵
"ai": ["爱", "来", "在", "开", "海", "带"], # ai韵
"ei": ["美", "飞", "倍", "泪", "谁", "为"], # ei韵
"ao": ["到", "好", "道", "老", "早", "宝"], # ao韵
"ou": ["有", "后", "手", "头", "走", "口"], # ou韵
"an": ["看", "难", "然", "安", "淡", "感"], # an韵
"en": ["人", "真", "深", "分", "门", "文"], # en韵
"ang": ["上", "望", "长", "伤", "光", "堂"], # ang韵
"eng": ["风", "声", "生", "梦", "等", "情"] # eng韵
}
# 常用词汇库
self.vocabulary = {
"自然": ["阳光", "月光", "星空", "海洋", "山川", "森林", "花朵", "雨滴", "微风", "云朵"],
"情感": ["心跳", "思念", "微笑", "泪水", "拥抱", "牵手", "回忆", "梦想", "希望", "勇气"],
"时间": ["永远", "瞬间", "明天", "昨天", "时光", "岁月", "青春", "未来", "过去", "现在"],
"空间": ["远方", "身旁", "心中", "世界", "角落", "天空", "大地", "旅途", "路口", "彼岸"]
}
def _initialize_themes(self) -> Dict[str, SongTheme]:
"""初始化主题库"""
return {
"爱情": SongTheme(
name="爱情",
keywords=["相遇", "相爱", "分离", "重逢", "誓言", "永恒"],
common_metaphors=["星辰大海", "春暖花开", "雨中漫步", "心跳交响"],
emotional_range=["甜蜜", "思念", "痛苦", "幸福", "期待"],
typical_structure=SongStructure.POP_STANDARD
),
"梦想": SongTheme(
name="梦想",
keywords=["追求", "坚持", "努力", "成功", "挫折", "成长"],
common_metaphors=["破茧成蝶", "星辰大海", "乘风破浪", "曙光初现"],
emotional_range=["激情", "希望", "挫折", "坚持", "成就"],
typical_structure=SongStructure.ROCK
),
"友情": SongTheme(
name="友情",
keywords=["陪伴", "支持", "成长", "回忆", "信任", "时光"],
common_metaphors=["并肩同行", "青春纪念", "岁月如歌", "风雨同舟"],
emotional_range=["温暖", "怀念", "感激", "快乐", "不舍"],
typical_structure=SongStructure.BALLAD
),
"自然": SongTheme(
name="自然",
keywords=["四季", "风景", "生命", "宁静", "和谐", "美丽"],
common_metaphors=["大地之歌", "风的低语", "水的流动", "山的呼吸"],
emotional_range=["平静", "感动", "敬畏", "喜悦", "沉思"],
typical_structure=SongStructure.BALLAD
),
"城市": SongTheme(
name="城市",
keywords=["霓虹", "人群", "孤独", "梦想", "奋斗", "夜晚"],
common_metaphors=["钢铁森林", "光影交错", "城市脉搏", "喧嚣中的寂静"],
emotional_range=["孤独", "希望", "疲惫", "激情", "迷茫"],
typical_structure=SongStructure.EDM
)
}
def generate_structured_lyrics(self, theme_name: str,
structure: SongStructure = None,
rhyme_scheme: RhymeScheme = RhymeScheme.AABB,
line_length: int = 8) -> Dict:
"""生成结构化歌词"""
theme = self.themes.get(theme_name)
if not theme:
theme = self.themes["爱情"] # 默认主题
if not structure:
structure = theme.typical_structure
print(f"🎵 生成 {theme_name} 主题歌词")
print(f"📐 结构: {structure.value}")
print(f"🎶 押韵: {rhyme_scheme.value}")
# 根据结构生成各部分
lyrics_structure = self._get_structure_template(structure)
lyrics = {}
total_lines = 0
for section_name in lyrics_structure:
section_lines = lyrics_structure[section_name]
# 生成该部分的歌词
section_lyrics = self._generate_section(
theme=theme,
section_name=section_name,
num_lines=section_lines,
rhyme_scheme=rhyme_scheme,
line_length=line_length
)
lyrics[section_name] = section_lyrics
total_lines += len(section_lyrics)
# 构建完整歌词文本
full_lyrics = self._assemble_full_lyrics(lyrics, structure)
return {
"theme": theme_name,
"structure": structure.value,
"rhyme_scheme": rhyme_scheme.value,
"total_lines": total_lines,
"sections": lyrics,
"full_lyrics": full_lyrics,
"analysis": self._analyze_lyrics(lyrics, theme)
}
def _get_structure_template(self, structure: SongStructure) -> Dict[str, int]:
"""获取结构模板"""
templates = {
SongStructure.POP_STANDARD: {
"主歌A": 4,
"副歌": 4,
"主歌B": 4,
"副歌": 4,
"桥段": 4,
"副歌": 4
},
SongStructure.BALLAD: {
"主歌A": 4,
"主歌B": 4,
"副歌": 4,
"主歌C": 4,
"副歌": 4
},
SongStructure.ROCK: {
"主歌": 4,
"副歌": 4,
"吉他独奏": 4,
"主歌": 4,
"副歌": 4
},
SongStructure.HIPHOP: {
"Intro": 2,
"Verse 1": 8,
"Hook": 4,
"Verse 2": 8,
"Hook": 4,
"Outro": 2
},
SongStructure.EDM: {
"Intro": 2,
"Buildup": 4,
"Drop": 4,
"Bridge": 4,
"Drop": 4,
"Outro": 2
}
}
return templates.get(structure, templates[SongStructure.POP_STANDARD])
def _generate_section(self, theme: SongTheme, section_name: str,
num_lines: int, rhyme_scheme: RhymeScheme,
line_length: int) -> List[str]:
"""生成一个部分的歌词"""
lines = []
# 根据部分类型选择词汇
if "主歌" in section_name or "Verse" in section_name:
vocab_categories = ["自然", "情感", "时间"]
elif "副歌" in section_name or "Hook" in section_name:
vocab_categories = ["情感", "时间"]
elif "桥段" in section_name or "Bridge" in section_name:
vocab_categories = ["空间", "情感"]
else:
vocab_categories = list(self.vocabulary.keys())
# 生成每行歌词
for i in range(num_lines):
line = self._generate_line(
theme=theme,
vocab_categories=vocab_categories,
line_length=line_length,
line_number=i,
total_lines=num_lines
)
lines.append(line)
# 应用押韵
if rhyme_scheme != RhymeScheme.FREE:
lines = self._apply_rhyme_scheme(lines, rhyme_scheme)
return lines
def _generate_line(self, theme: SongTheme, vocab_categories: List[str],
line_length: int, line_number: int,
total_lines: int) -> str:
"""生成单行歌词"""
# 选择词汇类别
category = random.choice(vocab_categories)
base_words = random.sample(self.vocabulary[category], 2)
# 添加主题关键词
if random.random() > 0.5:
keyword = random.choice(theme.keywords)
base_words.append(keyword)
# 添加比喻(在副歌部分更多使用)
is_chorus = line_number >= total_lines * 0.3 # 假设30%后是副歌
if is_chorus and random.random() > 0.7:
metaphor = random.choice(theme.common_metaphors)
base_words.append(metaphor)
# 构建句子
sentence_structures = [
f"{base_words[0]}的{base_words[1]}",
f"{base_words[0]}{base_words[1]}",
f"{base_words[1]}中{base_words[0]}",
f"{base_words[0]}{base_words[2]}的{base_words[1]}"
]
line = random.choice(sentence_structures)
# 确保长度合适
while len(line) < line_length - 2:
extra_word = random.choice(list(self.vocabulary.values())[0])
line += extra_word
# 截断到合适长度
if len(line) > line_length:
line = line[:line_length]
return line
def _apply_rhyme_scheme(self, lines: List[str],
rhyme_scheme: RhymeScheme) -> List[str]:
"""应用押韵方案"""
if rhyme_scheme == RhymeScheme.AABB:
# 每两行押韵
for i in range(0, len(lines), 2):
if i + 1 < len(lines):
lines[i+1] = self._make_rhyme(lines[i], lines[i+1])
elif rhyme_scheme == RhymeScheme.ABAB:
# 交叉押韵
for i in range(0, len(lines), 2):
if i + 2 < len(lines):
lines[i+2] = self._make_rhyme(lines[i], lines[i+2])
return lines
def _make_rhyme(self, line1: str, line2: str) -> str:
"""使两行押韵"""
# 提取最后1-2个字
last_word1 = line1[-1] if len(line1) >= 1 else line1[-2:]
# 寻找押韵的字
for rhyme_group, words in self.rhyme_dict.items():
if any(word in last_word1 for word in words[:3]):
# 用同韵的字替换line2的最后一个字
rhyming_word = random.choice(words)
if len(line2) >= 1:
line2 = line2[:-1] + rhyming_word
break
return line2
def _assemble_full_lyrics(self, sections: Dict[str, List[str]],
structure: SongStructure) -> str:
"""组装完整歌词文本"""
full_text = ""
for section_name, lines in sections.items():
full_text += f"[{section_name}]\n"
for line in lines:
full_text += line + "\n"
full_text += "\n"
return full_text.strip()
def _analyze_lyrics(self, lyrics: Dict[str, List[str]],
theme: SongTheme) -> Dict:
"""分析歌词质量"""
total_words = 0
unique_words = set()
emotion_words = 0
for section_lines in lyrics.values():
for line in section_lines:
words = line.strip().split()
total_words += len(words)
unique_words.update(words)
# 统计情感词汇
for word in words:
if word in theme.keywords or any(
emotion in word for emotion in theme.emotional_range
):
emotion_words += 1
# 计算指标
uniqueness_ratio = len(unique_words) / total_words if total_words > 0 else 0
emotion_density = emotion_words / total_words if total_words > 0 else 0
return {
"total_words": total_words,
"unique_words": len(unique_words),
"uniqueness_ratio": f"{uniqueness_ratio:.1%}",
"emotion_density": f"{emotion_density:.1%}",
"section_count": len(lyrics),
"average_lines_per_section": sum(len(l) for l in lyrics.values()) / len(lyrics)
}
def generate_song_idea(self, genre: str = "流行",
mood: str = "快乐") -> Dict:
"""生成完整的歌曲创意"""
# 随机选择主题
theme_name = random.choice(list(self.themes.keys()))
theme = self.themes[theme_name]
# 选择结构
if genre == "流行":
structure = SongStructure.POP_STANDARD
rhyme = RhymeScheme.AABB
elif genre == "民谣":
structure = SongStructure.BALLAD
rhyme = RhymeScheme.ABAB
elif genre == "摇滚":
structure = SongStructure.ROCK
rhyme = RhymeScheme.FREE
elif genre == "嘻哈":
structure = SongStructure.HIPHOP
rhyme = RhymeScheme.MULTI
else:
structure = theme.typical_structure
rhyme = RhymeScheme.AABB
# 生成歌词
lyrics_data = self.generate_structured_lyrics(
theme_name=theme_name,
structure=structure,
rhyme_scheme=rhyme,
line_length=random.randint(6, 10)
)
# 生成标题
title = self._generate_title(theme, mood)
# 生成提示词
prompt = self._generate_suno_prompt(title, lyrics_data, genre, mood)
return {
"title": title,
"theme": theme_name,
"genre": genre,
"mood": mood,
"structure": structure.value,
"rhyme_scheme": rhyme.value,
"lyrics": lyrics_data["full_lyrics"],
"lyrics_analysis": lyrics_data["analysis"],
"suno_prompt": prompt,
"recommended_instruments": self._get_recommended_instruments(genre),
"recommended_tempo": self._get_recommended_tempo(mood, genre)
}
def _generate_title(self, theme: SongTheme, mood: str) -> str:
"""生成歌曲标题"""
# 组合词汇生成标题
vocab_sets = [
self.vocabulary["自然"],
self.vocabulary["情感"],
self.vocabulary["时间"]
]
word1 = random.choice(random.choice(vocab_sets))
word2 = random.choice(theme.keywords)
# 标题模板
templates = [
f"{word1}的{word2}",
f"{word2}{word1}",
f"{word1}{word2}",
f"{mood}{word1}",
f"{word2}之{word1}"
]
return random.choice(templates)
def _generate_suno_prompt(self, title: str, lyrics_data: Dict,
genre: str, mood: str) -> str:
"""生成Suno提示词"""
prompt = f"创作一首歌曲,标题:{title}\n\n"
prompt += f"风格:{genre},情绪:{mood}\n\n"
prompt += "歌词:\n"
prompt += lyrics_data["full_lyrics"] + "\n\n"
prompt += "要求:\n"
prompt += "1. 旋律优美,容易记忆\n"
prompt += "2. 节奏与情绪相匹配\n"
prompt += "3. 乐器编排丰富但不过度\n"
prompt += "4. 人声清晰,情感表达充分\n"
if genre == "流行":
prompt += "5. 副歌部分要朗朗上口,适合传唱\n"
elif genre == "民谣":
prompt += "5. 突出吉他或钢琴伴奏,质朴自然\n"
elif genre == "电子":
prompt += "5. 使用合成器音色,节奏感强\n"
return prompt
def _get_recommended_instruments(self, genre: str) -> List[str]:
"""获取推荐乐器"""
instrument_map = {
"流行": ["钢琴", "吉他", "鼓组", "贝斯", "弦乐"],
"摇滚": ["电吉他", "贝斯", "鼓组", "键盘"],
"民谣": ["吉他", "钢琴", "口琴", "小提琴"],
"电子": ["合成器", "鼓机", "贝斯", "电子音效"],
"R&B": ["钢琴", "贝斯", "鼓", "弦乐", "和声"],
"爵士": ["萨克斯", "钢琴", "贝斯", "鼓", "小号"],
"国风": ["二胡", "古筝", "笛子", "琵琶", "钢琴"]
}
return instrument_map.get(genre, instrument_map["流行"])
def _get_recommended_tempo(self, mood: str, genre: str) -> str:
"""获取推荐速度"""
# BPM范围
tempo_map = {
"快乐": {"流行": "120-140 BPM", "摇滚": "140-160 BPM", "电子": "128-150 BPM"},
"悲伤": {"流行": "60-80 BPM", "民谣": "70-90 BPM", "R&B": "70-85 BPM"},
"浪漫": {"流行": "90-110 BPM", "爵士": "100-120 BPM", "R&B": "85-105 BPM"},
"励志": {"流行": "120-140 BPM", "摇滚": "140-160 BPM", "电子": "128-150 BPM"},
"放松": {"民谣": "70-90 BPM", "爵士": "80-100 BPM", "古典": "60-80 BPM"}
}
mood_tempos = tempo_map.get(mood, tempo_map["快乐"])
return mood_tempos.get(genre, "100-120 BPM")
# 使用示例
if __name__ == "__main__":
engineer = LyricEngineer()
# 示例1: 生成结构化歌词
print("示例1: 生成结构化歌词")
lyrics_data = engineer.generate_structured_lyrics(
theme_name="爱情",
structure=SongStructure.POP_STANDARD,
rhyme_scheme=RhymeScheme.AABB,
line_length=8
)
print(f"\n歌曲主题: {lyrics_data['theme']}")
print(f"歌曲结构: {lyrics_data['structure']}")
print(f"押韵方案: {lyrics_data['rhyme_scheme']}")
print(f"总行数: {lyrics_data['total_lines']}")
print("\n完整歌词:")
print(lyrics_data['full_lyrics'])
print("\n歌词分析:")
for key, value in lyrics_data['analysis'].items():
print(f"{key}: {value}")
# 示例2: 生成完整歌曲创意
print("\n" + "="*60)
print("示例2: 生成完整歌曲创意")
song_idea = engineer.generate_song_idea(
genre="流行",
mood="浪漫"
)
print(f"\n🎵 歌曲标题: {song_idea['title']}")
print(f"🎭 主题: {song_idea['theme']}")
print(f"🎸 风格: {song_idea['genre']}")
print(f"😊 情绪: {song_idea['mood']}")
print(f"📐 结构: {song_idea['structure']}")
print(f"\n🎼 推荐乐器: {', '.join(song_idea['recommended_instruments'])}")
print(f"🎚️ 推荐速度: {song_idea['recommended_tempo']}")
print(f"\n📝 Suno提示词(前200字符):")
print(song_idea['suno_prompt'][:200] + "...")
3.2 高级提示词工程
"""
Suno高级提示词工程系统
生成专业级音乐创作提示词
"""
import re
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
import json
class MusicGenre(Enum):
"""音乐流派详细分类"""
POP = "流行音乐"
ROCK = "摇滚乐"
HIPHOP = "嘻哈音乐"
EDM = "电子舞曲"
JAZZ = "爵士乐"
CLASSICAL = "古典音乐"
COUNTRY = "乡村音乐"
RNB = "节奏布鲁斯"
REGGAE = "雷鬼音乐"
METAL = "金属音乐"
INDIE = "独立音乐"
K_POP = "韩流音乐"
C_POP = "华语流行"
J_POP = "日本流行"
LOFI = "低保真"
AMBIENT = "氛围音乐"
SYNTHWAVE = "合成器浪潮"
FUNK = "放克音乐"
SOUL = "灵魂乐"
BLUES = "布鲁斯"
class InstrumentFamily(Enum):
"""乐器家族"""
STRINGS = "弦乐器"
WOODWINDS = "木管乐器"
BRASS = "铜管乐器"
PERCUSSION = "打击乐器"
KEYBOARD = "键盘乐器"
ELECTRONIC = "电子乐器"
VOCAL = "人声"
ETHNIC = "民族乐器"
class ProductionStyle(Enum):
"""制作风格"""
LIVE = "现场录制"
STUDIO = "录音室"
DIY = "独立制作"
ORCHESTRAL = "管弦乐"
MINIMAL = "极简主义"
LAYERED = "分层丰富"
SPACIOUS = "空间感强"
INTIMATE = "亲密感"
EPIC = "史诗感"
@dataclass
class AdvancedPrompt:
"""高级提示词"""
core_concept: str
genre: MusicGenre
mood: str
tempo: str
instruments: List[str]
production_style: ProductionStyle
lyrical_themes: List[str]
structure_hints: str
sound_qualities: List[str]
reference_artists: List[str]
def to_suno_prompt(self) -> str:
"""转换为Suno提示词"""
prompt = f"创作一首{self.genre.value},主题是:{self.core_concept}\n\n"
prompt += "【音乐风格与情绪】\n"
prompt += f"- 风格:{self.genre.value}\n"
prompt += f"- 情绪:{self.mood}\n"
prompt += f"- 速度:{self.tempo}\n"
prompt += f"- 制作风格:{self.production_style.value}\n\n"
prompt += "【乐器与音色】\n"
prompt += f"- 主要乐器:{', '.join(self.instruments)}\n"
prompt += f"- 声音特质:{', '.join(self.sound_qualities)}\n\n"
prompt += "【歌词主题】\n"
prompt += f"- 主题元素:{', '.join(self.lyrical_themes)}\n\n"
prompt += "【结构提示】\n"
prompt += f"{self.structure_hints}\n\n"
prompt += "【参考艺术家】\n"
prompt += f"参考以下艺术家的风格元素:{', '.join(self.reference_artists)}\n\n"
prompt += "【具体要求】\n"
prompt += "1. 旋律要令人难忘且情感丰富\n"
prompt += "2. 编曲层次分明,有动态变化\n"
prompt += "3. 人声表现自然,情感真挚\n"
prompt += "4. 整体制作精良,适合反复聆听\n"
return prompt
class AdvancedPromptEngineer:
"""高级提示词工程师"""
def __init__(self):
self.genre_knowledge = self._init_genre_knowledge()
self.mood_palette = self._init_mood_palette()
self.instrument_library = self._init_instrument_library()
def _init_genre_knowledge(self) -> Dict[MusicGenre, Dict]:
"""初始化流派知识库"""
return {
MusicGenre.POP: {
"tempo_range": "100-130 BPM",
"common_instruments": ["钢琴", "吉他", "鼓", "贝斯", "合成器"],
"structure": "主歌-预副歌-副歌-主歌-副歌-桥段-副歌",
"characteristics": ["朗朗上口的旋律", "明确的节拍", "重复的副歌"],
"reference_artists": ["Taylor Swift", "Ed Sheeran", "Ariana Grande"]
},
MusicGenre.LOFI: {
"tempo_range": "70-90 BPM",
"common_instruments": ["钢琴", "黑胶采样", "低保真鼓", "环境音效"],
"structure": "循环结构,渐进变化",
"characteristics": ["温暖的质感", "轻微的失真", "放松的节奏"],
"reference_artists": ["Jinsang", "Tomppabeats", " idealism"]
},
MusicGenre.SYNTHWAVE: {
"tempo_range": "100-120 BPM",
"common_instruments": ["模拟合成器", "鼓机", "贝斯", "人声和声"],
"structure": "主旋律重复,氛围渐进",
"characteristics": ["复古未来感", "丰富的和声", "强烈的节奏"],
"reference_artists": ["The Midnight", "FM-84", "Timecop1983"]
},
MusicGenre.C_POP: {
"tempo_range": "80-120 BPM",
"common_instruments": ["钢琴", "弦乐", "传统乐器", "电子元素"],
"structure": "主歌-副歌-主歌-副歌-桥段-副歌",
"characteristics": ["旋律优美", "情感丰富", "歌词诗意"],
"reference_artists": ["周杰伦", "林俊杰", "邓紫棋"]
}
}
def _init_mood_palette(self) -> Dict[str, Dict]:
"""初始化情绪调色板"""
return {
"怀旧": {
"description": "对过去的温柔回忆",
"musical_traits": ["缓慢的节奏", "温暖的音色", "简单的旋律"],
"lyrical_themes": ["童年记忆", "旧时光", "逝去的爱情"],
"sound_qualities": ["温暖", "朦胧", "柔和"]
},
"未来感": {
"description": "对未来的科技幻想",
"musical_traits": ["电子音色", "重复的节奏", "空间感"],
"lyrical_themes": ["科技进步", "宇宙探索", "数字生活"],
"sound_qualities": ["冰冷", "清晰", "广阔"]
},
"都市夜晚": {
"description": "城市夜晚的孤独与美丽",
"musical_traits": ["慢节奏", "氛围感", "轻微爵士影响"],
"lyrical_themes": ["霓虹灯光", "雨夜漫步", "城市孤独"],
"sound_qualities": ["湿润", "迷离", "深夜感"]
},
"自然治愈": {
"description": "大自然带来的平静与治愈",
"musical_traits": ["自然采样", "简单旋律", "环境音效"],
"lyrical_themes": ["森林漫步", "海边日落", "四季变化"],
"sound_qualities": ["清新", "自然", "平静"]
}
}
def _init_instrument_library(self) -> Dict[InstrumentFamily, List[str]]:
"""初始化乐器库"""
return {
InstrumentFamily.STRINGS: [
"小提琴", "大提琴", "中提琴", "低音提琴",
"吉他", "电吉他", "贝斯", "尤克里里",
"竖琴", "古筝", "二胡", "琵琶"
],
InstrumentFamily.KEYBOARD: [
"钢琴", "电钢琴", "合成器", "风琴",
"键盘", "电子琴", "钟琴", "钢片琴"
],
InstrumentFamily.PERCUSSION: [
"鼓组", "架子鼓", "手鼓", "康加鼓",
"铃鼓", "三角铁", "木鱼", "沙锤",
"电子鼓", "打击板"
],
InstrumentFamily.ELECTRONIC: [
"合成器贝斯", "电子音效", "氛围采样",
"节拍器", "效果器", "声码器"
],
InstrumentFamily.VOCAL: [
"主唱", "和声", "合唱", "人声采样",
"说唱", "吟唱", "口语"
]
}
def create_custom_prompt(self, concept: str, genre: MusicGenre = MusicGenre.POP,
mood: str = "怀旧", complexity: str = "中等") -> AdvancedPrompt:
"""创建自定义提示词"""
print(f"🎨 为 '{concept}' 创建高级提示词")
print(f"🎸 流派: {genre.value}")
print(f"😊 情绪: {mood}")
print(f"⚙️ 复杂度: {complexity}")
genre_info = self.genre_knowledge.get(genre, self.genre_knowledge[MusicGenre.POP])
mood_info = self.mood_palette.get(mood, self.mood_palette["怀旧"])
instruments = self._select_instruments(genre, mood, complexity)
structure_hints = self._generate_structure_hints(genre, complexity)
production_style = self._select_production_style(genre, mood)
prompt = AdvancedPrompt(
core_concept=concept,
genre=genre,
mood=mood,
tempo=genre_info["tempo_range"],
instruments=instruments,
production_style=production_style,
lyrical_themes=mood_info["lyrical_themes"],
structure_hints=structure_hints,
sound_qualities=mood_info["sound_qualities"],
reference_artists=genre_info["reference_artists"]
)
return prompt
def _select_instruments(self, genre: MusicGenre, mood: str,
complexity: str) -> List[str]:
"""选择乐器组合"""
base_instruments = []
genre_info = self.genre_knowledge.get(genre)
if genre_info and "common_instruments" in genre_info:
base_instruments = genre_info["common_instruments"][:3]
if mood in ["怀旧", "自然治愈"]:
base_instruments.extend(["原声吉他", "钢琴", "环境采样"])
if mood in ["未来感", "都市夜晚"]:
base_instruments.extend(["合成器", "鼓机", "电子音效"])
if complexity == "简单":
return base_instruments[:3]
elif complexity == "中等":
return base_instruments[:5]
else:
extra_instruments = []
if genre == MusicGenre.C_POP:
extra_instruments.extend(["二胡", "古筝", "笛子"])
elif genre == MusicGenre.SYNTHWAVE:
extra_instruments.extend(["模拟合成器", "人声和声", "贝斯"])
return base_instruments + extra_instruments[:2]
def _generate_structure_hints(self, genre: MusicGenre, complexity: str) -> str:
"""生成结构提示"""
genre_info = self.genre_knowledge.get(genre)
if not genre_info:
return "标准流行歌曲结构:主歌-副歌-主歌-副歌-桥段-副歌"
base_structure = genre_info.get("structure", "标准结构")
if complexity == "简单":
return f"简单结构:{base_structure},保持简洁"
elif complexity == "中等":
return f"中等复杂度结构:{base_structure},加入前奏和间奏"
else:
return f"复杂结构:{base_structure},加入多个桥段变化、器乐独奏和动态起伏"
def _select_production_style(self, genre: MusicGenre, mood: str) -> ProductionStyle:
"""选择制作风格"""
if genre in [MusicGenre.CLASSICAL, MusicGenre.JAZZ]:
return ProductionStyle.LIVE
if genre in [MusicGenre.LOFI, MusicGenre.INDIE]:
return ProductionStyle.DIY
if mood in ["史诗感", "未来感"]:
return ProductionStyle.EPIC
if mood in ["亲密感", "怀旧"]:
return ProductionStyle.INTIMATE
return ProductionStyle.STUDIO
def analyze_and_improve_prompt(self, user_prompt: str) -> Dict:
"""分析并改进用户提示词"""
analysis = {
"original": user_prompt,
"length": len(user_prompt),
"word_count": len(user_prompt.split()),
"issues": [],
"suggestions": [],
"improved_prompt": ""
}
if len(user_prompt) < 20:
analysis["issues"].append("提示词过短,信息不足")
analysis["suggestions"].append("添加更多关于风格、情绪、乐器的描述")
if len(user_prompt) > 500:
analysis["issues"].append("提示词过长,可能混淆AI")
analysis["suggestions"].append("精简到300字以内,突出重点")
has_genre = any(genre.value in user_prompt for genre in MusicGenre)
has_mood = any(mood in user_prompt for mood in self.mood_palette.keys())
has_instruments = any(
instrument in user_prompt
for instruments in self.instrument_library.values()
for instrument in instruments
)
if not has_genre:
analysis["issues"].append("未指定音乐流派")
analysis["suggestions"].append("明确指定流派,如'流行音乐'、'电子音乐'")
if not has_mood:
analysis["issues"].append("未指定情绪氛围")
analysis["suggestions"].append("添加情绪描述,如'怀旧的'、'欢快的'")
if not has_instruments:
analysis["issues"].append("未指定乐器")
analysis["suggestions"].append("指定1-3种主要乐器")
improved = self._improve_prompt(user_prompt, analysis["issues"])
analysis["improved_prompt"] = improved
return analysis
def _improve_prompt(self, original: str, issues: List[str]) -> str:
"""改进提示词"""
improved = original
if "提示词过短" in issues:
improved += "\n\n【补充说明】\n"
improved += "风格:流行音乐\n"
improved += "情绪:温暖怀旧\n"
improved += "乐器:钢琴、吉他、弦乐\n"
improved += "结构:主歌-副歌-主歌-副歌-桥段-副歌\n"
if "未指定音乐流派" in issues and "流行音乐" not in improved:
improved = "创作一首流行音乐," + improved
if "未指定情绪氛围" in issues and "情绪" not in improved:
improved += " 请以温暖怀旧的情绪创作。"
if "未指定乐器" in issues and "乐器" not in improved:
improved += " 主要使用钢琴和吉他。"
if "结构" not in improved:
improved += " 歌曲结构采用标准的流行歌曲结构。"
return improved
def generate_prompt_variations(self, base_prompt: str,
num_variations: int = 3) -> List[str]:
"""生成提示词变体"""
variations = []
variation_strategies = [
self._vary_genre,
self._vary_mood,
self._vary_instruments,
self._vary_production
]
for i in range(num_variations):
strategy = variation_strategies[i % len(variation_strategies)]
variation = strategy(base_prompt)
variations.append(variation)
return variations
def _vary_genre(self, prompt: str) -> str:
"""变化流派"""
genres_to_try = [MusicGenre.LOFI, MusicGenre.SYNTHWAVE, MusicGenre.C_POP]
for genre in genres_to_try:
if genre.value not in prompt:
for existing_genre in MusicGenre:
if existing_genre.value in prompt:
return prompt.replace(existing_genre.value, genre.value)
return f"创作一首{genre.value}," + prompt
return prompt
def _vary_mood(self, prompt: str) -> str:
"""变化情绪"""
moods_to_try = ["未来感", "都市夜晚", "自然治愈"]
for mood in moods_to_try:
if mood not in prompt:
for existing_mood in self.mood_palette.keys():
if existing_mood in prompt:
return prompt.replace(existing_mood, mood)
return prompt + f" 请以{mood}的情绪创作。"
return prompt
def _vary_instruments(self, prompt: str) -> str:
"""变化乐器"""
instrument_groups = [
["合成器", "鼓机", "电子贝斯"],
["二胡", "古筝", "笛子"],
["原声吉他", "口琴", "手鼓"]
]
for group in instrument_groups:
has_any = any(instrument in prompt for instrument in group)
if not has_any:
return prompt + f" 主要使用{group[0]}和{group[1]}。"
return prompt
def _vary_production(self, prompt: str) -> str:
"""变化制作风格"""
production_styles = [
"低保真DIY制作风格",
"录音室精良制作",
"现场演出感觉"
]
for style in production_styles:
if style not in prompt:
return prompt + f" 采用{style}。"
return prompt
if __name__ == "__main__":
engineer = AdvancedPromptEngineer()
print("示例1: 创建高级提示词")
custom_prompt = engineer.create_custom_prompt(
concept="雨夜中的城市漫步",
genre=MusicGenre.LOFI,
mood="都市夜晚",
complexity="中等"
)
print(f"\n🎨 核心概念: {custom_prompt.core_concept}")
print(f"🎸 流派: {custom_prompt.genre.value}")
print(f"😊 情绪: {custom_prompt.mood}")
print(f"🎚️ 速度: {custom_prompt.tempo}")
print(f"🎹 乐器: {', '.join(custom_prompt