<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <th:block th:include="include :: header('火山引擎-豆包声音克隆')" />
</head>
<body class="gray-bg">

<div class="container-div">
    <div class="row">

     <div class="col-sm-12 search-collapse">
            <pre><strong>豆包语音克隆注意事项：</strong>
1. 请在火山引擎后台 <a href="https://www.volcengine.com/docs/6561/1167802" target="_blank">"购买声音复刻音色"</a>。 注意：每个音色最多只能 "上传并训练10次"。
2. 请预先录制好 20-30 秒左右的声音，请确保环境安静且无噪音。
    推荐的录制方式:
    a. 电脑加耳机组合，使用电脑自带的录音机录制;
    b. 使用手机自带的录音机，把录制好的录音文件发送到电脑。</pre>
      </div>

        <div class="col-sm-12 search-collapse">
            <form id="formId">
                <div class="select-list">
                    <ul>
                        <li>
                            <label th:text="#{doubaovcl.form.voice-name}"></label>
                            <input type="text" name="voice_name" id="voice_name" />
                        </li>
                        <li>
                            <label th:text="#{doubaovcl.form.speaker_id}"></label>
                            <input type="text" name="speaker_id" id="speaker_id" />
                        </li>

                        <li>
                            <label th:text="#{doubaovcl.form.model_type}"></label>
                            <select name="model_type" id="model_type" onchange="$.operate.setLanguageList()">
                                <option value="1">声音复刻ICL1.0效果</option>
                                <option value="2">DiT标准版效果（音色、不还原用户的风格）</option>
                                <option value="3">DiT还原版效果（音色、还原用户口音、语速等风格）</option>
                                <option value="4">声音复刻ICL2.0效果</option>
                            </select>
                        </li>

                        <li>
                            <label th:text="#{doubaovcl.form.language}"></label>
                            <select name="language" id="language">
                            </select>
                        </li>

                        <li>
                            <a class="btn btn-info btn-xs" href="javascript:void(0)" onclick="$.operate.importFile()"><i class="fa fa-upload"></i> &nbsp;<span th:text="#{doubaovcl.form.chooseWavFile}"></span></a>
                          </li>
                    </ul>
                </div>
            </form>
        </div>

        <div class="col-sm-12 search-collapse" id="tts_text_area" style="display: none">
            <form id="formId2">
                <div class="select-list">
                    <ul>
                        <li>
                            <label th:text="#{doubaovcl.form.test_text}"></label>
                            <textarea placeholder="请输入测试语音合成的文本" name="tts_text" id="tts_text" cols="40" rows="5" ></textarea>
                        </li>

                        <li>
                            <label th:text="#{doubaovcl.form.language}"></label>
                            <select name="language_test" id="language_test">
                            </select>
                            <a class="btn btn-primary btn-rounded btn-sm" onclick="$.operate.ttsTest()"><i class="fa fa-search"></i>&nbsp;<span th:text="#{btn.ok}"></span></a>
                        </li>

                        <li>
                            <audio id="test_player" controls="controls" ></audio>
                        </li>
                    </ul>
                </div>
            </form>
        </div>

    </div>
</div>

