AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)

环境:

AI-Sphere-Butler

VBCABLE2.1.58

Win10专业版

豆包桌面版1.47.4

ubuntu22.04

英伟达4070ti 12G

python3.10

问题描述:

AI-Sphere-Butler之如何将豆包桌面版对接到AI全能管家~新玩法(一)

在这里插入图片描述
在这里插入图片描述

聊天视频:

AI真人版豆包来了,AI全能管家新玩法。

解决方案:

1.先安装VBCABLE2.1.58工具,采集豆包音频

“VBCABLE_Driver_Pack45win10” 指的是适用于 Windows 10 系统的 VBCABLE 驱动程序包,版本号可能是 45 。“VBCABLE” 可能是该驱动相关的产品或技术名称,“Driver_Pack” 明确是驱动程序包,而 “win10” 表明其适用的操作系统为 Windows 10 。例如,可能是一种虚拟音频电缆相关的驱动包,用于在 Windows 10 系统上实现特定音频功能。

下载完软件安装x64版

在这里插入图片描述
继续安装
在这里插入图片描述
2.打开电脑声音设置找到应用音量和设备首选项
在这里插入图片描述
3.将豆包程序的输出设备选择CABLEInput

在这里插入图片描述

4.自行安装python和安装依赖:

pip install flask flask-sockets gevent gevent-websocket

5.编写采集豆包声音客户端

Collection.py文件内容:

import asyncio
import sounddevice as sd
import websockets
import numpy as np
import signal
import threading
import time
from collections import dequeINPUT_RATE = 16000
CHANNELS = 1
FRAME_SIZE = 640  
WS_URL = "ws://192.168.1.4:8020"#websockets服务地址
SILENCE_THRESHOLD = 1000stop_event = threading.Event()
signal.signal(signal.SIGINT, lambda s, f: stop_event.set())class AudioBuffer:def __init__(self, max_frames=20):self.buffer = deque(maxlen=max_frames)self.lock = threading.Lock()def put(self, frame_bytes):with self.lock:if len(self.buffer) == self.buffer.maxlen:self.buffer.popleft()print("[BUF] Buffer full, dropping oldest frame")self.buffer.append(frame_bytes)def get_all(self):with self.lock:frames = list(self.buffer)self.buffer.clear()return framesdef size(self):with self.lock:return len(self.buffer)def is_voice(data_np):energy = np.mean(data_np.astype(np.float32) ** 2)return energy > SILENCE_THRESHOLDdef audio_callback(indata, frames, time_info, status, audio_buffer):if status:print(f"[CAP] Warning: {status}")audio_np = indata[:, 0]ts = time.time()if is_voice(audio_np):frame = audio_np.tobytes()#print(f"[CAP] Voice frame captured at {ts:.3f}s, energy sufficient")else:frame = (np.zeros_like(audio_np)).tobytes()#print(f"[CAP] Silence frame at {ts:.3f}s")audio_buffer.put(frame)async def sender(ws, audio_buffer):while not stop_event.is_set():frames = audio_buffer.get_all()if not frames:await asyncio.sleep(0.005)continuefor frame in frames:try:await ws.send(frame)#print(f"[SND] Sent frame size={len(frame)} at {time.time():.3f}s, buffer size={audio_buffer.size()}")except Exception as e:print(f"[SND] Send error: {e}")stop_event.set()returnasync def capture_and_send(ws):audio_buffer = AudioBuffer(20)device_index = Nonedevices = sd.query_devices()for i, d in enumerate(devices):if "CABLE" in d['name'] and d['max_input_channels'] >= CHANNELS:device_index = ibreakif device_index is None:device_index = sd.default.device[0]print(f"[SYS] Using device #{device_index}: {devices[device_index]['name']}")send_task = asyncio.create_task(sender(ws, audio_buffer))with sd.InputStream(samplerate=INPUT_RATE,device=device_index,channels=CHANNELS,dtype='int16',blocksize=FRAME_SIZE,callback=lambda indata, frames, time_info, status:audio_callback(indata, frames, time_info, status, audio_buffer)):print("[SYS] Recording started.")while not stop_event.is_set():await asyncio.sleep(0.1)send_task.cancel()try:await send_taskexcept asyncio.CancelledError:passprint("[SYS] Recording stopped.")async def main():print(f"[SYS] Connecting to {WS_URL}")try:async with websockets.connect(WS_URL) as ws:print("[SYS] Connected.")await capture_and_send(ws)except Exception as e:print(f"[ERR] Connection error: {e}")if __name__ == '__main__':asyncio.run(main())

