mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-11-12 20:23:46 +08:00
suno add new function for merging full songs and upload custom music
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
|
||||
<div class="params">
|
||||
<div class="item-group">
|
||||
<span class="label">循环</span>
|
||||
<span class="label">循环参考图</span>
|
||||
<el-switch v-model="loop" size="small" style="--el-switch-on-color:#BF78BF;" />
|
||||
</div>
|
||||
<div class="item-group">
|
||||
|
||||
@@ -211,6 +211,11 @@ const licenseConfig = ref({})
|
||||
const enableVerify = ref(false)
|
||||
const captchaRef = ref(null)
|
||||
|
||||
// 记录邀请码点击次数
|
||||
if (data.value.invite_code) {
|
||||
httpGet("/api/invite/hits",{code: data.value.invite_code})
|
||||
}
|
||||
|
||||
getSystemInfo().then(res => {
|
||||
if (res.data) {
|
||||
title.value = res.data.title
|
||||
|
||||
@@ -5,6 +5,20 @@
|
||||
<el-tooltip effect="light" content="定义模式" placement="top">
|
||||
<black-switch v-model:value="custom" size="large" />
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="light" content="请上传6-60秒的原始音频,检测到人声的音频将仅设为私人音频。" placement="bottom-end">
|
||||
<el-upload
|
||||
class="avatar-uploader"
|
||||
:auto-upload="true"
|
||||
:show-file-list="false"
|
||||
:http-request="uploadAudio"
|
||||
accept=".wav,.mp3"
|
||||
>
|
||||
<el-button class="upload-music" color="#363030" round>
|
||||
<i class="iconfont icon-upload"></i>
|
||||
<span>上传音乐</span>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
</el-tooltip>
|
||||
<black-select v-model:value="data.model" :options="models" placeholder="请选择模型" style="width: 100px" />
|
||||
</div>
|
||||
|
||||
@@ -28,10 +42,10 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="item"
|
||||
v-loading="generating"
|
||||
v-loading="isGenerating"
|
||||
element-loading-text="正在生成歌词..."
|
||||
element-loading-background="rgba(122, 122, 122, 0.8)">
|
||||
<black-input v-model:value="data.lyrics" type="textarea" :rows="10" placeholder="请在这里输入你自己写的歌词..."/>
|
||||
<black-input v-model:value="data.lyrics" type="textarea" :rows="10" :placeholder="promptPlaceholder"/>
|
||||
<button class="btn btn-lyric" @click="createLyric">生成歌词</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,7 +151,7 @@
|
||||
</div>
|
||||
<div class="right-box" v-loading="loading" element-loading-background="rgba(100,100,100,0.3)">
|
||||
<div class="list-box" v-if="!noData">
|
||||
<div v-for="item in list">
|
||||
<div v-for="item in list" :key="item.id">
|
||||
<div class="item" v-if="item.progress === 100">
|
||||
<div class="left">
|
||||
<div class="container">
|
||||
@@ -151,13 +165,18 @@
|
||||
<div class="center">
|
||||
<div class="title">
|
||||
<a :href="'/song/'+item.song_id" target="_blank">{{item.title}}</a>
|
||||
<span class="model">{{item.major_model_version}}</span>
|
||||
<span class="model" v-if="item.major_model_version">{{item.major_model_version}}</span>
|
||||
<span class="model" v-if="item.type === 4">用户上传</span>
|
||||
<span class="model" v-if="item.type === 3">
|
||||
<i class="iconfont icon-mp3"></i>
|
||||
完整歌曲
|
||||
</span>
|
||||
<span class="model" v-if="item.ref_song">
|
||||
<i class="iconfont icon-link"></i>
|
||||
{{item.ref_song.title}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="tags">{{item.tags}}</div>
|
||||
<div class="tags" v-if="item.tags">{{item.tags}}</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="tools">
|
||||
@@ -178,6 +197,12 @@
|
||||
</a>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip effect="light" content="获取完整歌曲" placement="top" v-if="item.ref_song">
|
||||
<button class="btn btn-icon" @click="merge(item)">
|
||||
<i class="iconfont icon-concat"></i>
|
||||
</button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip effect="light" content="复制歌曲链接" placement="top">
|
||||
<button class="btn btn-icon copy-link" :data-clipboard-text="getShareURL(item)" >
|
||||
<i class="iconfont icon-share1"></i>
|
||||
@@ -276,13 +301,13 @@ import MusicPlayer from "@/components/MusicPlayer.vue";
|
||||
import {compact} from "lodash";
|
||||
import {httpGet, httpPost} from "@/utils/http";
|
||||
import {showMessageError, showMessageOK} from "@/utils/dialog";
|
||||
import Generating from "@/components/ui/Generating.vue";
|
||||
import {checkSession} from "@/store/cache";
|
||||
import {ElMessage, ElMessageBox} from "element-plus";
|
||||
import {formatTime} from "@/utils/libs";
|
||||
import Clipboard from "clipboard";
|
||||
import BlackDialog from "@/components/ui/BlackDialog.vue";
|
||||
import Compressor from "compressorjs";
|
||||
import Generating from "@/components/ui/Generating.vue";
|
||||
|
||||
const winHeight = ref(window.innerHeight - 50)
|
||||
const custom = ref(false)
|
||||
@@ -329,6 +354,7 @@ const btnText = ref("开始创作")
|
||||
const refSong = ref(null)
|
||||
const showDialog = ref(false)
|
||||
const editData = ref({title:"",cover:"",id:0})
|
||||
const promptPlaceholder = ref('请在这里输入你自己写的歌词...')
|
||||
|
||||
const socket = ref(null)
|
||||
const userId = ref(0)
|
||||
@@ -422,7 +448,11 @@ const create = () => {
|
||||
data.value.ref_task_id = refSong.value ? refSong.value.task_id : ""
|
||||
data.value.ref_song_id = refSong.value ? refSong.value.song_id : ""
|
||||
data.value.extend_secs = refSong.value ? refSong.value.extend_secs : 0
|
||||
if (custom.value) {
|
||||
if (refSong.value) {
|
||||
if (data.value.extend_secs > refSong.value.duration) {
|
||||
return showMessageError("续写开始时间不能超过原歌曲长度")
|
||||
}
|
||||
} else if (custom.value) {
|
||||
if (data.value.lyrics === "") {
|
||||
return showMessageError("请输入歌词")
|
||||
}
|
||||
@@ -434,9 +464,6 @@ const create = () => {
|
||||
return showMessageError("请输入歌曲描述")
|
||||
}
|
||||
}
|
||||
if (refSong.value && data.value.extend_secs > refSong.value.duration) {
|
||||
return showMessageError("续写开始时间不能超过原歌曲长度")
|
||||
}
|
||||
|
||||
httpPost("/api/suno/create", data.value).then(() => {
|
||||
fetchData(1)
|
||||
@@ -446,6 +473,35 @@ const create = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 拼接歌曲
|
||||
const merge = (item) => {
|
||||
httpPost("/api/suno/create", {song_id: item.song_id, type:3}).then(() => {
|
||||
fetchData(1)
|
||||
showMessageOK("创建任务成功")
|
||||
}).catch(e => {
|
||||
showMessageError("合并歌曲失败:"+e.message)
|
||||
})
|
||||
}
|
||||
|
||||
const uploadAudio = (file) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file.file, file.name);
|
||||
// 执行上传操作
|
||||
httpPost('/api/upload', formData).then((res) => {
|
||||
httpPost("/api/suno/create", {audio_url: res.data.url, title:res.data.name, type:4}).then(() => {
|
||||
fetchData(1)
|
||||
showMessageOK("歌曲上传成功")
|
||||
}).catch(e => {
|
||||
showMessageError("歌曲上传失败:"+e.message)
|
||||
})
|
||||
removeRefSong()
|
||||
ElMessage.success({message: "上传成功", duration: 500})
|
||||
}).catch((e) => {
|
||||
ElMessage.error('文件传失败:' + e.message)
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
// 续写歌曲
|
||||
const extend = (item) => {
|
||||
refSong.value = item
|
||||
@@ -453,6 +509,7 @@ const extend = (item) => {
|
||||
data.value.title = item.title
|
||||
custom.value = true
|
||||
btnText.value = "续写歌曲"
|
||||
promptPlaceholder.value = "输入额外的歌词,根据您之前的歌词来扩展歌曲..."
|
||||
}
|
||||
|
||||
// 更细歌曲
|
||||
@@ -485,6 +542,7 @@ watch(() => custom.value, (newValue) => {
|
||||
const removeRefSong = () => {
|
||||
refSong.value = null
|
||||
btnText.value = "开始创作"
|
||||
promptPlaceholder.value = "请在这里输入你自己写的歌词..."
|
||||
}
|
||||
|
||||
const play = (item) => {
|
||||
@@ -553,21 +611,21 @@ const uploadCover = (file) => {
|
||||
});
|
||||
}
|
||||
|
||||
const generating = ref(false)
|
||||
const isGenerating = ref(false)
|
||||
const createLyric = () => {
|
||||
if (data.value.lyrics === "") {
|
||||
return showMessageError("请输入歌词描述")
|
||||
}
|
||||
generating.value = true
|
||||
isGenerating.value = true
|
||||
httpPost("/api/suno/lyric", {prompt: data.value.lyrics}).then(res => {
|
||||
const lines = res.data.split('\n');
|
||||
data.value.title = lines.shift().replace(/\*/g,"")
|
||||
lines.shift()
|
||||
data.value.lyrics = lines.join('\n');
|
||||
generating.value = false
|
||||
isGenerating.value = false
|
||||
}).catch(e => {
|
||||
showMessageError("歌词生成失败:"+e.message)
|
||||
generating.value = false
|
||||
isGenerating.value = false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user