IM项目-----语音识别子服务

news/2024/11/15 0:59:53/

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、搭建思想
  • 二、服务器搭建
    • 1.继承speechService类,重写业务代码
    • 2.编写语音识别服务器类
    • 3.建造者类编写
  • 三.测试


前言

语音转换子服务,用于调用语音识别 SDK,进行语音识别,将语音转为文字后返回给网关。

  1. 语音消息的文字转换:客户端进行语音消息的文字转换。

在这里插入图片描述


一、搭建思想

1.参数解析 – 基于gflags模块
rpc所需信息:
当前服务器的地址端口:用于搭建rpc服务器的监听地址信息

服务注册所需信息:
注册中心的地址端口:用于进行向服务注册中心进行服务注册

外部访问的地址端口:用于告诉注册中心的访问地址信息

语音识别平台所需信息
(app id,api key,secret key)

日志模块所需信息:
运行模式,日志文件名称,日志输出级别

2.初始化日志模块
3.搭建RPC服务器–实现语音识别业务接口功能
4.向注册中心进行服务注册

在这里插入图片描述

二、服务器搭建

1.继承speechService类,重写业务代码

只有一个rpc服务,就是进行语音识别,请求方需要将语音文件内容发送过来,我们在需要调用语音识别sdk,因此在成员变量中有一个ASRClient。这个变量是在make_rpc时传入进来的,在创建rpc时需要添加服务。

//1.继承SpeechService服务类,重写业务方法class SpeechServiceImpl :public SpeechService{public:SpeechServiceImpl(const ASRClient::ptr& _asr_client):_client(_asr_client){}~SpeechServiceImpl(){};//重写业务方法void SpeechRecognition(google::protobuf::RpcController* controller,const ::lkm_im::SpeechRecognitionReq* request,::lkm_im::SpeechRecognitionRsp* response,::google::protobuf::Closure* done){brpc::ClosureGuard rpc_guard(done);//解析出请求中的语音数据//基于语音识别sdk进行语音识别调用,获取语音转文字结果std::string err_msg;std::string resp = _client->recognize(request->speech_content(),err_msg);if(resp.empty()){//语音转文字失败LOG_ERROR("requestId = {} 语音识别失败.",request->request_id());response->set_request_id(request->request_id());response->set_success(false);response->set_errmsg(err_msg);}//构造响应返回response->set_request_id(request->request_id());response->set_success(true);response->set_recognition_result(resp);}private:ASRClient::ptr _client;     //语音识别客户端};

2.编写语音识别服务器类

在语音识别子服务中有三个对象,一个是服务注册对象,一个是语音识别对象,还有一个是rpc服务器。
服务注册对象的构建需要etcd服务器地址,注册的服务名称以及对应的主机地址。
语音识别对象的构建需要三个key.
rpc服务器构建需要rpc服务器监听的端口,还需要提供超时时间以及io线程数量.
构造这三个对象需要九个参数,因此我们使用建造者模式。

我们通过建造者类来构造这个对象,然后调用这个类提供的start方法,启动rpc服务器。

   //2.封装一个语音识别子服务服务器class SpeechServer{public:using ptr = std::shared_ptr<SpeechServer>;SpeechServer(const Registry::ptr& registry,const ASRClient::ptr& asr_client,const std::shared_ptr<brpc::Server>& server):_registry(registry),_asr_client(asr_client),_server(server){}~SpeechServer(){}//启动rpc服务器void start(){_server->RunUntilAskedToQuit();}private:Registry::ptr _registry;    //服务注册对象ASRClient::ptr _asr_client;     //语音识别客户端std::shared_ptr<brpc::Server> _server;        //rpc服务器};

3.建造者类编写

这个类提供了三个方法make_**(),需要先调用这个三个方法,来分别构造出rpc服务器,服务注册和语音识别客户端。在调用build方法,生成一个speechServer对象,通过这个对象就可以启动服务器。

在构造服务注册对象时,就会向etcd进行服务注册。

//建造者类,具体思想是通过建造者类的build函数构造一个SpeechServer对象,通过这个对象启动rpc服务器class SpeechServerBuilder{public:void make_registry(const std::string& etcd_host,const std::string& service_name,const std::string& service_host){_registry = std::make_shared<Registry>(etcd_host);//进行服务注册_registry->registry(service_name,service_host);}void make_asr(const std::string &app_id,const std::string &api_key,const std::string &secret_key){_asr_client = std::make_shared<ASRClient>(app_id,api_key,secret_key);}void make_brpc(uint16_t port, int32_t timeout = -1, uint8_t num_threads = 1){if(!_asr_client){LOG_ERROR("语音识别客户端未构造");abort();}//创建brpc服务器对象_server = std::make_shared<brpc::Server>();//添加服务SpeechServiceImpl *SpeechService = new SpeechServiceImpl(_asr_client);    //把这个对象的交给_server释放int ret = _server->AddService(SpeechService,brpc::ServiceOwnership::SERVER_OWNS_SERVICE);if (ret == -1) {LOG_ERROR("添加rpc服务失败");abort();}brpc::ServerOptions options;options.idle_timeout_sec = timeout;options.num_threads = num_threads;ret = _server->Start(port,&options);if(ret == -1){LOG_ERROR("rpc服务器启动失败");abort();}}SpeechServer::ptr build(){if(!_registry){LOG_ERROR("服务注册客户端对象未构造");abort();}if(!_asr_client){LOG_ERROR("语音识别客户端未构造");abort();}if(!_server){LOG_ERROR("rpc服务器对象未构造");abort();}SpeechServer::ptr speechServer = std::make_shared<SpeechServer>(_registry,_asr_client,_server);return speechServer;}private:Registry::ptr _registry;    //服务注册对象ASRClient::ptr _asr_client;     //语音识别客户端std::shared_ptr<brpc::Server> _server;        //rpc服务器};