6.主程序引入模块文件websocket_service.py:

AI-Sphere-Butler\core\server\virtual_human\websocket_service.py

import asyncio
import uuid
import websockets
import multiprocessing
import queueMAX_QUEUE_SIZE = 10def enqueue_audio_data(audio_queue, data):try:audio_queue.put_nowait(data)except queue.Full:try:discarded = audio_queue.get_nowait()print("[WSrv] 丢弃过旧音频包,防止积压")except queue.Empty:passtry:audio_queue.put_nowait(data)except queue.Full:# print("[WSrv] 队列满,丢弃当前音频包")passasync def audio_handler(websocket, audio_queue: multiprocessing.Queue):session_id = str(uuid.uuid4())# print(f"[WSrv] Session {session_id} connected")try:async for raw in websocket:if isinstance(raw, (bytes, bytearray)):enqueue_audio_data(audio_queue, (session_id, raw))# print(f"[WSrv] Queued {len(raw)} bytes from {session_id}")else:# print(f"[WSrv] Ignored non-binary message from {session_id}")passexcept websockets.exceptions.ConnectionClosed:passfinally:# print(f"[WSrv] Session {session_id} disconnected")passasync def run_server(audio_queue: multiprocessing.Queue, host='0.0.0.0', port=8020):async def handler(websocket):await audio_handler(websocket, audio_queue)server = await websockets.serve(handler, host, port)# print(f"[WSrv] Listening on ws://{host}:{port}")await asyncio.Future()  if __name__ == "__main__":q = multiprocessing.Queue(maxsize=MAX_QUEUE_SIZE)asyncio.run(run_server(q))

7.运行采集客户端和AI-Sphere-Butler服务

在这里插入图片描述

8.这样就可以和豆包聊天,驱动AI全能管家数字人说话了

在这里插入图片描述

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

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

相关文章

【STM32】启动流程

1、.s启动文件解析 STM32的启动文件(一般是.s汇编文件,如startup_stm32f407xx.s)是STM32上电后执行的第一段代码,承担着“系统初始化化引导员”的角色。 它的主要作用是设置初始化栈指针(SP)、程序计数器&…

【vim】通过vim编辑器打开、修改、退出配置文件

通过vim编辑器打开任一配置文件 vim /etc/profile 英文输入下,按i键进入INSERT模式,修改配置文件 完成修改后,按esc键退出INSERT模式 英文输入下,输入":wq!",即可保存并退出 :q #不保存并退出 :q! …

Effective Modern C++ 条款6:当 auto 推导类型不符合预期时,使用显式类型初始化惯用法

在C开发中,auto关键字以其简洁性和高效性被广泛使用。然而,“自动推导”并非万能,尤其在某些特殊场景下,auto的推导结果可能与开发者预期不符,甚至导致未定义行为。今天,我们以《Effective Modern C》条款6…

学习Linux进程冻结技术

原文:蜗窝科技Linux进程冻结技术 功耗中经常需要用到,但是linux这块了解甚少,看到这个文章还蛮适合我阅读的 1 什么是进程冻结 进程冻结技术(freezing of tasks)是指在系统hibernate或者suspend的时候,将…

GitHub 趋势日报 (2025年06月22日)

📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 624 LLMs-from-scratch 523 ai-engineering-hub 501 n8n 320 data-engineer-handb…

kotlin中为什么新增扩展函数功能?

