01
引言
随着 AIGC 技术的快速发展,虚拟主播逐渐成为内容生产、直播带货、在线教育和人机交互的重要应用场景。
传统虚拟主播系统多依赖规则驱动和预设脚本,缺乏灵活性和智能化。而大型语言模型(LLM)的出现,为虚拟主播赋予了自然语言理解、情感表达和多模态生成的能力。
本文将带你从零开始,结合 DeepSeek 模型,搭建一个可落地的智能虚拟主播系统。在阅读完本文后,你将能够:
学会如何让虚拟角色开口说话并口型同步
搭建一套“AI 大脑”驱动的智能对话系统
将画面和声音推流到直播平台,实现真正的“虚拟主播”
02
系统总体架构
一个典型的虚拟主播系统可以分为以下几个核心模块:
输入层
• 观众或用户输入(文字)
智能决策层(核心:DeepSeek 模型)
• 自然语言理解
• 对话管理
• 内容生成与风格控制
输出层
• 语音合成(TTS)
• 虚拟形象驱动(口型)
• 场景渲染与实时输出(直播推流)
03
前期准备工作
在正式搭建前,我们需要先准备好所需的软件和关键信息,这是确保后续流程顺利的基础。
VTube Studio 是一款常用的虚拟形象驱动软件,能让虚拟模型实现口型跟随等效果,我们通过 Steam 平台安装:
首先安装 Steam,打开后在商店搜索 “VTube Studio” 并下载安装。
若 Steam 商店加载缓慢或无法打开,可下载网易 UU 加速器对 Steam 进行加速,提升访问速度。
Python 是后续实现文本转语音等功能的关键工具,安装步骤如下:
前往 Python 官网(https://www.python.org/)下载适合 Windows 系统的最新版本。
-
安装时需勾选 “Add Python to PATH” 选项,方便后续在命令行中直接调用 Python。
-
安装完成后,打开命令提示符(Win+R,输入 cmd),输入 “python --version”,若显示 Python 版本号,则安装成功。
AI 大模型是虚拟主播 “智能大脑” 的核心,我们可选择多种主流模型(比如DeepSeek,通义千问,ChatGPT),它们的 API 接口基本兼容,后续可灵活替换,目前我们用的是DeepSeek做例子:
DeepSeek:进入 DeepSeek 官网,注册充值即可获取 API Key,性价比高,足够长时间使用。
虚拟声卡用于实现声音的内录和传输,确保虚拟主播的语音能被正确识别,步骤如下:
访问虚拟声卡驱动官网(https://vb-audio.com/Cable),下载最新版本的驱动安装包(推荐 “VBCABLE Driver Pack45.zip”,支持 XP 到 WIN11 系统)。
安装完成后,右键点击任务栏音量图标,选择 “声音”,在 “输出” 栏可看到 “CABLE Input (VB-Audio Virtual Cable)”,“输入” 栏可看到 “CABLE Output (VB-Audio Virtual Cable)”,表示安装成功。
04
配置 VTube Studio:让虚拟形象 “活” 起来
安装好 VTube Studio 后,我们需要进行一系列配置,让虚拟模型能跟随声音做出反应。
打开 VTube Studio,进入模型选择界面:
界面左侧“有更改VTS模型”等选项,若有自定义模型,可点击 “导入” 添加;若无,可选择软件自带的模型(如 Akari、Hijiki、Hiyori_A 等)。
点击想要使用的模型,即可完成选择,模型会在主界面显示。
为了让 VTube Studio 识别到虚拟主播的语音,需将麦克风设置为之前安装的虚拟声卡:
在 VTube Studio 主界面,找到 “设置” 选项,点击进入,找到”麦克风配置“项。
勾选 “使用麦克风”,然后点击 “麦克风” 下拉框,选择 “CABLE Output (VB-Audio Virtual Cable)”。
可根据需求调整 “音频增益”“音量限幅”“频率增益” 等参数,一般保持默认即可,若声音过小,可适当提高 “音频增益”。
让虚拟模型的口型随语音变化,是提升真实感的关键步骤:
在 VTube Studio 中,进入 “设置” 界面,找到 “Mouth Open”(口型张开)相关设置。
在“输入”选项下,点击下拉框,选择 “VoiceVolumePlusMouthOpen”,该选项能让口型根据声音音量和预设的口型参数综合变化。
“输出” 选项默认选择 “ParamMouthOpen” 即可。
05
用 OBS Studio 获取虚拟主播画面
OBS Studio 是一款常用的直播推流软件,我们用它来获取 VTube Studio 中的虚拟主播画面,以便后续开播。
打开 OBS Studio,进入主界面:
添加一个”游戏采集“场景。
“模式” 选择 “采集特定窗口”,确保只采集 VTube Studio 的画面,避免其他窗口干扰。
“窗口” 下拉框中,选择 “[VTube Studio.exe]: VTube Studio”,确保选中正确的 VTube Studio 窗口。
勾选”允许窗口透明“,主要作用是可以给虚拟主播换其他背景。
06
实现文本转语音:让虚拟主播 “开口说话”
文本转语音功能能将 AI 模型生成的文字回复转换为语音,我们使用 Python 的免费库pyttsx3来实现。
打开命令提示符(cmd),输入以下命令安装所需库:
安装pyttsx3:
pip install pyttsx3,该库依赖 Windows 系统自带的语音,无需联网,播放声音较为单一。
以pyttsx3为例,编写简单的文本转语音代码,实现输入文本、语速、音量,输出语音的功能:
import pyttsx3
import sys
def main():
try:
engine = pyttsx3.init()
# 获取当前语速和音量
rate = engine.getProperty('rate')
volume = engine.getProperty('volume')
# 从命令行参数获取语速(第一个参数)和音量(第二个参数)
if len(sys.argv) > 1:
rate = int(sys.argv[1])
if len(sys.argv) > 2:
volume = float(sys.argv[2])
# 设置语速和音量
engine.setProperty('rate', rate)
engine.setProperty('volume', volume)
# 从标准输入读取文本
text = sys.stdin.read()
# 播放语音
engine.say(text)
engine.runAndWait()
except Exception as e:
print(f"An error occurred: {e}", file=sys.stderr)
if __name__ == "__main__":
main()
将上述代码保存为 “text_to_speech.py” 文件,后续可通过命令行调用该脚本实现文本转语音。
为了方便在其他程序(如 C++)中调用文本转语音功能,我们将 “text_to_speech.py 脚本打包为 EXE 文件,使用 pyinstaller 工具:
首先安装 pyinstaller:在命令提示符中输入
pip install pyinstaller。
进入 “text_to_speech.py” 文件所在的文件夹,在该文件夹路径下打开命令提示符,输入
pyinstaller --onefile text_to_speech.py。
执行完成后,在该文件夹下会生成 “dist” 文件夹,进入 “dist” 文件夹,即可找到 生成的“text_to_speech.exe” 执行文件,双击可直接运行,也可被其他程序调用。
07
调用 AI 模型 API:给虚拟主播 “智能大脑”
通过调用 AI 模型 API,让虚拟主播能根据用户提问生成智能回复,这里以 DeepSeek为例(其他AI模型调用也一样,基本接口都是一样的),介绍 API 调用方法。
使用 curl 命令即可调用 DeepSeek 的 API,获取 AI 回复,命令格式如下:
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <DeepSeek API Key>" \
-d '{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "你叫小莉,是一位直播场景下的虚拟主播,需要保持简洁与互动性。"},
{"role": "user", "content": "你叫什么名字。"}
],
"stream": false
}'
将<DeepSeek API Key>替换为你自己的 DeepSeek API Key,执行该命令,即可得到 AI 模型返回的 JSON 格式回复。如果是其他AI模型,只需要修改url,Key和model即可。
API 请求中的关键参数决定了 AI 模型的回复效果和返回方式,具体说明如下:
system:用于设定 AI 的角色和回复规则。例如,若想让 AI 扮演直播平台的虚拟主播 “小莉”,可将 content 设置为:“你叫小莉,是一位直播场景下的虚拟主播,需要保持简洁与互动性。”
user:代表用户的提问内容。例如,用户问 “你叫什么名字。”,则 content 设置为 “你叫什么名字”。
stream:控制回复的返回方式。设为 “true” 时,AI 会逐步返回回复内容,适合实时互动场景;设为 “false” 时,AI 会生成完整回复后一次性返回,适合需要完整文本的场景。
callDeepSeekAPI 函数
功能:调用大语言模型 API,发送聊天消息并获取响应。
参数:
apiKey:API 访问密钥(Bearer Token)
messages:聊天消息列表(JSON 格式,包含角色和内容)返回值:API 返回的原始响应字符串(JSON 格式)。
核心流程:
初始化 libcurl 并设置请求 URL(阿里云通义千问兼容接口)。
构造 JSON 请求体,包含模型名称、消息列表和非流式响应参数。
设置 HTTP 头部(Content-Type 和 Authorization)。
注册
WriteCallback处理响应数据。执行请求并清理资源。
// 调用DeepSeek接口
std::string callDeepSeekAPI(const std::string& apiKey, const Json::Value& messages){
CURL* curl;
CURLcode res;
std::string readBuffer;
// 初始化curl
curl = curl_easy_init();
if (curl) {
// 设置URL
//deepseek
std::string url = "https://api.deepseek.com/chat/completions";
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
// 设置HTTP方法为POST
curl_easy_setopt(curl, CURLOPT_POST, 1L);
// 构建JSON请求体
Json::Value request;
//deepseek
request["model"] = "deepseek-chat";
request["messages"] = messages;
request["stream"] = false;
Json::StreamWriterBuilder writerBuilder;
std::string jsonRequest = Json::writeString(writerBuilder, request);
// 设置请求体
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonRequest.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)jsonRequest.length());
// 设置请求头
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
std::string authHeader = "Authorization: Bearer " + apiKey;
headers = curl_slist_append(headers, authHeader.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// 设置回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
// 执行请求
res = curl_easy_perform(curl);
// 检查请求结果
if (res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
}
// 清理
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
}
return readBuffer;
}
WriteCallback 函数
功能:作为 libcurl 的回调函数,用于处理 HTTP 响应数据,将接收到的内容追加到字符串中。
参数:
contents:接收数据的缓冲区指针
size:每个数据单元的大小
nmemb:数据单元的数量
s:用于存储结果的字符串指针返回值:实际处理的数据大小(
size * nmemb),若内存分配失败返回 0。
// 回调函数,用于处理HTTP响应
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* s) {
size_t newLength = size * nmemb;
try {
s->append((char*)contents, newLength);
}
catch (std::bad_alloc& e) {
return 0;
}
return newLength;
}
parseResponse 函数
功能:解析 API 返回的 JSON 响应,提取大模型的回答内容。
参数:
response为 API 返回的原始 JSON 字符串。返回值:提取的回答内容(字符串),解析失败则返回空字符串。
// 解析JSON响应
std::string parseResponse(const std::string& response){
Json::StreamWriterBuilder writerBuilder;
writerBuilder["emitUTF8"] = true; // 禁止 Unicode 转义,输出 UTF-8 编码的中文
std::string jsonString = Json::writeString(writerBuilder, response);
std::wcout.imbue(std::locale(""));
std::wstring wideJsonString = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes(jsonString);
std::wcout << L"recv.messages JSON:" << std::endl;
std::wcout << wideJsonString << std::endl;
Json::CharReaderBuilder readerBuilder;
Json::Value root;
std::string errors;
std::istringstream iss(response);
if (Json::parseFromStream(readerBuilder, iss, &root, &errors)) {
if (root.isMember("choices") && root["choices"].isArray() && root["choices"].size() > 0) {
return root["choices"][0]["message"]["content"].asString();
}
}
return "";
}
callTTS 函数
功能:调用上文中Python语音合成工具
text_to_speech.exe,将文本转换为语音。参数:
text:待合成的文本
rate:语速(默认 200)
volume:音量(默认 1.0)返回值:布尔值,表示语音合成是否成功。
bool callTTS(const std::string& text, int rate = 200, float volume = 1.0){
std::string command = "text_to_speech.exe \"" + text + "\" " + std::to_string(rate) + " " + std::to_string(volume);
// 计算所需的宽字符缓冲区大小,使用 CP_ACP
int wideLength = MultiByteToWideChar(CP_ACP, 0, command.c_str(), -1, nullptr, 0);
if (wideLength == 0) {
std::cerr << "计算宽字符缓冲区大小时出错,错误代码: " << GetLastError() << std::endl;
return false;
}
// 分配宽字符缓冲区
std::wstring wideCommand(wideLength, 0);
// 进行实际的转换
if (MultiByteToWideChar(CP_ACP, 0, command.c_str(), -1, &wideCommand[0], wideLength) == 0) {
std::cerr << "执行多字节到宽字符转换时出错,错误代码: " << GetLastError() << std::endl;
return false;
}
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; // 隐藏窗口
// 创建新进程
if (!CreateProcessW(NULL, const_cast<LPWSTR>(wideCommand.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
std::cerr << "执行语音转换时创建进程出错,错误代码: " << GetLastError() << std::endl;
return false;
}
// 等待进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭进程和线程句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
08
最终显示效果
使用OBS Studio进行rtmp推流
编写一个简单的web当作观众端,发送内容到服务端
使用vlc或ffplay进行rtmp拉流
09
应用与优化:挑战与实践经验
在完成从零到一的搭建之后,虚拟主播系统真正投入使用时,往往会遇到各种技术与场景挑战。下面结合实践经验,总结一些常见问题与优化思路。
直播带货
带货类虚拟主播需要语速更快、语调更有激情,以营造“紧迫感”。同时还要能实时识别观众的互动弹幕,在几秒内做出回应,否则容易丧失用户注意力。
在线教育
教育类场景强调知识传递的准确性与稳定性。虚拟主播需要更严谨的逻辑组织、较慢的语速,以及较少的口语化表达。
虚拟偶像演出
在娱乐和二次元文化中,虚拟偶像的粉丝更在意角色个性与情绪表现。因此,除了语言输出,还要结合丰富的表情、手势和舞台效果。
企业客服
客服场景要求 24 小时稳定运行,重点在于响应速度和信息准确,而不是外观或娱乐性。
不同场景的差异,决定了在构建虚拟主播时,需要对 模型参数设定、语音合成风格、场景渲染方式 做针对性调整。
语音的情绪化不足
问题:传统 pyttsx3 语音听感单一,容易给人“机器人朗读”的感觉。
优化:
•引入 ChatTTS、VITS 等开源模型,支持“愤怒、开心、疑问”等情绪标签。
•结合背景音乐与音效,弱化语音单调感。
口型与表情匹配
问题:仅用音量驱动口型,容易出现“张嘴大小一致”的僵硬效果。
优化:
•利用能量包络+ 频谱特征来驱动嘴型,模拟“元音/辅音”的差异。
•增加表情绑定,例如语音中检测到“疑问语气”,触发挑眉或歪头动作。
硬件门槛:入门级方案仅需一台普通 PC
•CPU:英特尔® 酷睿™ i7-6700处理器
•显卡:NVIDIA GeForce GTX 960
•内存:8GB
•硬盘:固态硬盘500G
若要支持 1080p 高清推流和高并发 AI 生成,建议配置更好的电脑。
网络环境:上行带宽至少 4Mbps,才能保证画面与音频同步稳定。
成本评估:DeepSeek 模型调用成本相对较低,适合长期运行;现在用的是入门的key,导致返回速度比较慢,如果追求更强的多模态效果,可以考虑接入商用 API或其他大模型,但费用会更高。
人性化小技巧:
•在 OBS 中为主播加上实时字幕,提升观众的可理解性。
•使用虚拟声卡通道叠加背景音乐或音效,增强直播氛围。
实时翻译:结合语音识别与机器翻译,主播可支持多语言观众互动。
多角色互动:通过一个服务端管理多个虚拟角色,实现“AI 主播连麦PK”。
动作捕捉融合:接入摄像头或动作捕捉设备,让虚拟主播拥有更丰富的肢体语言。
情绪识别与反馈:通过分析弹幕情绪,主播能在合适的时机调整语气和表情,营造更强的互动感。
10
结语与展望
虚拟主播的核心竞争力,正在从“炫酷外观”转向“智能驱动”。
借助 DeepSeek 模型,我们能够构建一个具备自然对话能力、情感表达和实时交互的虚拟主播系统。
未来,多模态大模型的发展(语音、表情、动作、视频生成)将进一步提升沉浸感,让虚拟主播24小时都成为教育、娱乐、商业领域的 超级助理。
11
参考资料
AI虚拟主播居然这么简单就做出来了?