三.测试

#include "speech_server.hpp"DEFINE_bool(run_mode, false, "程序的运行模式,false-调试; true-发布;");
DEFINE_string(log_file, "", "发布模式下,用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下,用于指定日志输出等级");DEFINE_string(etcd_host, "127.0.0.1:2379", "注册中心主机地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(instance_name, "/speech_service/instance", "当前实例名称");
DEFINE_string(access_host, "127.0.0.1:10001", "当前实例的外部访问地址");DEFINE_string(app_id, "115608644", "语音平台应用ID");
DEFINE_string(api_key, "GLQvgyNc4AaqhPfnDIMTRlw4", "语音平台API密钥");
DEFINE_string(secret_key, "vTcqDBswZUfAgjTcFA3GJGrc6yEWIO2w", "语音平台加密密钥");DEFINE_int32(rpc_port,10001,"rpc服务器监听端口");   //必须和access_host端口一致int main(int argc,char*argv[])
{google::ParseCommandLineFlags(&argc, &argv, true);lkm_im::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);lkm_im::SpeechServerBuilder ssb;ssb.make_registry(FLAGS_etcd_host,FLAGS_base_service + FLAGS_instance_name,FLAGS_access_host);ssb.make_asr(FLAGS_app_id,FLAGS_api_key,FLAGS_secret_key);ssb.make_brpc(FLAGS_rpc_port);lkm_im::SpeechServer::ptr speechServer = ssb.build();speechServer->start();return 0;
}

http://www.ppmy.cn/news/1528062.html

相关文章

FC优化配置

1.集群扩容CNA时打开bmc 2.给rhel7虚拟机安装tools-需要重启虚拟机 3.FC上创建集群 资源池右击创建集群&#xff08;物理机大于10台&#xff0c;分业务类型创建集群&#xff09; &#xff08;解决集群内主机挂了&#xff0c;动态调整&#xff09; &#xff08;解决集群内个别…

使用集成学习对不同的机器学习方法进行集成

数据入口&#xff1a;数据人才的现场调研 - Heywhale.com 本数据集中有 43 行&#xff0c;19 列&#xff0c;数据集包含如下字段&#xff1a; 首先读取数据&#xff1a; import pandas as pd# 读取Excel文件 data pd.read_excel(数据人才的现场调研.xls)可以输出每一列含有…

国科云域名解析课堂:一个域名可以解析到多个IP地址吗?

在互联网世界中&#xff0c;域名和IP地址是连接用户与网络资源的重要桥梁。每一个简单易记的域名背后都对应着复杂的IP地址&#xff0c;二者通过DNS解析实现对应关系&#xff0c;从而让人们可以通过域名而非IP地址来访问网络资源。那么&#xff0c;域名和IP地址是一一对应的关系…

qt-creator-10.0.2之后版本的jom.exe构建和编译速度慢下来了

1、Qt的IDE一直在升级&#xff0c;qt-creator的新版本下载地址 https://download.qt.io/official_releases/qtcreator/ 2、本人一直用的是qt-creator-10.0.2版本&#xff0c;官网历史仓库可以下载安装包qt-creator-opensource-windows-x86_64-10.0.2.exe https://download.qt…

leetcode 2576.求出最多标记下标

2576.求出最多标记下标 题意&#xff1a; 解析&#xff1a; 数组长为 n n n&#xff0c;因为一次标记两个&#xff0c;所以数组中最多有 ⌊ n 2 ⌋ \lfloor \frac{n}{2}\rfloor ⌊2n​⌋ 对标记。 贪心的考虑&#xff0c;一个数 x 一定优先与满足 y ≥ 2 x y \ge 2x y≥2…

前端面试题——token安全问题处理与大数据列表展示

1.长时间保存token问题 长时间保存Token涉及多个方面的问题&#xff0c;包括安全性、性能、以及Token的管理策略等。以下是对长时间保存Token问题的详细分析&#xff1a; 一、安全性问题 Token泄露风险&#xff1a; Token是用户身份验证的凭证&#xff0c;如果长时间保存且未…

C#中判断socket是否已断开的方法

代码如下&#xff1a; Socket s new Socket(..); if (s.Poll(-1, SelectMode.SelectRead)) {int nRead s.Receive();if (nRead 0){//socket连接已断开} }参考&#xff1a;C#中判断socket是否已断开的方法

ChatGPT的底层逻辑

“一些未知的东西正在做我们不知道的事情。” —— 阿瑟爱丁顿 “为何不尝试制作一个模拟儿童思维的程序呢&#xff1f;” —— 艾伦图灵 “只要是人脑能提出的问题&#xff0c;它就能够得到解决。” —— 库尔特哥德尔 开始 传说中的扫地僧&#xff0c;在现实中极其罕见。 有…