在 Kotlin 中,扩展函数的本质是「不修改原有类代码,为其新增功能」,这源自编程中「开闭原则」(对扩展开放,对修改关闭)的第一性原理。 核心需求:当需要给第三方库的类(如 Android 的…

excel 数据透视表介绍

Excel 数据透视表(PivotTable)就是你的数据分析神器!它能帮你快速汇总、分类、比较和分析 大量数据,从看似杂乱无章的表格中一键提取关键信息 ,生成交互式的汇总报告。无需复杂公式,只需拖拽几下,就能让数据“开口说话”&#xff…

半导体行业中的专用标准产品ASSP是什么?

半导体行业中的专用标准产品ASSP是什么? “专用标准产品”(ASSP - Application Specific Standard Product)是半导体集成电路中的一个重要分类。 你可以把它理解为介于通用标准产品和全定制ASIC之间的一种芯片。以下是它的核心定义和特点&a…

秋招Day14 - MySQL - 锁

MySQL中有几种类型的锁? 锁粒度来分,有表锁、页锁和行锁。 加锁机制划分,有乐观锁和悲观锁。 按兼容性划分,有共享锁和排他锁。 按锁模式划分,有记录锁,间隙锁,next-key锁,意向锁…

/var/lib/docker/overlay2目录过大怎么办

/var/lib/docker/overlay2 是 Docker 默认用于存储 容器镜像和容器运行时数据 的核心目录,基于 overlay2 存储驱动实现。以下是其具体作用和内容的详细解析: 1. overlay2 目录的作用 存储镜像分层结构: Docker 镜像采用分层设计,o…

JimuReport:一款免费的数据可视化报表工具

JimuReport(积木报表)是一款免费的企业级数据可视化报表软件,提供拖拽的方式像搭建积木一样完成在线设计,功能涵盖数据报表、打印设计、图表报表、门户设计、大屏设计等。 数据源 JimuReport 支持 30 多种数据源,包括…

Neo4j.5.X社区版创建数据库和切换数据库

在使用Neo4j数据库(版本:neo4j-community-5.22.0)时,系统自带的“neo4j”和“system”数据库适用于日常的简单学习和练习,但对于新的项目,将项目数据与练习数据混用会带来诸多不便,例如查询效率…

DAY33神经网络

浙大疏锦行 定义了一个简单的神经网络,主要是掌握pytorch框架

拼团系统多层限流架构详解

拼团系统多层限流架构详解 一、整体架构设计理念 多层限流采用"层层设防"思想,通过网关层全局流量控制→服务层接口粒度限流→本地资源隔离→热点参数精准防护的四级防御体系,实现从粗到细的流量治理,确保大促期间系统稳定性。 …

[ctfshow web入门] web92 `==`特性与intval特性

信息收集 和之前的题差不多,这次是使用了不严格相等的,详情看这篇博客: 和 在 PHP 中有何区别?一共包含哪些部分? 首先,不能使$num 4476,然后需要使intval($num,0)4476 include("flag…

在Springboot项目部署时遇到,centos服务器上,curl请求目标地址不通 ,curl -x 可以请求通的解决办法

在甲方服务器部署项目时,通常遇到需要开通外网权限的问题,有的是直接给开通服务器的白名单,就可以直接访问白名单外网地址了。也有的是通过网络转发,将url前面的部分替换,可以进行网络请求。有一次遇到一个罕见的&…

Python异步爬虫编程技巧:从入门到高级实战指南

Python异步爬虫编程技巧:从入门到高级实战指南 🚀 📚 目录 前言:为什么要学异步爬虫异步编程基础概念异步爬虫核心技术栈入门实战:第一个异步爬虫进阶技巧:并发控制与资源管理高级实战:分布式…

JMeter-SSE响应数据自动化3.0

背景 此次因为多了一些需要过滤排除的错误(数量很少),还需要修改下JMeter的jtl文件输出数据(后续统计数据需要) 所以只涉及到JSR脚本的一些改动(此部分改动并不会影响到JMeter的HTML报告) 改动 主要通过设置JMeter中prev输出数据变量threadN…

012 进程状态和优先级

🦄 个人主页: 小米里的大麦-CSDN博客 🎏 所属专栏: Linux_小米里的大麦的博客-CSDN博客 🎁 GitHub主页: 小米里的大麦的 GitHub ⚙️ 操作环境: Visual Studio 2022 文章目录 进程状态和优先级一、进程状态分类特殊状态说明 二、如何查看进程…

React JSX原理

JSX本质 实质上是React.createElement()的语法糖