Spaces:
Running
Running
var baseUrl = getProtocol() + getUrl(); | |
var currentModelPage = 1; | |
var vitsSpeakersCount = 0; | |
var w2v2SpeakersCount = 0; | |
var bertVits2SpeakersCount = 0; | |
var GPTSoVitsSpeakersCount = 0 | |
var selectedFile = null; | |
function speakersInit() { | |
$.ajax({ | |
url: '/voice/speakers', | |
type: 'GET', | |
dataType: 'json', | |
success: function (data) { | |
vitsSpeakersCount = data['VITS'].length; | |
w2v2SpeakersCount = data['W2V2-VITS'].length; | |
bertVits2SpeakersCount = data['BERT-VITS2'].length; | |
GPTSoVitsSpeakersCount = data['GPT-SOVITS'].length; | |
showModelContentBasedOnStatus(); | |
}, | |
error: function (xhr, status, error) { | |
console.error('Request failed with status', status, 'and error', error); | |
} | |
}); | |
} | |
$(function () { | |
$('[data-toggle="tooltip"]').tooltip() | |
}) | |
function getProtocol() { | |
return 'https:' == location.protocol ? "https://" : "http://"; | |
} | |
function getUrl() { | |
let url = window.location.host; | |
return url; | |
} | |
function setBaseUrl() { | |
let text = document.getElementById("input_text" + currentModelPage).value; | |
let id = document.getElementById("input_id" + currentModelPage).value; | |
let vits_link = document.getElementById("vits_link"); | |
let speakers_link = document.getElementById("speakers_link"); | |
let vits_url = baseUrl + "/voice/vits?text=" + text + "&id=" + id; | |
let speakers_url = baseUrl + "/voice/speakers"; | |
vits_link.href = vits_url; | |
vits_link.textContent = vits_url; | |
speakers_link.href = speakers_url; | |
speakers_link.textContent = speakers_url; | |
} | |
function getLink() { | |
let text = document.getElementById("input_text" + currentModelPage).value; | |
let id = document.getElementById("input_id" + currentModelPage).value; | |
let format = document.getElementById("input_format" + currentModelPage).value; | |
let lang = document.getElementById("input_lang" + currentModelPage).value; | |
let api_key = document.getElementById("apiKey").value; | |
let segment_size = document.getElementById("input_segment_size" + currentModelPage).value; | |
let url = baseUrl; | |
let length = null; | |
let noise = null; | |
let noisew = null; | |
let streaming = null; | |
let sdp_ratio = null; | |
let emotion = null; | |
let text_prompt = ""; | |
let style_text = ""; | |
let style_weight = ""; | |
let prompt_text = null; | |
let prompt_lang = null; | |
let preset = null; | |
let top_k = null; | |
let top_p = null; | |
let temperature = null; | |
let batch_size = null; | |
let speed = null; | |
if (currentModelPage == 1 || currentModelPage == 2 || currentModelPage == 3) { | |
length = document.getElementById("input_length" + currentModelPage).value; | |
noise = document.getElementById("input_noise" + currentModelPage).value; | |
noisew = document.getElementById("input_noisew" + currentModelPage).value; | |
} | |
if (currentModelPage == 1) { | |
streaming = document.getElementById('streaming1'); | |
url += "/voice/vits?id=" + id; | |
} else if (currentModelPage == 2) { | |
emotion = document.getElementById('emotion').value; | |
url += "/voice/w2v2-vits?id=" + id + "&emotion=" + emotion; | |
} else if (currentModelPage == 3) { | |
sdp_ratio = document.getElementById("input_sdp_ratio").value; | |
streaming = document.getElementById('streaming3'); | |
emotion = document.getElementById('input_emotion3').value; | |
text_prompt = document.getElementById('input_text_prompt3').value; | |
style_text = document.getElementById('input_style_text3').value; | |
style_weight = document.getElementById('input_style_weight3').value; | |
url += "/voice/bert-vits2?id=" + id; | |
} else if (currentModelPage == 4) { | |
streaming = document.getElementById('streaming4'); | |
prompt_text = document.getElementById('input_prompt_text4').value; | |
prompt_lang = document.getElementById('input_prompt_lang4').value; | |
preset = document.getElementById('input_preset4').value; | |
top_k = document.getElementById('input_top_k4').value; | |
top_p = document.getElementById('input_top_p4').value; | |
temperature = document.getElementById('input_temperature4').value; | |
batch_size = document.getElementById('input_batch_size4').value; | |
// speed = document.getElementById('input_speed4').value; | |
url += "/voice/gpt-sovits?id=" + id; | |
} else { | |
console.error("Invalid model page: ", currentModelPage); | |
return null; | |
} | |
if (format != "" && format != null) { | |
url += "&format=" + format; | |
} | |
if (lang != "" && lang != null) { | |
url += "&lang=" + lang; | |
} | |
if (length != "" && length != null) { | |
url += "&length=" + length; | |
} | |
if (noise != "" && noise != null) { | |
url += "&noise=" + noise; | |
} | |
if (noisew != "" && noisew != null) { | |
url += "&noisew=" + noisew; | |
} | |
if (segment_size != "" && segment_size != null) { | |
url += "&segment_size=" + segment_size; | |
} | |
if (currentModelPage == 1) { | |
if (streaming.checked) | |
url += '&streaming=true'; | |
} else if (currentModelPage == 3) { | |
if (streaming.checked) | |
url += '&streaming=true'; | |
if (sdp_ratio != "") | |
url += "&sdp_ratio=" + sdp_ratio; | |
// length_zh = document.getElementById("input_length_zh3").value; | |
// if (length_zh != "") | |
// url += "&length_zh=" + length_zh; | |
// length_ja = document.getElementById("input_length_ja3").value; | |
// if (length_ja != "") | |
// url += "&length_ja=" + length_ja; | |
// length_en = document.getElementById("input_length_en3").value; | |
// if (length_en != "") | |
// url += "&length_en=" + length_en; | |
if (emotion !== null && emotion !== "") | |
url += "&emotion=" + emotion; | |
if (text_prompt !== null && text_prompt !== "") | |
url += "&text_prompt=" + text_prompt; | |
if (style_text !== null && style_text !== "") | |
url += "&style_text=" + style_text; | |
if (style_weight !== null && style_weight !== "") | |
url += "&style_weight=" + style_weight; | |
} else if (currentModelPage == 4) { | |
if (streaming.checked) | |
url += '&streaming=true'; | |
if (prompt_lang !== null && prompt_lang !== "") | |
url += "&prompt_lang=" + prompt_lang; | |
if (prompt_text !== null && prompt_text !== "") | |
url += "&prompt_text=" + prompt_text; | |
if (preset !== null && preset !== "") | |
url += "&preset=" + preset; | |
if (top_k !== null && top_k !== "") | |
url += "&top_k=" + top_k; | |
if (top_p !== null && top_p !== "") | |
url += "&top_p=" + top_p; | |
if (temperature !== null && temperature !== "") | |
url += "&temperature=" + temperature; | |
if (batch_size !== null && batch_size !== "") | |
url += "&batch_size=" + batch_size; | |
if (speed !== null && speed !== "") | |
url += "&speed=" + speed; | |
} | |
if (api_key != "") { | |
url += "&api_key=" + api_key | |
} | |
url += "&text=" + text | |
return url; | |
} | |
function updateLink() { | |
let url = getLink(); | |
let link = document.getElementById("vits_link"); | |
link.href = url; | |
link.textContent = url; | |
} | |
function setAudioSourceByGet() { | |
if (currentModelPage == 1 && vitsSpeakersCount <= 0) { | |
alert("未加载VITS模型"); | |
return; | |
} | |
if (currentModelPage == 2 && w2v2SpeakersCount <= 0) { | |
alert("未加载W2V2-VITS模型"); | |
return; | |
} | |
if (currentModelPage == 3 && bertVits2SpeakersCount <= 0) { | |
alert("未加载Bert-VITS2模型"); | |
return; | |
} | |
let url = getLink(); | |
// Add a timestamp parameter to prevent browser caching | |
let timestamp = new Date().getTime(); | |
url += '&t=' + timestamp; | |
let audioPlayer = document.getElementById("audioPlayer" + currentModelPage); | |
audioPlayer.src = url; | |
audioPlayer.play(); | |
} | |
function setAudioSourceByPost() { | |
if (currentModelPage == 1 && vitsSpeakersCount <= 0) { | |
alert("未加载VITS模型"); | |
return; | |
} | |
if (currentModelPage == 2 && w2v2SpeakersCount <= 0) { | |
alert("未加载W2V2-VITS模型"); | |
return; | |
} | |
if (currentModelPage == 3 && bertVits2SpeakersCount <= 0) { | |
alert("未加载Bert-VITS2模型"); | |
return; | |
} | |
let text = $("#input_text" + currentModelPage).val(); | |
let id = $("#input_id" + currentModelPage).val(); | |
let format = $("#input_format" + currentModelPage).val(); | |
let lang = $("#input_lang" + currentModelPage).val(); | |
let segment_size = $("#input_segment_size" + currentModelPage).val(); | |
let api_key = $("#apiKey").val(); | |
let formData = new FormData(); | |
formData.append('text', text); | |
formData.append('id', id); | |
formData.append('format', format); | |
formData.append('lang', lang); | |
formData.append('segment_size', segment_size); | |
let url = ""; | |
let length = null; | |
let noise = null; | |
let noisew = null; | |
let streaming = null; | |
let sdp_ratio = null; | |
// let length_zh = 0; | |
// let length_ja = 0; | |
// let length_en = 0; | |
let emotion = null; | |
let text_prompt = ""; | |
let style_text = ""; | |
let style_weight = ""; | |
let prompt_text = null; | |
let prompt_lang = null; | |
let preset = null; | |
let top_k = null; | |
let top_p = null; | |
let temperature = null; | |
let batch_size = null; | |
let speed = null; | |
let headers = {}; | |
if (currentModelPage == 1 || currentModelPage == 2 || currentModelPage == 3) { | |
length = $("#input_length" + currentModelPage).val(); | |
noise = $("#input_noise" + currentModelPage).val(); | |
noisew = $("#input_noisew" + currentModelPage).val(); | |
formData.append('length', length); | |
formData.append('noise', noise); | |
formData.append('noisew', noisew); | |
} | |
if (currentModelPage == 1) { | |
url = baseUrl + "/voice/vits"; | |
streaming = $("#streaming1")[0]; | |
} else if (currentModelPage == 2) { | |
emotion = $("#emotion").val(); | |
url = baseUrl + "/voice/w2v2-vits"; | |
} else if (currentModelPage == 3) { | |
sdp_ratio = $("#input_sdp_ratio").val(); | |
url = baseUrl + "/voice/bert-vits2"; | |
streaming = $("#streaming3")[0]; | |
// length_zh = $("#input_length_zh3").val(); | |
// length_ja = $("#input_length_ja3").val(); | |
// length_en = $("#input_length_en3").val(); | |
emotion = $("#input_emotion3").val(); | |
text_prompt = $("#input_text_prompt3").val(); | |
style_text = $("#input_style_text3").val(); | |
style_weight = $("#input_style_weight3").val(); | |
} else if (currentModelPage == 4) { | |
url = baseUrl + "/voice/gpt-sovits"; | |
streaming = $("#streaming4")[0]; | |
prompt_text = $("#input_prompt_text4").val(); | |
prompt_lang = $("#input_prompt_lang4").val(); | |
preset = $("#input_preset4").val(); | |
top_k = $("#input_top_k4").val(); | |
top_p = $("#input_top_p4").val(); | |
temperature = $("#input_temperature4").val(); | |
batch_size = $("#input_batch_size4").val(); | |
// speed = $("#input_speed4").val(); | |
} | |
// 添加其他配置参数到 FormData | |
if ((currentModelPage == 1 || currentModelPage == 3 || currentModelPage == 4) && streaming.checked) { | |
formData.append('streaming', true); | |
} | |
if (currentModelPage == 3 && sdp_ratio != "") { | |
formData.append('sdp_ratio', sdp_ratio); | |
} | |
// if (currentModelPage == 3 && length_zh != "") { | |
// formData.append('length_zh', length_zh); | |
// } | |
// if (currentModelPage == 3 && length_ja != "") { | |
// formData.append('length_ja', length_ja); | |
// } | |
// if (currentModelPage == 3 && length_en != "") { | |
// formData.append('length_en', length_en); | |
// } | |
if ((currentModelPage == 2 || currentModelPage == 3) && emotion != null && emotion != "") { | |
formData.append('emotion', emotion); | |
} | |
if ((currentModelPage == 3 || currentModelPage == 4) && selectedFile) { | |
formData.append('reference_audio', selectedFile); | |
} | |
if (currentModelPage == 3 && text_prompt) { | |
formData.append('text_prompt', text_prompt); | |
} | |
if (currentModelPage == 3 && style_text) { | |
formData.append('style_text', style_text); | |
} | |
if (currentModelPage == 3 && style_weight) { | |
formData.append('style_weight', style_weight); | |
} | |
if (api_key !== "") { | |
headers['X-API-KEY'] = api_key; | |
} | |
if (currentModelPage == 4 && prompt_text) { | |
formData.append('prompt_text', prompt_text); | |
} | |
if (currentModelPage == 4 && prompt_lang) { | |
formData.append('prompt_lang', prompt_lang); | |
} | |
if (currentModelPage == 4 && preset) { | |
formData.append('preset', preset); | |
} | |
if (currentModelPage == 4 && top_k) { | |
formData.append('top_k', top_k); | |
} | |
if (currentModelPage == 4 && top_p) { | |
formData.append('top_p', top_p); | |
} | |
if (currentModelPage == 4 && temperature) { | |
formData.append('temperature', temperature); | |
} | |
if (currentModelPage == 4 && batch_size) { | |
formData.append('batch_size', batch_size); | |
} | |
if (currentModelPage == 4 && speed) { | |
formData.append('speed', speed); | |
} | |
let downloadButton = document.getElementById("downloadButton" + currentModelPage); | |
// 发送post请求 | |
$.ajax({ | |
url: url, | |
method: 'POST', | |
data: formData, | |
processData: false, | |
contentType: false, | |
responseType: 'blob', | |
xhrFields: { | |
responseType: 'blob' | |
}, | |
headers: headers, | |
success: function (response, status, xhr) { | |
let blob = new Blob([response], {type: 'audio/wav'}); | |
let audioPlayer = document.getElementById("audioPlayer" + currentModelPage); | |
let audioFileName = getFileNameFromResponseHeader(xhr); | |
audioPlayer.setAttribute('data-file-name', audioFileName); | |
audioPlayer.src = URL.createObjectURL(blob); | |
audioPlayer.load(); | |
audioPlayer.play(); | |
downloadButton.disabled = false; | |
}, | |
error: function (error) { | |
// console.error('Error:', error); | |
let message = "无法获取音频数据,请查看日志!"; | |
console.log(message) | |
alert(message); | |
downloadButton.disabled = true; | |
} | |
}); | |
} | |
function getFileNameFromResponseHeader(xhr) { | |
var contentDispositionHeader = xhr.getResponseHeader('Content-Disposition'); | |
var matches = contentDispositionHeader.match(/filename=(.+)$/); | |
return matches ? matches[1] : 'audio.wav'; // 如果无法从响应头获取文件名,则使用默认值 | |
} | |
function downloadAudio() { | |
let audioPlayer = document.getElementById("audioPlayer" + currentModelPage); | |
let audioFileName = audioPlayer.getAttribute('data-file-name') || 'audio.wav'; | |
let downloadLink = document.createElement('a'); | |
downloadLink.href = audioPlayer.src; | |
downloadLink.download = audioFileName; | |
document.body.appendChild(downloadLink); | |
downloadLink.click(); | |
document.body.removeChild(downloadLink); | |
} | |
function showContent(index) { | |
const panes = document.querySelectorAll(".content-pane"); | |
const buttons = document.querySelectorAll(".tab-button"); | |
currentModelPage = index + 1; | |
for (let i = 0; i < panes.length; i++) { | |
if (i === index) { | |
panes[i].classList.add("active"); | |
buttons[i].classList.add("active"); | |
} else { | |
panes[i].classList.remove("active"); | |
buttons[i].classList.remove("active"); | |
} | |
} | |
updateLink(); | |
} | |
function showModelContentBasedOnStatus() { | |
if (vitsSpeakersCount > 0) { | |
showContent(0); | |
} else if (w2v2SpeakersCount > 0) { | |
showContent(1); | |
} else if (bertVits2SpeakersCount > 0) { | |
showContent(2); | |
} else if (GPTSoVitsSpeakersCount > 0) { | |
showContent(3); | |
} else { | |
showContent(0); | |
} | |
} | |
function updatePlaceholders(config, page) { | |
for (let key in config) { | |
if (key == "presets") { | |
let data = config[key]; | |
let selectElement = $("#input_preset" + page); | |
selectElement.empty(); // 清除现有的选项 | |
let isFirst = true; | |
for (let name in data) { | |
let preset_value = data[name]; | |
let preset = `[${name}] audio: ${preset_value["refer_wav_path"]}`; | |
// 创建preset | |
let option = $("<option>", { | |
value: name, | |
text: preset, | |
'data-prompt-lang': preset_value["prompt_lang"], | |
'data-prompt-text': preset_value["prompt_text"] | |
}); | |
selectElement.append(option); | |
// 自动填入第一个preset的参考文本 | |
if (isFirst) { | |
$("#input_prompt_lang" + page).val(preset_value["prompt_lang"]); | |
$("#input_prompt_text" + page).val(preset_value["prompt_text"]); | |
isFirst = false; | |
} | |
} | |
// 当选择改变时更新输入预设的值 | |
selectElement.change(function () { | |
let selectedOption = $(this).find(":selected"); | |
let promptLang = selectedOption.data("prompt-lang"); | |
let promptText = selectedOption.data("prompt-text"); | |
$("#input_prompt_lang" + page).val(promptLang); | |
$("#input_prompt_text" + page).val(promptText); | |
}); | |
} else { | |
$("#input_" + key + page).attr("placeholder", config[key]); | |
} | |
} | |
} | |
function setDefaultParameter() { | |
$.ajax({ | |
url: "/voice/default_parameter", | |
method: 'POST', | |
responseType: 'json', | |
success: function (response) { | |
default_parameter = response; | |
updatePlaceholders(default_parameter.vits_config, 1); | |
updatePlaceholders(default_parameter.w2v2_vits_config, 2); | |
updatePlaceholders(default_parameter.bert_vits2_config, 3); | |
updatePlaceholders(default_parameter.gpt_sovits_config, 4); | |
}, | |
error: function (error) { | |
} | |
}); | |
} | |
document.addEventListener('DOMContentLoaded', function () { | |
var apiKeyIcon = document.getElementById('apiKeyIcon'); | |
var apiKeyInput = document.getElementById('apiKeyInput'); | |
var apiKeyField = document.getElementById('apiKey'); | |
// 检查 apiKey 是否已存储在 localStorage 中 | |
var storedApiKey = localStorage.getItem('apiKey'); | |
if (storedApiKey) { | |
apiKeyField.value = storedApiKey; | |
} | |
// 点击图标时切换 apiKeyInput 的可见性 | |
apiKeyIcon.addEventListener('click', function (event) { | |
apiKeyInput.style.display = apiKeyInput.style.display === 'flex' ? 'none' : 'flex'; | |
// 停止事件传播,防止文档点击事件立即隐藏输入框 | |
event.stopPropagation(); | |
}); | |
// 在点击其他地方时隐藏 apiKeyInput | |
document.addEventListener('click', function () { | |
apiKeyInput.style.display = 'none'; | |
}); | |
// 防止点击输入框时输入框被隐藏 | |
apiKeyInput.addEventListener('click', function (event) { | |
event.stopPropagation(); | |
}); | |
}); | |
function saveApiKey() { | |
var apiKeyField = document.getElementById('apiKey'); | |
var apiKey = apiKeyField.value; | |
// 将 apiKey 保存到 localStorage 中 | |
localStorage.setItem('apiKey', apiKey); | |
document.getElementById('apiKeyInput').style.display = 'none'; | |
} | |
$(document).ready(function () { | |
speakersInit(); | |
setDefaultParameter(); | |
setBaseUrl(); | |
$('.reference_audio').fileinput({ | |
language: 'zh', | |
dropZoneEnabled: true, | |
dropZoneTitle: "上传参考音频", | |
uploadAsync: false, | |
maxFileCount: 1, | |
showPreview: false, | |
showUpload: false | |
}).on("fileloaded", function (event, file, previewId, index, reader) { | |
selectedFile = file; | |
}).on("filecleared", function (event) { | |
selectedFile = null; | |
}); | |
}); |