live2d + edge-tts 优雅的实现数字人讲话 ~

震惊!live2d数字人竟开口说话 ~

之前有想做数字人相关项目,查了一些方案。看了一些三方大厂的商用方案,口型有点尴尬,而且很多是采用视频流的方案,对流量的消耗很大。后来了解了live2d 技术,常在博客网页上见到的看板娘就是live2d技术实现的 ~

说下demo的技术实现,核心采用 live2d 的模型[含有开口说话的动作] + 文本转语音接口

1、文本转语音接口

这个接口采用前面分享过的edge-tts项目

基于微软TTS,优雅的实现文本转语音-CSDN博客

代码仓库地址

GitHub edge-ttshttps://github.com/lyz1810/edge-tts

2、前端实现数字人开口说话

2.1 引入 Live2D 必要的 JavaScript 库
复制代码
    <script src="./js/live2dcubismcore.min.js"></script>
    <script src="./js/live2d.min.js"></script>
    <script src="./js/pixi.min.js"></script>

    <!-- if only Cubism 4 support-->
    <script src="./js/cubism4.min.js"></script>
    <script src="./js/jquery-3.1.1.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2.2 创建页面画布和按钮
html 复制代码
<canvas id=canvas></canvas>
<div id="control">
    <div class="label">1、测试说话</div>
    <button id="play">测试音频</button>
    <br/><br/>
    <div class="label">2、调用接口生成音频</div>
    <textarea id="text" style="width:400px;height:300px;">你好,欢迎光临</textarea>
    <br/><br/>
    <button id="start">开始说话</button>
</div>



<style>
    #control {
        position: absolute;
        top: 50px;
        left: 50px;
        color: #ffffff;
        font-size: 18px;
    }

    .label {
        font-size: 32px;
        font-weight: 800;
    }
</style>
2.3 创建了一个 PIXI 渲染器实例,用于渲染 Live2D 模型
javascript 复制代码
    // 数字人模型
    const cubism4Model = "./assets/kei_vowels_pro/kei_vowels_pro.model3.json";

    const live2d = PIXI.live2d;
    (async function main() {
        const app = new PIXI.Application({
            view: document.getElementById("canvas"),
            autoStart: true,
            resizeTo: window,
            backgroundColor: 0x333333
        });

        const models = await Promise.all([
            live2d.Live2DModel.from(cubism4Model)
        ]);

        models.forEach((model) => {
            app.stage.addChild(model);

            const scaleX = (innerWidth) / model.width;
            const scaleY = (innerHeight) / model.height;

            // fit the window
            model.scale.set(Math.min(scaleX, scaleY));
            model.y = innerHeight * 0.1;
            draggable(model);
        });

        const model4 = models[0];
        console.log(innerWidth)
        // model4.x = innerWidth / 2;
        // 居中显示
        model4.x = (innerWidth - model4.width) / 2;

        model4.on("hit", (hitAreas) => {
            if (hitAreas.includes("Body")) {
                model4.motion("Tap");
            }

            if (hitAreas.includes("Head")) {
                model4.expression();
            }
        });

    })();
2.4 创建播放音频函数,播放音频 并调用模型开口说话动作
javascript 复制代码
    function talk(model, audio) {
        var audio_link = audio;  //[Optional arg, can be null or empty] [relative or full url path] [mp3 or wav file] "./Keira.wav"
        var volume = 1; // [Optional arg, can be null or empty] [0.0 - 1.0]
        var expression = 8; // [Optional arg, can be null or empty] [index|name of expression]
        var resetExpression = true; // [Optional arg, can be null or empty] [true|false] [default: true] [if true, expression will be reset to default after animation is over]
        var crossOrigin = "anonymous"; // [Optional arg, to use not same-origin audios] [DEFAULT: null]

        model.speak(audio_link, {
            volume: volume,
            expression: expression,
            resetExpression: resetExpression,
            crossOrigin: crossOrigin
        })
        model.speak(audio_link)
        model.speak(audio_link, {volume: volume})
        model.speak(audio_link, {expression: expression, resetExpression: resetExpression})

    }
2.5 测试音频播放,并开口说话。点击 测试音频 按钮,测试正常播放调用。一切正常
javascript 复制代码
        $("#play").click(function () {
            talk(model4, "./demo.mp3");
        });
2.6 核心来了,让模型根据文字内容开口说话
javascript 复制代码
$("#start").click(function () {
            console.log($("#text").val());
            let text = $("#text").val().trim();
            if (text == "") {
                alert("请输入内容");
                return false;
            }
            $("#start").prop("disabled", true);
            axios.get("http://127.0.0.1:2020/dealAudio?file_name=test.mp3&voice=xiaoxiao&text=" + text)
                .then(response => {
                    console.log(response.data);
                    const audioUrl = response.data + "?v=" + new Date().getTime();
                    talk(model4, audioUrl);
                    $("#start").prop("disabled", false);
                })
                .catch(error => {
                    console.error('请求接口失败:', error);
                    $("#start").prop("disabled", false);
                });
        });

这里调用的接口地址,采用的是文章开头提到的 文本转语音助手

输入文字,点击开始说话

模型正常说话 ~

live2d的卡通数字人,感觉比3D建模的"真人数字人"效果要好很多,都是张口说话,live2d显的不会那么尴尬 。

live2d的制作成本相对低很多,想商用的话感兴趣可以去查下模型制作教程 ~

代码也已开源,仓库地址

live2dSpeekhttps://github.com/lyz1810/live2dSpeek

相关推荐
aiguangyuan3 小时前
基于BERT的中文命名实体识别实战解析
人工智能·python·nlp
量子-Alex3 小时前
【大模型RLHF】Training language models to follow instructions with human feedback
人工智能·语言模型·自然语言处理
晚霞的不甘3 小时前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频
陈天伟教授3 小时前
人工智能应用- 语言处理:04.统计机器翻译
人工智能·自然语言处理·机器翻译
Dfreedom.3 小时前
图像处理中的对比度增强与锐化
图像处理·人工智能·opencv·锐化·对比度增强
wenzhangli73 小时前
OoderAgent 企业版 2.0 发布的意义:一次生态战略的全面升级
人工智能·开源
AI_56784 小时前
SQL性能优化全景指南:从量子执行计划到自适应索引的终极实践
数据库·人工智能·学习·adb
cyyt4 小时前
深度学习周报(2.2~2.8)
人工智能·深度学习
阿杰学AI4 小时前
AI核心知识92——大语言模型之 Self-Attention Mechanism(简洁且通俗易懂版)
人工智能·ai·语言模型·自然语言处理·aigc·transformer·自注意力机制
陈天伟教授4 小时前
人工智能应用- 语言处理:03.机器翻译:规则方法
人工智能·自然语言处理·机器翻译