zhengyiwei1987
zhengyiwei1987
我是做了一个过度效果,让过度的时候画画面高斯模糊,虽然不会那么生硬,但也略胜于无,而且做了数字人讲话完成,自动跳转到动作编排的第一帧,这样,动作可控,不会跳转那么生硬
webrtc开启摄像头通道,视频截取视频帧,没5秒截取一次,再llm里修改一下,有图片就发送图片 ,思路给你了,具体这么做坑就很多
你要自己配置ASR,语音转文字的模型,或者用云上的,建议用豆包的语音识别大模型,准确率非常高,不过对接有点难度,你要自己处理webrtc音频流,断句
没配置stun吧,如果不想配置,临时用,可以把信令里面的内网ip替换成你服务器的公网ip,虽然不推荐临时可以用, 转发得开放很多端口的,webrtc就不要尝试转发了,老老实实的用stun服务 const answer = await offerReq.json(); answer.sdp = answer.sdp.replace(/192.168.0.168/g, '147.94.111.111'); await this.peerConn.setRemoteDescription(answer);
@byronv5 哈哈,我也是通过js让video音量平滑变小,延迟3-4秒,嘴还在动,我只能说体验很差啊,依然是你说你的我说我的, 做实时演示的时候,那叫一个尴尬,后端的清空流不管用,你清空的时候,实际上这时候,流都已经读出来了,估计在进行运算合成对嘴型,这个时候很难停下来,
@byronv5 就在刚刚,我找到了通过程序立即停止说话的地方了,如果用的事wav2lip,那在 lipreal.py 的 inference 方法里 只要设计一个准确一点的说话状态管理器就行了,那个 stopSpeaking 是我加的,只要让他False,数字人立马闭嘴🤣,这个方法我看不懂,猜测是从列队里拉出帧,处理了什么,然后在塞进列队 ,只然后再从 process_frames 方法里拉出来,要是流从 process_frames ,好像就来不及了 ,要做个状态管理器,把帧都丢弃掉就好了, for i,res_frame in enumerate(pred): #self.__pushmedia(res_frame,loop,audio_track,video_track) print('stopSpeaking', stopSpeaking) if stopSpeaking: res_frame_queue.put((res_frame,__mirror_index(length,index),audio_frames[i*2:i*2+2])) index = index + 1
@WThirteen 你无论怎么样你只要需要对口型,就都要把livekit的音频流推进来驱动口型,这不本质还是用tts驱动对口型么, 只要进入livetalking ,模型需要实时推理,以现在的架构就很难实现,我是设计了一个task_id的模式,从llm->tts每次请求都生成一个task_id,如果执行打断,就抛弃之前的,即便这样,打断也只能比原来快一点(大概2-3秒,但不会因为llm持续返回句子,一条一条的读),程序原本甚至能够到达5-6秒(基本是读完整个上下游游tts的音频流驱动后的列队,打断时间长短取决于llm断句生成的tts断句), 有时候我真怀疑,为了对口型值得么,哈哈
@WThirteen 这部分我研究过,我大模型用了FASTGPT(不用设计上下文逻辑),你别说用知识库了,就开启工作流模式,什么都不加节点,速度都要慢0.7-1.2秒,对于实时性很高要求的数字人来说,不合适,只能选用聪明的大模型+尽可能在系统初始提示词上做文章,要求不能太高,这就是豆包目前有ip形象,有语音通话,现在也有视频功能,就是没有开启虚拟ip形象数字人?大厂还搞不定这个?一是对口型确实影响打断和应答效率,即便asr调教的再好,也禁不住对推理口型拖后腿,二是体验提升微乎其微徒增算力。 至于非得私有化查询知识库慢,还是多在界面交互或者动作编排切换上做文章吧,比如设计优雅的等待动画,或者给任务编排思考的动作衔接 至于你那个还是换个思路吧,你调用了livetalking 就是先走了调用livetalking的tts,tts生成流式语音,然后驱动wav2lip,而wav2lip就是语音驱动口型的,本质还是得改进程序的底层架构,否则就只能用js检测麦克风音量让video标签音量变小的妥协办法
@wewaa 我已经做好了,打断能在1.5秒内打断就是改的地方有点多,tts里要加task_id,抛弃列队,basereal.py中要添加更新task_id的方法,task_id的作用主要针对连续像llm发送多条信息时,打断后取消之前一切对话,不会傻乎乎的一条一条的读几个字然后打断(asr识别到的消息发给llm之前我都会执行一次打断,即便这样,也会读取llm返回的每一条消息,说两个字就打断这样的过程),实现立即闭嘴, 而且做了再5秒内的asr识别出的消息合并(每个消息都有一个talkid,5秒内的消息沿用上一次的talkid),合并文字消息再次发送给大模型,这样降低因为asr因为断句,大模型对话的碎片化,在前端ui上,根据talkid合并chat消息气泡, 在baseasr.py 里self.feat_queue = mp.Queue(2),把2改成1,目前看没有什么副作用,mp.Queue 2改成1对打断速度提升巨大,
@WThirteen 设计的时候就要考虑销毁,例如livetalking的nerfreal,你可以吧你的服务构建进去,销毁的时候随着sessionid一同销毁,也可以绑定sessionid销毁,不过我已经把程序思路摸透了,将wav2lip搞到了小智ai里,webrtc启动链接,1秒打断,24000采样率tts,豆包asr语音识别,急速响应,识别率也非常高