欢迎光临散文网 会员登陆 & 注册

使用nodejs完成TTS有声书的制作

2023-06-08 01:05 作者:需求等待中  | 我要投稿


现今网络媒体中已经出现了多种基于TTS的亚文化二创,比如电棍活字印刷,绫地宁宁朗诵等等。

这些作品大都是作者通过特定的可执行文件手动编辑输入文字并剪辑的,效率并不高。

本文将以绫地宁宁朗诵为例子,介绍一种通过nodejs批量化操作,制造有声书视频的方法。

本文将使用的工具包括:

nodejs

MoeGoe

puppeteer

ffmpeg

工具介绍

nodejs

Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台执行环境。

Node.js 大部分基本模块都用 JavaScript 语言编写。在 Node.js 出现之前,JavaScript 通常作为客户端程序设计语言使用,以JavaScript 写出的程序常在用户的浏览器上执行。Node.js 的出现使 JavaScript 也能用于服务端编程。Node.js 含有一系列内置模块,使得程序可以脱离 Apache HTTP Server 或 IIS,作为独立服务器执行。

简要的讲,nodejs允许我们通过JavaScript编程操作计算机系统中的文件,进程和网络等等对象,正如同CMD,PowerShell这类技术一样。

参考:https://nodejs.dev/en/

Moegoe

Moegoe是b站ID名为@CjangCjengh 的大佬开发的基于VITS的AI语音合成引擎,主要提供TTS(Text to Sound,文字转语音)的功能,目前已经预先计算好的音色模型多种多样,通过在Moegoe中应用这些模型文件,我们得以用该音色朗诵文字,Moegoe最常用的音色是绫地宁宁(綾地 寧々),在bilibili可见各种的二次创作。

目前Moegoe仅有Windows版打包文件,直接使用Python源文件进行部署会面临一系列问题,本文使用作者预先打包好的Windows可执行文件进行操作。

参考:https://github.com/CjangCjengh/MoeGoe

puppeteer

puppeteer是一种流行的无头浏览器(headless browser)框架,一般意义上的浏览器通过其内核解析HTML,CSS,JavaScript等等网页组成文件,将其渲染为一个浏览器页面进程,用户通过图形化的浏览器进行交互,无头浏览器不提供可视化界面,而是通过API提供浏览器应当有的全部功能,包括对DOM(document object model)进行操作(这也就包括了我们在浏览器中常用的功能,比如点击超链接,保存图片等等),截图,跳转网页,提供COOKIE等等。

puppeteer是封装为npm包的无头浏览器,这意味着我们可以在nodejs的编程环境下直接通过JavaScript脚本对其进行操作

参考:https://www.npmjs.com/package/puppeteer

FFmpeg

FFmpeg 是一个开放源代码的自由软件,可以执行音频和视频多种格式的录影、转换、串流功能,包含了libavcodec——这是一个用于多个项目中音频和视频的解码器库,以及libavformat——一个音频与视频格式转换库。

FFmpeg提供一个命令行操作界面,用户得以以此对音视频进行操作,应当指出市面上大部分的音视频剪辑软件都是对FFmpeg的再封装。

本文基于nodejs完成大部分操作,因此选用了fluent-ffmpeg作为FFmpeg在nodejs环境下的封装作为工具。

参考:

https://ffmpeg.org

https://www.npmjs.com/package/fluent-ffmpeg


操作思路

使用上述技术完成小仲马《茶花女》有声书的生成脚本的思路如图:

流程图

首先通过人工操作,对《茶花女》以txt格式记录的原文本进行编辑,主要通过正则表达式作为工具,对原文文本进行段落的划分,并去除多余的注释的换行符,制表符等等。

在原文文本具有一致明确的格式后,通过JavaScript的String对象的实例方法对原文中的每个句子重新标记好其在文章中的位置信息,包括每个句子所在的章节,位于整篇文档中的第几行,是其所在章节中的第几句话,记录为一个Javascript数组中的一个json元素。

在以视频作为表现形式的有声书中,原文中每一句话将表现为一段视觉可见的文字和与之对应的语音,两者结合形成一段表现该文字的视频,多段视频前后连接即形成整篇有声书。

视觉可见的文字将以一张电子图片的形式生成,在这里使用puppeteer作为生成工具,预先制作好一个展示文字的网页模板,模板中预留出文字和文字相关的元信息的位置,在通过访问DOM的方法进行赋值并截图,由无头浏览器生成图片备用。

网页模板,文字控制字数为4行15列,超出部分会分开生成

声音将通过Moegoe的Windows进程生成。Moegoe的操作基于Python打包,nodejs环境不能直接操作,因此使用node:child_process模块进行操作,以生成一个子进程的方法,对子进程的标准输入和输出流进行操作,达到批量生成文字的目的。

在每一小段图片和音频生成后,使用FFmpeg将两者结合生成一段视频,将各个小段视频连接,加上片头片尾即可得到成品。

踩坑记录

通过nodejs操作Moegoe是本项目中最具挑战性的环节,Moegoe提供的是命令行界面,用户通过输入文字和进程进行交流,使用child_process模块对Moegoe进行封装,实际上是在重写整个命令行界面,对命令行进行封装,使之成为易于使用的JavaScript API,因此首先要充分穷举命令行界面的所有行为,明确其内部的循环语句的结构,再再JavaScript中对应的进行循环语句的条件判断。

最最最致命的是,Windows命令行界面默认使用GB2312作为文字输入输出的编码,而Python的输入输出流是cp936,两者互相读取将导致乱码,乱码输入的中文文字对于Moegoe而言生成的音频也是乱码。因此选用了iconv-lite作为解决编码问题的方案,在写入时使用GB2312,在读取输出时使用cp936。

在nodejs的实际编程中,采用了分别编写图片生成脚本,音频生成脚本,视频生成脚本,再通过一个总的脚本引入三者,读取标记好的原文文本信息进行批量化生成。

在批量化生成的过程中使用了JavaScript的异步编程语法,await和async关键字,应当注意,await结合async的语法生成的Promise链有时会有不自动结束pending状态的问题,因此需要对promise链中的每一步进行仔细考虑。

源代码

我的github登录不上了,放评论区



使用nodejs完成TTS有声书的制作的评论 (共 条)

分享到微博请遵守国家法律