【UE5】离线实时语音转文字 插件 教程

前言:该UE5.1项目实现了离线实时语音转文字并朗读输出结果的功能,能作为一个实现参考。

1.准备工作:

  • 下载我打包好的插件、环境、模型:baiduyun更多模型下载

  • 安装UE5.1引擎,VS开发环境&编译器:Epic LauncherMicrosoft VS

  • 新建空白C++项目后关闭引擎,并打开项目文件夹:

  • 项目文件夹中放入下载的插件与语言模型:

                1.项目目录/Plugins文件夹中放入下载解压好VoskPlugin插件

                2.项目目录/Vosk文件夹中放入下载解压好的语言服务器

                3.项目目录/Vosk/install/Models文件夹中放入解压好的大,小中文模型

2.各项设置:

  • 修改配置,项目支持语音: 项目目录/Config文件夹中修改DefaultEngine.ini,末尾添加配置项

  • [Voice]
    bEnabled=true
    [SystemSettings]
    voice.SilenceDetectionThreshold=0.01
  • 打开项目并在菜单栏-工具-新建C++类KTTKComponent(继承自VoskComponent)到Vosk插件中:

  • KTTKComponent.h中实现服务器初始化,各项默认配置,开启/关闭识别函数:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"

#include "VoskComponent.h"
#include "VoskServerParameters.h"
#include "ProcessHandleWrapper.h"
#include "Engine/World.h"
#include "TimerManager.h"
#include "Kismet/KismetSystemLibrary.h"

#include "KTTKComponent.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class VOSKPLUGIN_API UKTTKComponent : public UVoskComponent
{
	GENERATED_BODY()

public:	
	UKTTKComponent();

public:
	FString ModelPath;
	bool BuildVoskSucess = false;
	TArray<FString> CommandLineArgs;

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="使用AI语言大模型"))
	bool UseBigModel = false;

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="AI语言大模型路径"))
	FString BigModelPath = UKismetSystemLibrary::GetProjectDirectory() + "Vosk/install/Models/vosk-model-cn-0.22";

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="AI语言小模型路径"))
	FString SmallModelPath = UKismetSystemLibrary::GetProjectDirectory() + "Vosk/install/Models/vosk-model-small-cn-0.22";

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="识别服务器程序"))
	FString VoskServerExe = UKismetSystemLibrary::GetProjectDirectory() + "Vosk/install/asr_server.exe";

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="识别服务器IP"))
	FString VoskServerIP = "127.0.0.1";

	UPROPERTY(BlueprintReadWrite,EditAnywhere,category = "AI",meta = (displayName="识别服务器端口", ClampMin = "1024", ClampMax = "65535"))
	int32 VoskServerPort = 25565;

	UPROPERTY(BlueprintReadWrite,category = "AI")//识别服务器配置
	FVoskServerParameters serverconfig;

	UPROPERTY(BlueprintReadOnly,category = "AI")//识别服务进程Handle
	FProcessHandleWrapper ProcessHandleVosk;

	UFUNCTION(BlueprintCallable,category = "AI",meta = (displayName = "开始识别"))
	void Start(FString iDeviceNameIn);

	UFUNCTION(BlueprintCallable,category = "AI",meta = (displayName = "停止识别"))
	void End(TArray<uint8>& CaptureData,int32& SamplesRecorded);

protected:
	FTimerHandle DelayTimeHandle;
	void DelayTimmer();
	void initlazi();
	void InitlaziVosk();

	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:	
	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};
  • KTTKComponent中具体实现:

#include "KTTKComponent.h"

UKTTKComponent::UKTTKComponent()
{
	PrimaryComponentTick.bCanEverTick = true;
}

void UKTTKComponent::BeginPlay()
{
	Super::BeginPlay();

	if(UseBigModel==true)//Use Chinese Big Model or Small Model(使用中文语言大模型/小模型)
	{
		ModelPath = BigModelPath;
	}else{ModelPath = SmallModelPath;};
	FString FullPathOfProgramToRun = VoskServerExe;//服务器执行程序路径 

	serverconfig.PathToModel = ModelPath;//设置语言模型路径

	CommandLineArgs = BuildServerParameters(serverconfig,BuildVoskSucess);//创建执行命令

	CreateProcessV(ProcessHandleVosk,FullPathOfProgramToRun,CommandLineArgs,false,true,0);//创建执行识别进程

	initlazi();//进行识别服务器初始化
}

void UKTTKComponent::DelayTimmer()
{
	GetWorld()->GetTimerManager().SetTimer(DelayTimeHandle,this,&UKTTKComponent::InitlaziVosk,5.0f,false);
}

