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

news2024/11/16 3:23:59

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

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

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

1、文本转语音接口

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

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

代码仓库地址

 GitHub edge-ttsicon-default.png?t=N7T8https://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 创建页面画布和按钮
<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 模型
    // 数字人模型
    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 创建播放音频函数,播放音频 并调用模型开口说话动作

    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 测试音频播放,并开口说话。点击 测试音频 按钮,测试正常播放调用。一切正常
        $("#play").click(function () {
            talk(model4, "./demo.mp3");
        });
2.6 核心来了,让模型根据文字内容开口说话
$("#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的制作成本相对低很多,想商用的话感兴趣可以去查下模型制作教程  ~ 

代码也已开源,仓库地址

live2dSpeekicon-default.png?t=N7T8https://github.com/lyz1810/live2dSpeek

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Go语言初探】(三)、运行程序报错:Cannot find package “xxx“

一、问题描述 在运行项目中的main.go文件时&#xff0c;报错&#xff1a;Error: Cannot find package cast 报错截图如下&#xff1a; 二、原因及解决方法 出现上述报错的原因是&#xff0c;运行方法栏中选择了“Package”&#xff08;包运行&#xff09;&#xff0c;改成“…

WebGoC题解(19) 12569.(2022GoC能力测试第5题)智慧树 难度:4

时限&#xff1a;5s 空间&#xff1a;256m 通过次数&#xff1a;827 题目描述 有一种智慧树&#xff0c;它是这样生长的&#xff0c;它先长出长度50的主干&#xff0c;才开始长侧枝&#xff0c;每长出一根侧枝&#xff0c;主干就向上长出长度30。如果侧枝长度是偶数&am…

了解 K-Means 聚类的工作原理(详细指南)

一、说明 K-means 的目标是将一组观测值划分为 k 个聚类&#xff0c;每个观测值分配给均值&#xff08;聚类中心或质心&#xff09;最接近的聚类&#xff0c;从而充当该聚类的代表。 在本文中&#xff0c;我们将全面介绍 k 均值聚类&#xff08;最常用的聚类方法之一&#xff0…

Python 全栈系列263 简易资源监控

说明 开始比等待强 这块其实我也不太熟&#xff0c;而且我也知道应该有更专业的做法 其实连grafana我都准备好了&#xff0c;prometheus的镜像也准备好了&#xff0c;但是还没时间去细细弄。 我想先快快整一版够用的&#xff08;能让我依据这个数据进行调度&#xff09;就行。…

高性能内存对象缓存

Memcached概述 一套开源的高性能分布式内存对象缓存系统 所有的数据都存储在内存中 支持任意存储类型的数据 提高网站的访问速度 数据存储方式与数据过期方式 数据存储方式:Slab Allocation 按组分配内存&#xff0c;每次先分配一个Slab&#xff0c;相当于一个大小为1M的页&…

技术革新!MultiDesk:高效远程桌面管理工具,TAB切换引领新潮流!

前言 话说远程操作&#xff0c;win系统自带的远程工具那可真是个让人头疼又爱不释手的活儿&#xff1b;不过别怕&#xff0c;今天小江湖要给大家揭秘一款神器——MultiDesk&#xff1b;有了它&#xff0c;可以不需要频繁切换窗口&#xff0c;不再为记不住复杂的服务器地址和密…

电脑监控怎样看回放视频?一键解锁电脑监控回放,守护安全不留死角!高效员工电脑监控,回放视频随时查!

你是否曾好奇那些键盘敲击背后的秘密&#xff1f;电脑监控不仅是守护企业安全的隐形盾牌&#xff0c;更是揭秘高效与合规的魔法镜&#xff01;一键解锁安企神监控回放&#xff0c;就像打开时间宝盒&#xff0c;让过去的工作瞬间跃然眼前。无论是精彩瞬间还是潜在风险&#xff0…

go语言中数据接口set集合的实现

概述 set 是一种常用的数据结构&#xff0c;它表示一组唯一元素的集合。在不同的编程语言和库中&#xff0c;set 可能有不同的实现方式和特性。 set 集合数据结构具有以下特性&#xff1a; 唯一性&#xff1a;set 中的元素是唯一的&#xff0c;不允许重复。这意味着在 set 中…

Linux环境下OpenSSH升级到 OpenSSH_9.8p1(内置保姆级教程并包含openssl升级过程)

文章目录 前言一、下载openssh、openssl二进制包二、升级步骤1.系统开启telnet&#xff0c;防止意外导致shh无法连接2.确认升级前openssh的版本3.升级openssh3.1.备份旧ssh配置文件及目录3.2.备份旧ssh相关的二进制程序文件3.3.安装gcc,并解压9.8p1的安装包3.4.执行openssh编译…

超有性价比深度学习卡特斯拉 P100,16G大显存,Stable Diffusion AI 绘画利器

超有性价比深度学习卡特斯拉 P100&#xff0c;16G大显存&#xff0c;Stable Diffusion AI 绘画利器 在当今数字化创作的时代&#xff0c;AI 绘画技术正以惊人的速度发展&#xff0c;为艺术家和创作者们带来了全新的可能性。而要实现高效的 AI 绘画&#xff0c;一款性能卓越的显…

MySQL——基本概念、环境安装、分类、语法(增删改查)以及内置数据库与基本函数

目录 一、数据库的概念 二、数据库的分类 关系型数据库&#xff1a; 非关系型数据库&#xff1a; 三、数据库系统 四、安装数据库 配置数据库的环境变量 五、MySQL的登录命令 六、SQL DDL DML DQL DCL 七、创建数据库 八、增删改查数据库 增加数据 删除数据 逻…

进程间的通信2——有名管道、信号

通信方式&#xff1a;(1)单工&#xff1a;//广播&#xff1b;单一方向的数据通道&#xff1b; &#xff08;2&#xff09;半双工&#xff1a;//对讲机&#xff1b;同一时刻只能有一个方向&#xff1b; &#xff08;3&#xff09;全双工&#xff1a;//手机电话&#xff1b;同一时…

Selenium 自动化测试平台

1.介绍 Selenium 是一套 Web网站 的程序自动化操作 解决方案。 通过它&#xff0c;我们可以写出自动化程序&#xff0c;像人一样在浏览器里操作web界面。 比如点击界面按钮&#xff0c;在文本框中输入文字 等操作。 而且还能从web界面获取信息。 比如获取 火车、汽车票务信息…

Spark2.x 入门:套接字流(DStream)

Spark Streaming可以通过Socket端口监听并接收数据&#xff0c;然后进行相应处理。 新建NetworkWordCount.scala代码文件&#xff0c;请在该文件中输入如下内容&#xff1a; package org.apache.spark.examples.streaming import org.apache.spark._ import org.apache.spark…

图像数据处理9

二、灰度变换 2.3 非线性灰度变换 以下式子中使用 f 表示输入图像的像素值&#xff0c;g 表示输出图像的像素值 2.3.1伽马校正&#xff08;Gamma Correction&#xff09; γ 是伽马值&#xff0c;通常大于0。调整 γ 的值可以改变图像的亮度。当 γ<1 时&#xff0c;图像…

一个简单的Rtmp推流客户端(QT录音,OpenCV摄像,FFmpeg编码推流)

RTMP&#xff08;Real-Time Messaging Protocol&#xff09;是一种实时流媒体传输协议&#xff0c;常用于音视频直播。 RTMP推流客户端是一种能够将音视频数据推送到直播服务器的工具。QT录音是利用Qt库实现的录音功能。OpenCV摄像是利用OpenCV库实现的对摄像头的控制和图像处理…

Chrome书签搜索插件

效果展示 这是一个chroma插件&#xff0c;可以按住 ctrl/command B 进行搜索您的书签&#xff0c;并且点击打开您的书签。支持上下切换回车打开新页面。支持文件夹搜索。多层级文件夹使用 / 分割。如&#xff1a;文件夹1/文件夹2/标签1 扩展下载地址 bookmark-search 欢迎有…

小程序学习day09-WXS脚本、自定义组件-组件的创建、引用、组件与页面的区别、组件的样式隔离

39、WXS脚本&#xff08;小程序独有的一套脚本语言&#xff09; &#xff08;1&#xff09;作用&#xff1a;结合WXML&#xff0c;可以构建出页面结构 &#xff08;2&#xff09;应用&#xff1a;在小程序中充当过滤器。&#xff08;wxml无法调用在页面的.js中定义的函数&…

DNS in Kubernetes

DNS in Kubernetes 对象分配的名称Service DNS 记录Pod DNS 记录 Cluster DNS参考 DNS for Services and Pods 这里主要讨论集群内不同对象之间的DNS解析 默认情况下&#xff0c;创建集群时&#xff0c;k8s会部署内置的DNS服务器&#xff0c;在集群内&#xff0c;我们不关注…

spring-boot-3.2.6+spring-security-6.2.4+oauth2整合github示例

一、添加依赖 在 pom.xml 中添加如下依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"h…