【Android App】实现在线语音合成功能(使用云知声平台和WebSocket 超详细 附源码)

简介: 【Android App】实现在线语音合成功能(使用云知声平台和WebSocket 超详细 附源码)

需要源码和Jar包请点赞关注收藏后评论区留下QQ~~~

一、在线语音合成

虽然国产智能机大多集成了中文语音引擎,但是系统自带的语音工具无法满足商用要求,功能单一,所以势必引入第三方的语音引擎,依靠第三方提供的开发包统一支撑语音的交互操作

此处选用云知声引擎,对新生免费并且语音处理采用公开的WebSocket接口,无须引入额外的语音SDK,进入云知声网址后,在右上角找到AI开放平台,然后注册进入控制台创建应用即可

云知声官网

创建好后如下 要记住key和secret  后面要用v

云知声采用WebSocket接口交互,故而不管是语音合成还是语音识别,都需要定义WebSocket客户端的处理任务,云知声使用JSON字符串封装报文合成后的音频数据通过字节数组传回,具体合成过程如下

1:定义WebSocket客户端的语音合成任务

实现以下几个功能

1:在请求报文中填写原始文本 音频格式和采样率等合成参数 再把JSON字符串传给WebSocket服务器

2:服务器分批返回字节数组形式的音频流 客户端需要将这些数据依次追加到存储卡中

3:在合成过程中,服务器还会数次返回JSON格式的应答报文 可能不止一个,只有报文中的end字段为true时才表示合成结束

2:把语音任务关联到WebSocket服务器

此时要拼接完整的URL地址,包含之前在云知声平台的appkey和appsecret,填在SoundUtil这个类中

3:创建并启动语音合成任务

效果如下

合成结束后效果如下 点击右上角的播放可以收听由文字转换的语音

部分代码如下

需要源码请点赞关注收藏后评论区留下QQ~~~

Java类

