优化歌曲消息匹配,适配更多模型支持生成歌曲

This commit is contained in:
zyc404 2024-05-09 22:09:51 +08:00
parent 554f6a69f3
commit 7288e2b845
6 changed files with 402 additions and 37 deletions

View file

@ -6,6 +6,285 @@ import fs from 'fs'
import crypto from 'crypto'
import fetch from 'node-fetch'
const Style = [
{ value: 'Dance', describe: '跳舞' },
{ value: 'Festive', describe: '节日' },
{ value: 'Groovy', describe: '槽的' },
{ value: 'Mid-Tempo', describe: '中速' },
{ value: 'Syncopated', describe: '切分音' },
{ value: 'Tipsy', describe: '醉' },
{ value: 'Dark', describe: '黑暗' },
{ value: 'Atmospheric', describe: '大气' },
{ value: 'Cold', describe: '冷' },
{ value: 'Dark', describe: '黑暗' },
{ value: 'Doom', describe: '厄运' },
{ value: 'Dramatic', describe: '戏剧性的' },
{ value: 'Sinister', describe: '险恶' },
{ value: 'Eclectic', describe: '折衷' },
{ value: 'Adjunct', describe: '兼职' },
{ value: 'Art', describe: '艺术' },
{ value: 'Capriccio', describe: '狂想曲' },
{ value: 'Mellifluous', describe: '美化' },
{ value: 'Nü', describe: 'Nü' },
{ value: 'Progressive', describe: '进步' },
{ value: 'Unusual', describe: '异常' },
{ value: 'Emotion', describe: '情感' },
{ value: 'Anthemic', describe: '国歌' },
{ value: 'Emotional', describe: '感情的' },
{ value: 'Happy', describe: '快乐' },
{ value: 'Jubilant', describe: '欢腾' },
{ value: 'Melancholy', describe: '忧郁' },
{ value: 'Sad', describe: 'Sad' },
{ value: 'Hard', describe: '硬' },
{ value: 'Aggressive', describe: '侵略性的' },
{ value: '积极', describe: '积极' },
{ value: 'Banger', describe: '爆竹' },
{ value: 'Power', describe: '权力' },
{ value: 'Stadium', describe: '体育场' },
{ value: 'Stomp', describe: '踩' },
{ value: 'Lyrical', describe: '抒情' },
{ value: 'Broadway', describe: '百老汇' },
{ value: 'Cabaret', describe: '酒店' },
{ value: 'Lounge', describe: '休息室' },
{ value: 'Operatic', describe: '歌剧' },
{ value: 'Storytelling', describe: '故事' },
{ value: 'Torch-Lounge', describe: '火炬酒廊' },
{ value: 'Theatrical', describe: '戏剧' },
{ value: 'Troubadour', describe: '吟游诗人' },
{ value: 'Vegas', describe: '维加斯' },
{ value: 'Magical', describe: '神奇' },
{ value: 'Ethereal', describe: '空灵' },
{ value: 'Majestic', describe: '雄伟' },
{ value: 'Mysterious', describe: '神秘' },
{ value: 'Minimal', describe: '极小' },
{ value: 'Ambient', describe: '氛围' },
{ value: 'Cinematic', describe: '电影' },
{ value: 'Heat', describe: '热' },
{ value: 'Minimal', describe: '极小' },
{ value: 'Slow', describe: '慢' },
{ value: 'Sparse', describe: '稀疏' },
{ value: 'Party', describe: '党' },
{ value: 'German Schlager', describe: '德国施拉格' },
{ value: 'Glam', describe: '格南' },
{ value: 'Glitter', describe: '闪光' },
{ value: 'Groovy', describe: '槽的' },
{ value: 'oft', describe: '软' },
{ value: 'Ambient', describe: '氛围' },
{ value: 'Bedroom', describe: '卧室' },
{ value: 'Chillwave', describe: '寒波' },
{ value: 'Ethereal', describe: '空灵' },
{ value: 'Intimate', describe: '亲密' },
{ value: 'Heat', describe: '热' },
{ value: 'Sadcore', describe: '悲伤' },
{ value: 'Weird', describe: '奇怪' },
{ value: 'Carnival', describe: '狂欢节' },
{ value: 'Distorted', describe: '扭曲' },
{ value: 'Glitchy', describe: '毛刺' },
{ value: 'Haunted', describe: '闹鬼的' },
{ value: 'Hollow', describe: '空心' },
{ value: 'Musicbox', describe: '音乐盒' },
{ value: 'Random', describe: '随机' },
{ value: 'World/Ethnic', describe: '世界/民族' },
{ value: 'Arabian', describe: '阿拉伯' },
{ value: 'Bangra', describe: '班格拉' },
{ value: 'Calypso', describe: '卡吕普索' },
{ value: 'Chalga', describe: '查尔加' },
{ value: 'Egyptian', describe: '埃及人' },
{ value: 'Hindustani', describe: '印度斯坦语' },
{ value: 'Jewish Music 犹太音乐' },
{ value: 'Klezmer 克莱兹默' },
{ value: 'Middle East', describe: '中东' },
{ value: 'Polka', describe: '波尔卡' },
{ value: 'Russian Navy Song', describe: '俄罗斯海军之歌' },
{ value: 'Suomipop', describe: 'Suomipop' },
{ value: 'Tribal', describe: '部落' }
]
const Genre = [
{ value: 'Country', describe: '乡村' },
{ value: 'Appalachian', describe: '阿巴拉契亚' },
{ value: 'Bluegrass', describe: '兰草' },
{ value: 'Country', describe: '乡村' },
{ value: 'Folk', describe: '民族' },
{ value: 'Freak Folk', describe: '怪胎民谣' },
{ value: 'Western', describe: '西方' },
{ value: 'Dance', describe: '跳舞' },
{ value: 'Afro-Cuban', describe: '非裔古巴人' },
{ value: 'Dance Pop', describe: '流行舞曲' },
{ value: 'Disco', describe: '迪斯科' },
{ value: 'Dubstep', describe: 'Dubstep的' },
{ value: 'Disco Funk', describe: '迪斯科放克' },
{ value: 'EDM', describe: 'EDM' },
{ value: 'Electro', describe: '电' },
{ value: 'High-NRG', describe: '高NRG' },
{ value: 'House', describe: '房子' },
{ value: 'Trance', describe: '恍惚' },
{ value: 'Downtempo', describe: '慢节奏' },
{ value: 'Ambient', describe: '氛围' },
{ value: 'Downtempo', describe: '慢节奏' },
{ value: 'Synthwave', describe: '合成波' },
{ value: 'Trap', describe: '陷阱' },
{ value: 'Electronic', describe: '电子的' },
{ value: 'Ambient', describe: '氛围' },
{ value: 'Cyberpunk', describe: '赛博朋克' },
{ value: 'Drum\'n\'bass Drum\'n\'bass', describe: '鼓与贝斯' },
{ value: 'Dubstep', describe: 'Dubstep的' },
{ value: 'Electronic', describe: '电子的' },
{ value: 'Hypnogogical', describe: '催眠' },
{ value: 'IDM', describe: 'IDM' },
{ value: 'Phonk', describe: '冯克' },
{ value: 'Synthpop', describe: '合成流行音乐' },
{ value: 'Techno', describe: '技术' },
{ value: 'Trap', describe: '陷阱' },
{ value: 'Jazz/Soul', describe: '爵士乐/灵魂乐' },
{ value: 'Bebop', describe: '贝波普' },
{ value: 'Gospel', describe: '福音' },
{ value: 'Electro', describe: '电' },
{ value: 'Frutiger Aero Frutiger', describe: '航空' },
{ value: 'Jazz', describe: '爵士乐' },
{ value: 'Latin Jazz', describe: '拉丁爵士乐' },
{ value: 'RnB', describe: 'RnB' },
{ value: 'Soul', describe: '灵魂' },
{ value: 'Latin', describe: '拉丁语' },
{ value: 'Bossa Nova', describe: '博萨诺瓦' },
{ value: 'Latin Jazz', describe: '拉丁爵士乐' },
{ value: 'Forró', describe: 'Forró' },
{ value: 'Mambo', describe: '曼波' },
{ value: 'Salsa', describe: '萨尔萨' },
{ value: 'Tango', describe: '探戈' },
{ value: 'Reggae', describe: '瑞格乐' },
{ value: 'Afrobeat', describe: '非洲节拍' },
{ value: 'Dancehall', describe: '舞厅' },
{ value: 'Dub', describe: 'Dub' },
{ value: 'Reggae', describe: '瑞格乐' },
{ value: 'Reggaeton', describe: '雷鬼' },
{ value: 'Metal', describe: '金属' },
{ value: 'Black Metal', describe: '黑色金属' },
{ value: 'Deathcore', describe: '死亡核心' },
{ value: 'Death Metal', describe: '死亡金属' },
{ value: 'Heavy Metal', describe: '重金属' },
{ value: 'Heavy Metal Trap', describe: '重金属捕集器' },
{ value: 'Metalcore', describe: '金属芯' },
{ value: 'Nu Metal', describe: 'Nu Metal努金属' },
{ value: 'Power Metal', describe: '动力金属' },
{ value: 'Popular', describe: '流行' },
{ value: 'Pop', describe: 'Pop' },
{ value: 'Dance Pop', describe: '流行舞曲' },
{ value: 'Pop Rock', describe: '流行摇滚' },
{ value: 'Kpop', describe: '韩流' },
{ value: 'Jpop', describe: '大通' },
{ value: 'Synthpop', describe: '合成流行音乐' },
{ value: 'Rock', describe: '摇滚' },
{ value: 'Classic Rock', describe: '经典摇滚' },
{ value: 'Blues Rock', describe: '蓝调摇滚' },
{ value: 'Emo', describe: 'Emo' },
{ value: 'Glam Rock', describe: '华丽摇滚' },
{ value: 'Hardcore Punk', describe: '硬核朋克' },
{ value: 'Indie', describe: '独立' },
{ value: 'Industrial Rock', describe: '工业摇滚' },
{ value: 'Punk', describe: '朋克' },
{ value: 'Rock', describe: '摇滚' },
{ value: 'Skate Rock', describe: '滑板摇滚' },
{ value: 'Skatecore', describe: '滑板芯' },
{ value: 'Suomipop', describe: 'Suomipop' },
{ value: 'Urban', describe: '都市的' },
{ value: 'Funk', describe: '恐惧' },
{ value: 'HipHop', describe: '嘻哈' },
{ value: 'Phonk', describe: '冯克' },
{ value: 'Rap', describe: 'Rap' },
{ value: 'Trap', describe: '陷阱' }
]
const Types = [
{ value: 'Background', describe: '背景' },
{ value: 'Elevator', describe: '电梯' },
{ value: 'Jingle', describe: '静乐县' },
{ value: 'Muzak', describe: '穆扎克' },
{ value: 'Call to Prayer', describe: '祷告的呼召' },
{ value: 'Adan', describe: '阿丹' },
{ value: 'Adjan', describe: '阿让' },
{ value: 'Call to Prayer', describe: '祷告的呼召' },
{ value: 'Gregorian Chant', describe: '格里高利圣歌' },
{ value: 'Character', describe: '字符' },
{ value: 'I Want Song', describe: '我想要歌' },
{ value: 'Hero Theme', describe: '英雄主题' },
{ value: 'Strut', describe: '支柱' },
{ value: 'March', describe: '三月' },
{ value: 'Military', describe: '军事' },
{ value: 'Villain Theme', describe: '反派主题' },
{ value: 'Children', describe: '孩子' },
{ value: 'Lullaby', describe: '催眠曲' },
{ value: 'Nursery Rhyme', describe: '童谣' },
{ value: 'Sing-along', describe: '跟唱' },
{ value: 'Toddler', describe: '幼儿' },
{ value: 'Composer', describe: '作曲家' },
{ value: 'Adagio', describe: '阿德吉奥' },
{ value: 'Adjunct', describe: '兼职' },
{ value: 'Andante', describe: '行板' },
{ value: 'Allegro', describe: '快板' },
{ value: 'Capriccio', describe: '狂想曲' },
{ value: 'Instruments', describe: '仪器' },
{ value: 'Acoustic Guitar', describe: '木吉他' },
{ value: 'Bass', describe: '低音' },
{ value: 'Doublebass', describe: '低音提琴' },
{ value: 'Electricbass', describe: '电贝司' },
{ value: 'Electric Guitar', describe: '电吉他' },
{ value: 'Fingerstyle Guitar', describe: '指弹吉他' },
{ value: 'Percussion', describe: '击发' },
{ value: 'Noise', describe: '噪声' },
{ value: 'Chaotic', describe: '混沌' },
{ value: 'Distorted', describe: '扭曲' },
{ value: 'Glitch', describe: '故障' },
{ value: 'Noise', describe: '噪声' },
{ value: 'Random', describe: '随机' },
{ value: 'Stuttering', describe: '口吃' },
{ value: 'Orchestral', describe: '管弦乐' },
{ value: 'glissando', describe: 'trombone 长号' },
{ value: 'legato cello', describe: '大提琴连奏' },
{ value: 'Orchestral', describe: '管弦乐' },
{ value: 'spiccato violins', describe: '斯皮卡托小提琴' },
{ value: 'staccato viola', describe: '断奏中提琴' },
{ value: 'Symphonic', describe: '交响' },
{ value: 'Retro', describe: '复古' },
{ value: '1960s', describe: '1960年代' },
{ value: 'Barbershop', describe: '理发店' },
{ value: 'Big Band', describe: '大乐队' },
{ value: 'Classic', describe: '经典' },
{ value: 'Doo Wop', describe: '嘟' },
{ value: 'Girl Group', describe: '女团' },
{ value: 'Mambo', describe: '曼波' },
{ value: 'Salooncore', describe: '沙龙核心' },
{ value: 'Swing', describe: '摆动' },
{ value: 'Traditional', describe: '传统的' },
{ value: 'Suffix', describe: '后缀' },
{ value: '…core', describe: '...核心' },
{ value: '…jam', describe: '...果酱' },
{ value: '…out', describe: '...外' },
{ value: '…wave', describe: '...浪' },
{ value: 'Traditional', describe: '传统的' },
{ value: 'Americana', describe: '美洲' },
{ value: 'Barbershop', describe: '理发店' },
{ value: 'Christmas Carol', describe: '圣诞颂歌' },
{ value: 'Traditional', describe: '传统的' },
{ value: 'Voice', describe: '声音' },
{ value: 'A Cappella', describe: '无伴奏合唱' },
{ value: 'Arabian Ornamental', describe: '阿拉伯观赏' },
{ value: 'Dispassionate', describe: '冷静的' },
{ value: 'Emotional', describe: '感情的' },
{ value: 'Ethereal', describe: '空灵' },
{ value: 'Gregorian chant', describe: '格里高利圣歌' },
{ value: 'Hindustani', describe: '印度斯坦语' },
{ value: 'Lounge Singer', describe: '休息室歌手' },
{ value: 'Melismatic', describe: '旋律' },
{ value: 'Monotone', describe: '单调' },
{ value: 'Narration', describe: '叙事' },
{ value: 'Resonant', describe: '谐振' },
{ value: 'Spoken Word', describe: '口语' },
{ value: 'Sprechgesang', describe: 'Sprechgesang' },
{ value: 'Sultry', describe: '闷热' },
{ value: 'Scream', describe: '尖叫' },
{ value: 'Torchy', describe: '火炬' },
{ value: 'Vocaloid', describe: '声乐' },
]
export default class BingSunoClient {
constructor(opts) {
this.opts = opts
@ -16,6 +295,7 @@ export default class BingSunoClient {
messages.push(`歌名:${song.title}\n风格: ${song.musicalStyle}\n歌词:\n${song.prompt}\n`)
messages.push(`音频链接:${song.audioURL}\n视频链接:${song.videoURL}\n封面链接:${song.imageURL}\n`)
messages.push(segment.image(song.imageURL))
await e.reply(await common.makeForwardMsg(e, messages, '音乐合成结果'))
let retry = 10
let videoPath
while (!videoPath && retry >= 0) {
@ -38,8 +318,6 @@ export default class BingSunoClient {
} else {
logger.warn(`${song.title}下载视频失败,仅发送视频链接`)
}
await e.reply(await common.makeForwardMsg(e, messages, '音乐合成结果'))
}
async getSuno(prompt, e) {
@ -170,7 +448,7 @@ export default class BingSunoClient {
})
const sunoId = await responseId.json()
if (sunoId[0]?.id) {
await e.reply('Bing Suno 生成中,请稍后')
await e.reply('Suno 生成中,请稍后')
let timeoutTimes = Config.sunoApiTimeout
let timer = setInterval(async () => {
const response = await fetch(`${Config.bingSunoApi}/api/get?ids=${sunoId[0]?.id}`, {
@ -180,7 +458,7 @@ export default class BingSunoClient {
}
})
if (!response.ok) {
await e.reply('Bing Suno 数据获取失败')
await e.reply('Suno 数据获取失败')
logger.error(response.error.message)
redis.del(`CHATGPT:SUNO:${e.sender.user_id}`)
clearInterval(timer)
@ -332,4 +610,52 @@ export default class BingSunoClient {
return result
}
extractLyrics(text) {
// 定义分段关键词
const sectionKeywords = ['Verse', 'Chorus', 'Bridge', 'Outro', 'End']
// 初始化lyrics变量
let lyrics = ''
// 标记是否开始提取歌词
let startExtracting = false
// 将文本按行分割
const lines = text.split('\n')
lines.forEach(line => {
// 检查每一行是否包含分段关键词
const sectionFound = sectionKeywords.some(keyword => {
const regex = new RegExp(`\\[${keyword} \\d+\\]|\\(${keyword} \\d+\\)`, 'i')
return regex.test(line)
})
// 如果找到第一个分段关键词,开始提取歌词
if (sectionFound && !startExtracting) {
startExtracting = true
}
// 如果已经开始提取歌词则添加到lyrics变量中
if (startExtracting) {
lyrics += line + '\n'
}
})
return lyrics.trim() // 返回处理过的歌词
}
getRandomElements(arr, count) {
const shuffled = arr.sort(() => 0.5 - Math.random())
return shuffled.slice(0, count)
}
generateRandomStyle() {
const totalItems = 5
const itemsPerArray = Math.floor(totalItems / 3)
let remainingItems = totalItems % 3
let selectedStyles = this.getRandomElements(Style, itemsPerArray)
let selectedGenres = this.getRandomElements(Genre, itemsPerArray)
let selectedTypes = this.getRandomElements(Types, itemsPerArray)
if (remainingItems > 0) selectedStyles = selectedStyles.concat(this.getRandomElements(Style, 1)), remainingItems--
if (remainingItems > 0) selectedGenres = selectedGenres.concat(this.getRandomElements(Genre, 1)), remainingItems--
const allSelected = [...selectedStyles, ...selectedGenres, ...selectedTypes]
return allSelected.map(item => item.value).join(', ')
}
}