void UKTTKComponent::initlazi()
{
	if(IsInitialized()==false)//是否已经初始化识别服务
	{
		DelayTimmer();//延迟5秒执行开启识别服务器
	}else{return;};
}

void UKTTKComponent::InitlaziVosk()
{
	Initialize(VoskServerIP,VoskServerPort);
	GetWorld()->GetTimerManager().ClearTimer(DelayTimeHandle);//清除定时handle
}

void UKTTKComponent::Start(FString iDeviceNameIn)
{
	BeginCapture(iDeviceNameIn);//开始录制对话
}

void UKTTKComponent::End(TArray<uint8>& CaptureData,int32& SamplesRecorded)
{
	FinishCapture(CaptureData,SamplesRecorded);//结束录制对话
}

void UKTTKComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	if(EndPlayReason == EEndPlayReason::Type::Quit || EndPlayReason == EEndPlayReason::Type::EndPlayInEditor || EndPlayReason == EEndPlayReason::Type::Destroyed)
	{
		KillProcess(ProcessHandleVosk);//停止识别服务器
	}
}

void UKTTKComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

3.编译并测试:

  • 生成并打开该项目:

  • 蓝图中创建游戏模式GM_STTS,玩家控制器PC_STTS:

        1.该游戏模式中选定该玩家控制器,并将该游戏模式设置到当前地图的世界场景设置;
        2.玩家控制器中添加组件:KTTK,设置默认配置值(是否使用大的语言模型,模型自定义路径,本机或远程语言服务器IP端口),实现测试蓝图逻辑;
  • 电脑插入麦克风,运行关卡,按下测试按键即可测试回调输出打印字符。

  • 输出最终识别结果时朗读结果:蓝图中的TTSSpeech来自另一插件-TTSPluginMeoPlay(请自行寻找该插件)。

4.项目构建流程图:


后言:该项目实现了语言实时转文字,且能通过调用系统音色朗读输出内容。识别效果准确率根据模型精度而定,模型加载到内存So还需要考虑硬件需求。希望此文章能帮到你!
### 关于 Unreal Engine 5离线语音识别功能 目前,Unreal Engine 官方并未直接提供内置的离线语音识别功能。然而,开发者可以通过第三方插件或自行集成开源库来实现这一目标。 #### 使用 Sphinx-UE4 插件 Sphinx-UE4 是一个专为 Unreal Engine 设计的语音识别插件[^1]。尽管该插件最初是为了 UE4 开发的,但由于其基于 Pocketsphinx 库构建,理论上也可以适配到 UE5 中。Pocketsphinx 是 CMU Sphinx 系列中的轻量级版本,支持多种平台上的实时语音文字处理。要将其应用于 UE5: 1. **移植兼容性调整** 需要对原插件代码进行必要的修改以适应 UE5 的架构变化。这可能涉及更新蓝图节点接口以及修复因 API 变更而引发的编译错误。 2. **配置声学模型与词典文件** 下载适合目标语言的预训练模型并加载至项目中。这些资源通常可以从官方仓库或其他社区贡献者处获取。 3. **测试性能优化** 调整参数设置(如采样率、静音检测阈值等),确保在游戏运行环境中能够稳定工作且延迟较低。 #### 自定义开发方案 对于更高程度的需求控制或者希望完全自主掌控的情况,可以选择手动嵌入其他成熟的 C++ 或 Python SDK 到虚幻工程项目里去完成同样的任务。例如 Google Speech-to-Text Offline Mode 尽管主要面向 Android/iOS 移动端应用,但部分核心算法仍可借鉴用于桌面版部署;又或者是 Mozilla DeepSpeech 这样的纯机器学习驱动型框架也值得考虑尝试引入进来作为替代选项之一[^3]。 以下是利用 pocketsphinx 创建简单命令解析系统的伪代码示例: ```cpp #include <sphinxbase/err.h> #include <pocketsphinx/pocketsphinx.h> // 初始化解码器环境... ps_decoder_t *ps; cmd_ln_t *config; if ((config = cmd_ln_init(NULL, ps_args(), TRUE, "-hmm", MODELDIR "/en-us/en-us", "-lm", MODELDIR "/en-us/en-us.lm.bin", "-dict", MODELDIR "/en-us/cmudict-en-us.dict", NULL)) == NULL){ ERR_ERROR("Failed to create config object\n"); } /* Create a decoder instance */ if (!(ps = ps_init(config))) { fprintf(stderr, "Unable to open model\n"); } ``` --- ### 注意事项 虽然上述方法可行,但在实际操作过程中可能会遇到一些挑战,比如不同操作系统间的依赖管理问题、音频输入设备的选择限制等等。因此建议先从小规模原型做起逐步完善整个流程直至满足最终产品需求为止。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值