package com.example.voice;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.example.voice.constant.SoundConstant;
import com.example.voice.task.TtsClientEndpoint;
import com.example.voice.util.DateUtil;
import com.example.voice.util.SoundUtil;
public class VoiceComposeActivity extends AppCompatActivity {
    private final static String TAG = "VoiceComposeActivity";
    private TextView tv_option; // 声明一个文本视图对象
    private EditText et_compose_text; // 声明一个编辑框对象
    private TextView tv_result; // 声明一个文本视图对象
    private String mComposeFilePath; // 合成语音的文件路径
    private MediaPlayer mMediaPlayer = new MediaPlayer(); // 媒体播放器
    private boolean isPlaying = false; // 是否正在播音
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_voice_compose);
        findViewById(R.id.iv_back).setOnClickListener(v -> finish());
        TextView tv_title = findViewById(R.id.tv_title);
        tv_title.setText("在线语音合成");
        tv_option = findViewById(R.id.tv_option);
        tv_option.setText("开始播放语音");
        tv_option.setVisibility(View.GONE);
        et_compose_text = findViewById(R.id.et_compose_text);
        tv_result = findViewById(R.id.tv_result);
        findViewById(R.id.btn_compose_voice).setOnClickListener(v -> {
            String text = et_compose_text.getText().toString();
            if (TextUtils.isEmpty(text)) {
                Toast.makeText(this, "请先输入待朗读的一段话", Toast.LENGTH_SHORT).show();
                return;
            }
            new Thread(() -> onlineCompose(text)).start(); // 启动在线合成语音的线程
        });
        tv_option.setOnClickListener(v -> {
            if (!isPlaying) { // 未在播音
                startPlay(); // 开始播音
            } else { // 正在播音
                stopPlay(); // 停止播音
            }
        });
    }
    // 在线合成语音
    private void onlineCompose(String text) {
        mComposeFilePath = String.format("%s/%s.mp3",
                getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(),
                DateUtil.getNowDateTime());
        // 创建语音合成任务,并指定语音监听器
        TtsClientEndpoint task = new TtsClientEndpoint(this, mComposeFilePath, text, arg -> {
            if (Boolean.TRUE.equals(arg[0])) {
                Toast.makeText(this, "语音合成结束", Toast.LENGTH_SHORT).show();
                tv_result.setText("音频文件位于"+arg[2]);
                tv_option.setVisibility(View.VISIBLE);
            }
        });
        SoundUtil.startSoundTask(SoundConstant.URL_TTS, task); // 启动语音合成任务
    }
    // 开始播音
    private void startPlay() {
        isPlaying = !isPlaying;
        tv_option.setText("停止播放语音");
        mMediaPlayer.reset(); // 重置媒体播放器
        // 设置媒体播放器的完成监听器
        mMediaPlayer.setOnCompletionListener(mp -> stopPlay());
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); // 设置音频流的类型为音乐
        try {
            mMediaPlayer.setDataSource(mComposeFilePath); // 设置媒体数据的文件路径
            mMediaPlayer.prepare(); // 媒体播放器准备就绪
            mMediaPlayer.start(); // 媒体播放器开始播放
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 停止播音
    private void stopPlay() {
        tv_option.setText("开始播放语音");
        if (mMediaPlayer.isPlaying() || isPlaying) { // 如果正在播放
            isPlaying = !isPlaying;
            mMediaPlayer.stop(); // 停止播放
            Toast.makeText(this, "语音播放结束", Toast.LENGTH_LONG).show();
        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        stopPlay(); // 停止播音
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMediaPlayer.release(); // 释放媒体播放器
    }
}

SoundUtil类

package com.example.voice.util;
import android.util.Log;
import com.example.voice.constant.SoundConstant;
import java.net.URI;
import java.security.MessageDigest;
import javax.websocket.ContainerProvider;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
public class SoundUtil {
    private final static String TAG = "SoundUtil";
    // 启动语音处理任务(语音识别或者语音合成)
    public static void startSoundTask(String url, Object task) {
        long time = System.currentTimeMillis();
        StringBuilder paramBuilder = new StringBuilder();
        // 填写该应用在开放平台上申请的密钥和密码
        paramBuilder.append(SoundConstant.APP_KEY).append(time).
                append(SoundConstant.APP_SECRET);
        String sign = getSHA256Digest(paramBuilder.toString());
        StringBuilder param = new StringBuilder();
        param.append("appkey=azkk2kwv5f22m5z4iebchxsetodz3y677chtzniz").append(SoundConstant.APP_KEY).append("&")
                .append("time=").append(time).append("&")
                .append("sign=").append(sign).append("&").append("appsecret=6d6f4426e005e6b7f9a7fee2a9fdda44");
        String fullUrl = url + param.toString();
        Log.d(TAG, "fullUrl="+fullUrl);
        // 获取WebSocket容器
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        try {
            URI uri = new URI(fullUrl); // 创建一个URI对象
            // 连接WebSocket服务器,并关联语音处理任务获得连接会话
            Session session = container.connectToServer(task, uri);
            // 设置文本消息的最大缓存大小
            session.setMaxTextMessageBufferSize(1024 * 1024 * 10);
            // 设置二进制消息的最大缓存大小
            session.setMaxBinaryMessageBufferSize(1024 * 1024 * 10);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 获得SHA摘要
    private static String getSHA256Digest(String data) {
        String digest = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] bytes = md.digest(data.getBytes("UTF-8"));
            digest = byte2hex(bytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return digest;
    }
    // 二进制转十六进制字符串
    private static String byte2hex(byte[] bytes) {
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex.toUpperCase());
        }
        return sign.toString();
    }
}

创作不易 觉得有帮助请 点赞关注收藏~~~

相关文章
|
2天前
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
34 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
4天前
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
29 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
4天前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
23 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
9天前
|
开发框架 缓存 搜索推荐
PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
嗨,大家好,我是小华同学。PiliPala 是一个基于 Flutter 开发的 BiliBili 第三方客户端,提供流畅、个性化的使用体验。核心功能包括视频浏览与推荐、用户互动、丰富的播放设置、多维度搜索和个性化主题等。相比官方客户端,PiliPala 功能更丰富、性能更优、界面更美观。
60 14
|
11天前
|
Web App开发 前端开发 安全
语音交友app系统源码功能及技术研发流程剖析
语音交友App核心功能包括语音聊天(一对一、群聊、语音消息)、语音房间(直播、主题房、管理)、社交互动(好友、关注、打赏)、内容发现、音效美化、通知提醒及安全隐私等。开发流程涵盖需求分析、技术选型(前端、后端、数据库、实时通信)、UI/UX设计、前后端开发、实时通信集成、音效处理、测试优化、部署上线及运营维护,确保稳定高效运行并持续优化用户体验。
|
1月前
|
移动开发 监控 小程序
TP6+Uni-app框架开发,2025年最新圈子系统功能展示,圈子app流量主模式
圈子系统基于TP6+Uni-app框架开发,支持多端账号同步并可快速生成APP。它适用于行业、地方、社交、游戏、兴趣等多种圈子场景,提供广告展示、商品销售、推广结算、交易佣金、入驻费用、会员增值及线上线下活动等多元盈利模式,帮助商户精准定位用户,实现流量变现和业务增长。
|
1月前
|
移动开发 开发框架 小程序
轻松搭建婚恋交友系统源码,H5/小程序/APP自动适配,智能匹配恋爱交友平台快速落地
婚恋交友系统涵盖在线交友、线下活动、专业服务、社交娱乐等,满足用户多样化需求。系统设计简洁易用,提供实名认证、多注册方式及安全保护,确保用户隐私和数据安全。功能丰富,支持图文展示、筛选匹配、聊天互动、虚拟礼物等,提升互动趣味性。平台可分类管理用户、审核信息、智能推荐,优化用户体验。基于TP6+Uni-app框架,实现跨平台同步,支持二次开发,适应不同市场需求。 [了解更多](https://gitee.com/multi-customer-software/jy)
|
1月前
|
消息中间件 监控 小程序
电竞陪玩系统架构优化设计,陪玩app如何提升系统稳定性,陪玩小程序平台的测试与监控
电竞陪玩系统架构涵盖前端(React/Vue)、后端(Spring Boot/php)、数据库(MySQL/MongoDB)、实时通信(WebSocket)及其他组件(Redis、RabbitMQ、Nginx)。通过模块化设计、微服务架构和云计算技术优化,提升系统性能与可靠性。同时,加强全面测试、实时监控及故障管理,确保系统稳定运行。
|
2月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
90 11
|
2月前
|
安全 定位技术 API
婚恋交友系统匹配功能 婚恋相亲软件实现定位 语音社交app红娘系统集成高德地图SDK
在婚恋交友系统中集成高德地图,可实现用户定位、导航及基于地理位置的匹配推荐等功能。具体步骤如下: 1. **注册账号**:访问高德开放平台,注册并创建应用。 2. **获取API Key**:记录API Key以备开发使用。 3. **集成SDK**:根据开发平台下载并集成高德地图SDK。 4. **配置功能**:实现定位、导航及基于位置的匹配推荐。 5. **注意事项**:保护用户隐私,确保API Key安全,定期更新地图数据,添加错误处理机制。 6. **测试优化**:完成集成后进行全面测试,并根据反馈优化功能。 通过以上步骤,提升用户体验,提供更便捷的服务。

热门文章

最新文章

  • 1
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    34
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 4
    【Azure Function】Function App门户上的Test/Run返回错误:Failed to fetch
    31
  • 5
    陪玩APP推送配置:陪玩系统手机锁屏收不到推送?可能是这些原因!解决方案来了!
    34
  • 6
    小游戏源码开发之可跨app软件对接是如何设计和开发的
    33
  • 7
    原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力
    135
  • 8
    PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
    60
  • 9
    语音app系统软件源码开发搭建新手启蒙篇
    44
  • 10
    MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
    884