<th:block th:include="include :: footer" />
<script th:inline="javascript">
    var prefix = ctx + "aicall/doubaovcl";
    $(function() {
        $("#model_type").val('2');
        $.operate.setLanguageList();
    });

    // fill dropdown list for language field.
    $.operate.setLanguageList = function() {
        var modelType = parseInt($("#model_type").val());
        $.operate.setLanguageUtil(modelType, $('#language'));
        $.operate.setLanguageUtil(modelType, $('#language_test'));
    };

    $.operate.setLanguageUtil = function(modelType, languageHtmlObject ){
        languageHtmlObject.empty();
        // model_type为3或4时候，仅支持中英文
        languageHtmlObject.append('<option value="0">中文</option>');
        languageHtmlObject.append('<option value="1">英文</option>');

        if (modelType <= 2) {
            languageHtmlObject.append('<option value="2">日语</option>');
            languageHtmlObject.append('<option value="3">西班牙语</option>');
            languageHtmlObject.append('<option value="4">印尼语</option>');
            languageHtmlObject.append('<option value="5">葡萄牙语</option>');
        }

        // 仅当model_type为2的时候，支持德语和法语
        if (modelType === 2) {
            languageHtmlObject.append('<option value="6">德语</option>');
            languageHtmlObject.append('<option value="7">法语</option>');
        }
    };

    // send tts test request
    $.operate.ttsTest = function() {
        if($.operate.ttsTest.processing === true){
            $.modal.msg("请等待合成完成!");
            return;
        }
        $.operate.ttsTest.processing = true;
        var formData = new FormData();
        formData.append('language', $("#language_test").val());
        formData.append('text', $("#tts_text").val());
        formData.append('speakerId', $("#speaker_id").val());
        $.ajax({
            url: prefix + "/doubaoTtsTest",
            type: "POST",
            data: formData,
            processData: false, // 告诉 jQuery 不要去处理发送的数据
            contentType: false, // 告诉 jQuery 不要去设置 Content-Type 请求头
            success: function(respJson) {
                var code = respJson["code"];
                if(code === 500){
                    var msgTips = respJson["msg"];
                    if(msgTips == null || msgTips.length === 0){
                        msgTips = i18n('doubaovcl.admin.tts-test.failed-tips');
                    }
                    $.modal.msgError(msgTips);
                }
                if(code === 0) {
                    $.modal.msgSuccess(i18n('doubaovcl.admin.tts-test.success-tips'));
                    var player =  $("#test_player");
                    player.css("display","block");
                    var audioJson = JSON.parse(respJson["data"]);
                    var audioCode =  audioJson["code"];
                    if(audioCode === 3000){
                        var audioSrc = 'data:audio/mp3;base64,' +  audioJson["data"];
                        console.log("try to play audio, length=", audioJson["data"].length );
                        player.attr("src", audioSrc);
                        player[0].play();
                    }
                }
            },
            complete: function(xhr, status) {
                $.operate.ttsTest.processing = false;
            },
            error: function() {
                $.modal.msgError(i18n('doubaovcl.form.upload-failed-tips'));
            }
        });
    };

    // 导入数据
    $.operate.importFile = function() {
        var input = document.createElement('input');
        input.type = 'file';
        input.accept = '.wav, .mp3, .ogg, .m4a, .aac'; // wav、mp3、ogg、m4a、aac
        input.onchange = function(event) {
            var file = event.target.files[0];
            if (file) {
                var formData = new FormData();
                formData.append('file', file);
                var voice_name = $("#voice_name").val().trim();
                var speaker_id = $("#speaker_id").val().trim();
                var language = $("#language").val().trim();
                var model_type = $("#model_type").val().trim();
                if(voice_name === ""){
                    $.modal.msgError("请填写 音色名称 ");
                    $("#voice_name")[0].focus();
                    return;
                }
                if(speaker_id === ""){
                    $.modal.msgError("请填写 声音ID ");
                    $("#speaker_id")[0].focus();
                    return;
                }
                formData.append('voice_name', voice_name);
                formData.append('speaker_id', speaker_id);
                formData.append('language', language);
                formData.append('model_type', model_type);
                $.modal.msg("正在上传中，整个过程大概需要15-30秒， 请稍后...");
                $.ajax({
                    url: prefix + "/uploadAndTrain",
                    type: "POST",
                    data: formData,
                    processData: false, // 告诉 jQuery 不要去处理发送的数据
                    contentType: false, // 告诉 jQuery 不要去设置 Content-Type 请求头
                    success: function(respJson) {
                        var code = respJson["code"];
                        if(code === 500){
                            var msgTips = respJson["msg"];
                            if(msgTips == null || msgTips.length === 0){
                                msgTips = i18n('doubaovcl.form.upload-failed-tips');
                            }
                            $.modal.msgError(msgTips);
                        }
                        if(code === 0) {
                            $.modal.msgSuccess(i18n('doubaovcl.form.upload-success-tips'));
                            $("#tts_text_area").css("display", "block");
                        }
                    },
                    error: function() {
                        $.modal.msgError(i18n('doubaovcl.form.upload-failed-tips'));
                    }
                });
            }
        };
        input.click();
    };

</script>
</body>
</html>