# huaweicloud-CodeArts-TextToSpeechSample-cpp **Repository Path**: HuaweiCloudDeveloper/huaweicloud-code-arts-text-to-speech-sample-cpp ## Basic Information - **Project Name**: huaweicloud-CodeArts-TextToSpeechSample-cpp - **Description**: 基于华为云CodeArts IDE for C/C++开发的应用示例,通过结合华为云API,实现文字合成语音应用,按照文本要求输出专属场景音色音频 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master-dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-08-29 - **Last Updated**: 2025-06-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 1、介绍 CodeArts IDE面向华为云开发者提供的智能化可扩展桌面集成开发环境(IDE),结合华为云行业和产业开发套件,实现极致的一站式用云和开发体验。 - **连接华为云,用云更畅快**:内置华为云帐号支持和华为云API开发套件,支持一键登录后快速用云,浏览、查找、引用和调试云服务API,并有样例代码支持 - **编码新体验,开发更高效**:内置华为自研C/C++语言开发支持,提供全新的工程加载、语法着色、符号解析、编码重构和运行调试等开发体验,提升开发效率 - **能力可扩展,生态更开放**:支持基于插件的能力扩展,开放的插件标准,开源的插件框架,开放的插件市场,形成更加开放的生态系统 - **界面可裁剪,体验更优质**:支持基于组建的界面剪裁,在精简模式下形成专用工具的优质体验,又可以在需要时升级为全模式的全量IDE工具 **CodeArts IDE for C/C++**:基于C/C++语言开发CMake工程,并通过CodeArts IDE完成从工程创建、代码编写、运行调试到发布测试的全过程。基于插件扩展可以将个人开发者作业流集成其中,实现从需求到提交的全部过程,更可在业务中集成华为云所提供的的诸多能力,提升应用交付效率。 ### 您将学到什么? 本实验将指导开发者通过CodeArts IDE for C/C++平台,在本地桌面实现华为云应用的快速开发。通过本实验您将体验到: - **在CodeArts IDE for C/C++上进行基于CMake项目的本地编译构建** - **在CodeArts IDE上的调试和运行** - **结合华为云API接口,实现一个文字合成语音的应用,最终按照文本要求输出专属场景音色音频** ## 2、前置条件 - 注册华为云账号并完成实名认证 - 下载并安装[CodeArts IDE for C/C++](https://devcloud.cn-north-4.huaweicloud.com/codeartside/home)到本地 - 使用前需获取账号的AK、SK、Project_Id和用户请求Token,获取指南详见步骤3。 - 注册Gitee账号,下载源代码并解压至本地 ## 3、实验配置 配置前打开CodeArts IDE,点击“文件”,“打开文件夹”,找到代码包所在目录并打开。 ![img.png](asserts/openFile.png) ### 3.1 配置AK/SK 访问语音合成API需要AK/SK,AK/SK在华为云[“控制台”](https://console.huaweicloud.com/console/?agencyId=0b1f24c5a780f4711f64c00993d09b37®ion=cn-north-4&locale=zh-cn#/home)的右上方用户名下拉菜单中,点击“我的凭证”->“访问密钥”页面上创建,具体可[参考文档](https://support.huaweicloud.com/iam_faq/iam_01_0618.html)。 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; 本示例以ak和sk保存在环境变量中来实现身份验证为例,运行本示例前请先在本地环境中设置环境变量HUAWEICLOUD_SDK_AK和HUAWEICLOUD_SDK_SK。 ```cpp static const std::string ACCESS_KEY = std::getenv("HUAWEICLOUD_SDK_AK"); static const std::string SECRET_KEY = std::getenv("HUAWEICLOUD_SDK_SK"); ``` ### 3.2 配置语音合成API的请求URL 点击IDE左边栏的“华为云API”,找到语音合成接口RunTts, ![img.png](asserts/huaweicloud-api.png) 复制文档中的URL。 ![img.png](asserts/RunTts.png) 示例URL:https://sis-ext.cn-east-3.myhuaweicloud.com/v1/{project_id}/tts 其中cn-east-3为区域,project_id是项目编号,需替换为用户自己的,获取方法可参见从[控制台获取项目ID](https://support.huaweicloud.com/api-sis/sis_03_0008.html),注意,URL中对应的项目ID需对应所属区域,如华北-北京四(cn-north-4)。 ![img.png](asserts/project_id.png) 将配置好的URL和所属区域替换到源代码code目录下的MyWidget.cpp中的TTS_REQUEST_URL和REGION。 ```cpp static const QString REGION = "" static const QString TTS_REQUEST_URL = ""; ``` ### 3.3 配置获取用户Token的URL Token认证就是在调用API的时候将Token加到请求消息头,从而通过身份认证,获得操作API的权限。华为云提供了通过URL获取token的方式,可参考[文档](https://support.huaweicloud.com/sis_faq/sis_04_0077.html )获取请求token的URL ![img.png](asserts/getToken.png) 其中的区域字段(如cn-north-4)需和语音合成API的请求URL区域字段相同。 源代码已内置了获取token的方法,只需替换源代码code目录下的TOKEN_REQUEST_URL即可自动获取token。 ```cpp static const QString TOKEN_REQUEST_URL = ""; ``` ### 3.4 配置合成语音音色 华为云语音合成API提供了多种场景下的语音音色选择,默认为"chinese_xiaoyan_common",如需更改请替换code目录下MyWidget.cpp文件中LANGUAGE_SPEAKER_DOMAIN的字段,具体可参考华为云API语音合成文档。 ```cpp static const QString LANGUAGE_SPEAKER_DOMAIN = "chinese_xiaoyan_common"; ``` ![img.png](asserts/language_property.png) ## 4、编译构建与运行调试 ### 4.1 编译构建 代码配置完成后,在IDE页面的右上角,点击构建项目按钮,或点击页面上方的“构建”->“构建项目”,CMake构建类型选择Debug。然后在弹窗中选择all META,当编译构建成功后,日志打印finished,并显示成功的图示。 ![img.png](asserts/build.png) ![img.png](asserts/build_success.png) ### 4.2 调试和运行 构建成功后,在页面的右上角选择调试的目标,然后进行调试和运行。 ![img.png](asserts/run.png) 更多信息请参考CodeArts IDE [用户指南](https://support.huaweicloud.com/usermanual-codeartside/codeartside_01_0048.html) ## 5、关键代码片段 ```cpp // 创建语音合成应用及可视化界面 void MyWidget::TextToSpeech() { m_playIconPath = QApplication::applicationDirPath() + "/asserts/play.png"; m_pauseIconPath = QApplication::applicationDirPath() + "/asserts/pause.png"; if (m_textInputEdit == nullptr) { m_textInputEdit = new QTextEdit(this); m_textInputEdit->setPlaceholderText("Enter Text (no more than 500 characters)"); m_textInputEdit->setFixedHeight(300); m_textInputEdit->setFixedWidth(780); } m_layout->addWidget(m_textInputEdit); QPushButton *convertButton = new QPushButton("Click to Convert", this); m_layout->addWidget(convertButton); m_playButton = new QPushButton(this); m_playButton->setFlat(true); m_playButton->setIcon(QPixmap(m_pauseIconPath)); m_playButton->setIconSize(QSize(100, 100)); m_layout->addWidget(m_playButton); m_layout->setAlignment(Qt::AlignCenter); m_widget->setLayout(m_layout); m_textInputEdit->show(); m_textInputEdit->setFocus(); connect(convertButton, &QPushButton::clicked, this, &MyWidget::ShowTextToSpeechResult); connect(m_player, &QMediaPlayer::stateChanged, this, &MyWidget::OnPlayerStateChanged); connect(m_playButton, &QPushButton::clicked, this, &MyWidget::OnPlayButtonClicked); return; } // 解码base64格式的音频数据并生成音频文件播放 void MyWidget::ShowTextToSpeechResult() { // 获取语音合成API返回的响应Json数据 QJsonDocument textToSpeechData = GetTextToSpeechResult(); if (textToSpeechData.isNull()) { return; } QString encodedData = textToSpeechData.object()["result"].toObject()["data"].toString(); QByteArray encodedDataBytes = encodedData.toLatin1(); QByteArray decodedDataBytes = QByteArray::fromBase64(encodedDataBytes); // 生成.wav音频文件 m_audioPath = QApplication::applicationDirPath() + "/asserts/audio.wav"; QFile file(m_audioPath); if (file.exists()) { file.remove(); } if (!file.open(QIODevice::WriteOnly)) { qDebug() << "Failed to open file for writing"; return; } file.write(decodedDataBytes); file.close(); isSetAudio = true; return; } // 生成语音合成API调用的http请求并发送,获取返回的响应数据 QJsonDocument MyWidget::GetTextToSpeechResult() { QNetworkAccessManager manager; QNetworkRequest request; request.setUrl(QUrl(TTS_REQUEST_URL)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); m_token = GetToken(); request.setRawHeader("X-Auth-Token", m_token); QJsonObject requestBody; QJsonObject configSpeech; QString inputText = m_textInputEdit->toPlainText(); requestBody["text"] = inputText; configSpeech["property"] = LANGUAGE_SPEAKER_DOMAIN; requestBody["config"] = configSpeech; QJsonDocument jsonDocument(requestBody); QByteArray requestData = jsonDocument.toJson(); QNetworkReply *reply = manager.post(request, requestData); QEventLoop loop; QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); QJsonDocument jsonResponse; if (reply->error() == QNetworkReply::NoError) { QByteArray responseData = reply->readAll(); jsonResponse = QJsonDocument::fromJson(responseData); } else { qDebug() << "Error:" << reply->errorString(); } reply->deleteLater(); return jsonResponse; } ``` ## 6、运行结果 输入文本,点击“Click to Convert”按钮,生成语音文件,语音文件默认存储在.exe程序目录下的asserts文件夹中,点击播放按钮播放合成语音。 运行结果如下图: ![img.png](asserts/result.png) ## 7、参考 本示例的代码工程仅用于简单演示,实际开发过程中应严格遵循开发指南。访问以下链接可以获取详细信息:[开发指南](https://support.huaweicloud.com/usermanual-codeartside/codeartside_01_0042.html) ## 8、修订记录 | 发布日期 | 文档版本 | 修订说明 | | ------------ | ------------ | ------------ | | 2023-09-07 | 1.0 | 文档首次发布 |