vue实现语音合成功能,Android和wap端

概览

vue项目需要实现小说朗读功能,wap端和Android APP端,wap端能使用的方法在Android端不能使用,需要使用原生Android的方法实现小说朗读功能。

需求分析

1、WAP端实现小说朗读,即语音合成功能实现

2、vue项目打包成Android项目

3、Android端实现小说朗读(语音合成)

4、vue中调用Android原生类

具体实现

1、wap端的不多做讲述,直接上代码
this.synth = window.speechSynthesis;// 监听speaking状态变化this.speakMsg = new SpeechSynthesisUtterance();this.speakMsg.onend = function(){console.log("播放结束")if(document.getElementById(that.intaBook + '')) document.getElementById(that.intaBook + '').style.backgroundColor = ""that.intaBook = that.intaBook + 1//最后一段的时候if(that.intaBook == that.bookContent[0].contentList.length - 2){console.log("播放结束  最后一段的时候 ")that.getTTSNextChapter()if(that.isElementInViewport(document.getElementById('' + that.intaBook))){console.log("播放结束  最后一段的时候 33333 ")//如果在当前窗口展示不进行处理}else{console.log("播放结束  最后一段的时候 44444  ")//不在当前窗口展示,进行跳转下一页处理that.ttsPageFunc(false)}}else if(that.intaBook < that.bookContent[0].contentList.length - 2){console.log("播放结束  2222 ")if(that.isElementInViewport(document.getElementById('' + that.intaBook))){console.log("播放结束 33333 ")//如果在当前窗口展示不进行处理}else{console.log("播放结束 44444  ")//不在当前窗口展示,进行跳转下一页处理that.ttsPageFunc(false)}}else{console.log("播放结束 播放下一章  ")if(that.bookCacheContent.length <= 0){return}that.bookContent[0] = that.bookCacheContent[0]that.intaBook = 0if(document.getElementById(that.intaBook + '')) document.getElementById(that.intaBook + '').style.backgroundColor = "#DCD1B0"that.styleObject = '';that.offsetX = 0;that.bookCurrentPage++;that.currentPaging = 1;that.bookCacheContent = []}that.handleSpeak(that.bookContent[0].contentList[that.intaBook])if(document.getElementById(that.intaBook + '')) document.getElementById(that.intaBook + '').style.backgroundColor = "#DCD1B0"};this.handleSpeak(this.bookContent[0].contentList[this.intaBook])//阅读最后一段落if(this.intaBook == that.bookContent[0].contentList.length - 2){console.log("直接播放  最后一段的时候 ")this.getTTSNextChapter()}

因为是小说朗读功能,代码中有部分是把小说的内容,根据每一段转成一个字符串,整篇文章放到了一个数组中。

其中的主要方法

this.speakMsg = new SpeechSynthesisUtterance();
this.speakMsg.onend = function(){console.log("播放结束")								
};
this.speakMsg.text ="需要朗读的内容";
this.speakMsg.lang = 'zh-CN';
this.speakMsg.volume = '1';
this.speakMsg.rate = 1;
this.speakMsg.pitch = 1;
this.synth.speak(this.speakMsg); //这里实现进行语音合成this.synth.resume();//暂停this.synth.pause();//暂停之后,该方法为继续播放合成的语音this.synth.cancel();//关闭停止
2、vue打包成Android项目,参考:vue项目如何打包Android APK(保姆教程)_vue项目打包安卓-CSDN博客

3、重点来了,vue项目如何实现打包的Android APP进行小说朗读

a、首先可以先搞一个Android项目

b、 使用第三方提供的SDK或者API,例如:科大讯飞,百度,阿里等,使用Android系统自带的API :TextToSpeech,TextToSpeech中的API文档:TextToSpeech  |  Android Developers

c、在AndroidManifest.xml文件中添加权限

<!--外存储写权限,构建语法需要用到此权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!--外存储读权限,构建语法需要用到此权限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

d、Demo中activity中页面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"><EditTextandroid:id="@+id/et_input"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="文本输入" /><Buttonandroid:id="@+id/btn_speech"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="speech" /></LinearLayout>

e、TextToSpeech介绍,相关的方法

1、//使用默认的引擎
TextToSpeech(Context context, TextToSpeech.OnInitListener listener)
//使用指定的引擎
TextToSpeech(Context context, TextToSpeech.OnInitListener listener, String engine)
2.textToSpeech.setLanguage():设置播报的语言
3.textToSpeech.speak():播放
4.textToSpeech.setPitch():设置语调,值越大声音越尖锐,越小声音越低沉
5.textToSpeech.setSpeechRate():设置语速,较低的值会减慢语音(0.5是正常语速的一半),更大的值会加速它(2.0是正常语速的两倍)

f、先初始化textToSeepch,再转换(示例用的默认的TTS引擎),activity中具体的代码

package com.yjwxc.ttsproject;import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import java.util.Locale;public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {private static final String TAG = "MainActivity";private TextToSpeech textToSpeech;private EditText inputEt;private Button speechBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);speechBtn = findViewById(R.id.btn_speech);inputEt = findViewById(R.id.et_input);init();}private void init() {textToSpeech = new TextToSpeech(this, this);//设置语言int result = textToSpeech.setLanguage(Locale.ENGLISH);if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE&& result != TextToSpeech.LANG_AVAILABLE) {Toast.makeText(MainActivity.this, "TTS暂时不支持这种语音的朗读!",Toast.LENGTH_SHORT).show();}//设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规textToSpeech.setPitch(1.0f);//设置语速,1.0为正常语速textToSpeech.setSpeechRate(0.9f);//speech按钮监听事件speechBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//播放textToSpeech.speak(inputEt.getText().toString(),TextToSpeech.QUEUE_ADD, null);}});}@Overridepublic void onInit(int status) {//初始化成功if (status == TextToSpeech.SUCCESS) {Log.d(TAG, "init success");} else {Log.d(TAG, "init fail");}}@Overrideprotected void onDestroy() {super.onDestroy();//中断当前话语textToSpeech.stop();//释放资源textToSpeech.shutdown();}
}

g、面向 Android 11使用文本转语音的应用应先在AndroidManifest.xml声明INTENT_ACTION_TTS_SERVICE

    <queries><intent><action android:name="android.intent.action.TTS_SERVICE" /></intent></queries>

H、可能存在的问题

没有声音或不支持当前设置的语言

需要检查系统是否设置播放引擎,设置—>无障碍 —> 文本转语音中是否安装了播放引擎;系统默认是应该是Pico TTS,不过这个不支持中文;

需要安装第三方播放引擎

com.svox.pico 系统自带不支持中文语音
com.svox.classic 搜svox搜到的,和上面类似不支持中文
com.google.android.tts 谷歌文字转语音引擎,不支持5.0以下系统,大小17.98M
com.iflytek.speechcloud 科大讯飞语音引擎3.0,支持4.0以上系统,大小27.27M
com.iflytek.speechsuite 新版科大讯飞语音引擎,2018年开始新版手机一般会内置,如oppo、vivo、华为
com.baidu.duersdk.opensdk 度秘语音引擎3.0 不支持5.0以下系统,大小11.95M
com.iflytek.tts 科大讯飞语音合成,较老,不支持7.0以上系统,大小9M

现在的Android手机基本上都已经自带了讯飞语音引擎,可以进行中文的语音合成功能。

可以下载Demo进行测试:https://download.csdn.net/download/ahualong1/89921075

4、如何在vue中调用Android中的方法

先上代码

package com.yjwxc.yj;import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.Toast;import java.util.HashMap;
import java.util.Locale;public class JsJavaBridge {private TextToSpeech tts;private Activity activity;private WebView webView;private boolean isPlaying = false;private boolean isPaused = false;private String[] bookDataList = new String[0];private int inta = 0;public JsJavaBridge() {}/*** 初始化tts* @return*/public void androidTtsInit(){Log.e("TEST","初始化 方法 null == tts");tts = new TextToSpeech(this.activity, new TextToSpeech.OnInitListener() {@Overridepublic void onInit(int status) {if(status == tts.SUCCESS){int result = tts.setLanguage(Locale.CHINA);
//                    tts.setOnUtteranceProgressListener(new ClearUtteranceProgressListener());if(result != TextToSpeech.LANG_COUNTRY_AVAILABLE && result != TextToSpeech.LANG_AVAILABLE){showTip("TTS暂时不支持这种语言的朗读");Log.e("TEST","TTS暂时不支持这种语言的朗读");}}Log.e("TEST","status " + status);Log.e("TEST","tts.SUCCESS " + tts.SUCCESS);}});tts.setOnUtteranceProgressListener(new ClearUtteranceProgressListener());
//        if(null == tts){
//
//        }else{
//            Log.e("TEST","初始化 方法 null != tts");
//        }}public JsJavaBridge(MainActivity mainActivity, WebView webView) {this.activity = mainActivity;this.webView = webView;}@JavascriptInterfacepublic void onFinishActivity() {activity.finish();}/*** 开始播放内容* @param stringData*/@JavascriptInterfacepublic void speakStartPlay(String stringData){Log.d("TEST","打印传递过来的数据 " + stringData);tts = new TextToSpeech(this.activity, new TextToSpeech.OnInitListener() {@Overridepublic void onInit(int status) {if (status == TextToSpeech.SUCCESS) {// 设置语言int result = tts.setLanguage(Locale.SIMPLIFIED_CHINESE); // 或者其他所需语言if (result != TextToSpeech.LANG_COUNTRY_AVAILABLE || result != TextToSpeech.LANG_AVAILABLE) {showTip("不支持当前语言");return;}// 开始朗读文本String text = stringData; // 获取小说章节的内容tts.speak(text, TextToSpeech.QUEUE_ADD, null);} else {showTip("初始化失败");}}});
//        if (tts != null) {
//            tts.speak(stringData,TextToSpeech.QUEUE_ADD,null);
//        }else{
//            this.showTip("初始化失败");
//            Log.e("TEST","初始化失败 传递的内容 " + stringData);
//        }}/*** 继续播放*/@JavascriptInterfacepublic void continueSpeakPlay(){if (tts != null) {// 对于旧版本的Android,使用isSpeaking检查并继续播放if (!tts.isSpeaking()) {HashMap<String, String> params = new HashMap<>();params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "resume");tts.speak("", TextToSpeech.QUEUE_ADD, params);}}}/*** 暂停播放* @return*/@JavascriptInterfacepublic void pauseSpeakPlay(){Log.e("TEST","pauseSpeakPlay 暂停播放");if (isPlaying && !isPaused) {Log.e("TEST","isPlaying && !isPaused 暂停播放");tts.stop();isPaused = true;}}/*** 停止播放* @return*/@JavascriptInterfacepublic void stopSpeakPlay(){Log.e("TEST","stopSpeakPlay 停止播放");if (tts != null) {Log.e("TEST","tts != null 停止播放");tts.stop();tts.shutdown();}}private void showTip(final String str) {Toast.makeText(this.activity, str, Toast.LENGTH_SHORT).show();}private class ClearUtteranceProgressListener extends UtteranceProgressListener {@Overridepublic void onStart(String s) {Log.e("TEST","方法 onStart " + s);isPlaying = true;isPaused = false;}@Overridepublic void onDone(String s) {Log.e("TEST","方法 onDone " + s);isPlaying = false;}@Overridepublic void onError(String s) {Log.e("TEST","方法 onError " + s);isPlaying = false;}};}

@JavascriptInterface 是Android JavaScript Interface库(如DroidGap/Cordova)提供的一种注解,它允许Java开发者创建JavaScript可以访问的接口。当一个Java方法被这个注解修饰后,JavaScript可以在运行时通过WebView调用该方法,实现Java与JavaScript之间的交互。这种方式常用于构建混合应用(Hybrid App),即结合了原生组件和Web内容的应用。

 /*** 停止播放* @return*/@JavascriptInterfacepublic void stopSpeakPlay(){Log.e("TEST","stopSpeakPlay 停止播放");if (tts != null) {Log.e("TEST","tts != null 停止播放");tts.stop();tts.shutdown();}}

上面该方法是Android中停止播放的方法,在vue中如何调用,如下:

stopFn() {console.log("打印stop")if(typeof $Android !== 'undefined'){$Android.stopSpeakPlay();}else{if(this.synth){// this.synth.pause();this.synth.cancel();this.synth = null;this.speakMsg = null;this.isSpeaking = "STOP";var that = thisif(document.getElementById(that.intaBook + '')) document.getElementById(that.intaBook + '').style.backgroundColor = ""this.intaBook = 0}}this.musice_box = false;},

$Android.stopSpeakPlay(); 即为调用的Android中定义的方法。

到这里结合上面4个部分的具体实现内容,即可实现vue项目打包成wap和AndroidAPP ,进行小说的语音合成功能(朗读功能)。

如有什么好的建议,希望大佬们能够不吝赐教。拜谢拜谢🙏!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458832.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python实战(二)——房屋价格回归建模

一、任务背景 本章将使用一个经典的Kaggle数据集——House Prices - Advanced Regression Techniques进行回归建模的讲解。这是一个房价数据集&#xff0c;与我们熟知的波士顿房价数据集类似&#xff0c;但是特征数量要更多&#xff0c;数据也要更为复杂一些。下面&#xff0c;…

Linux 命令行查看当前目录的总大小/总磁盘空间/磁盘清理

一、du 查看目录空间大小 &#xff08;一&#xff09; du 命令解析 在Linux命令行可以使用 du 命令来查看当前目录的总大小。du 是 disk usage 的缩写&#xff0c;表示磁盘使用情况。 命令解释&#xff1a;总结每个文件的磁盘使用情况&#xff0c;递归地用于目录。 使用格式…

以通俗易懂的仓库来讲解JVM内存模型

JVM内存模型可以想象成一个大型的仓库&#xff0c;这个仓库被分成了几个不同的区域&#xff0c;每个区域都有特定的用途和规则。下面我们用一个仓库的比喻来介绍JVM内存模型&#xff1a; 仓库大门&#xff08;JVM启动&#xff09;&#xff1a; 当JVM启动时&#xff0c;就像打开…

自动化抖音点赞取消脚本批量处理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

多个立方体盒子组成

效果&#xff1a; 知识了解&#xff1a; 在同一水平上&#xff0c;盒子经纬度计算&#xff1a;经度有误差&#xff0c;纬度没有误差 纬度计算&#xff1a;lat50/111320 约等于0.000449 经度计算&#xff1a;lon50/111320*cos(纬度) 约等于0.000519 一个立方体&#xff1a; // 添…

CentOS进入单用户模式进行密码重置

一、单用户模式介绍 单用户模式是一种特殊的启动模式&#xff0c;主要用于系统维护和故障排除。在单用户模式下&#xff0c;系统以最小化的状态启动&#xff0c;只有最基本的系统服务会被加载&#xff0c;通常只有root用户可以登录。这种模式提供了对系统的完全控制&#xff0…

模型训练识别手写数字(一)

一、模型训练数据集 1. 导入所需库 import numpy as np from sklearn.datasets import fetch_openmlnumpy 是用于数值计算的库。 fetch_openml 是用于从 OpenML 下载数据集的函数。 2. 获取 MNIST 数据集 X, y fetch_openml(mnist_784, version1, return_X_yTrue)fetch_ope…

Spring Boot与Flyway实现自动化数据库版本控制

一、为什么使用Flyway 最简单的一个项目是一个软件连接到一个数据库&#xff0c;但是大多数项目中我们不仅要处理我们开发环境的副本&#xff0c;还需要处理其他很多副本。例如&#xff1a;开发环境、测试环境、生产环境。想到数据库管理&#xff0c;我们立刻就能想到一系列问…

Ovis原理解读: 多模态大语言模型的结构嵌入对齐

论文&#xff1a;https://arxiv.org/pdf/2405.20797 github:https://github.com/AIDC-AI/Ovis 在多模态大语言模型 (MLLM) 中&#xff0c;不同的嵌入策略有显著的区别。以下是使用基于连接器的方法与 Ovis 方法的比较&#xff1a; 基于连接器的方法-优缺点(connector-based …

斜杠往哪斜、路径绝对还是相对,终端目录切换不再迷茫

目录 路径表示绝对路径相对路径两者区别 路径中斜杠的用法正反斜杠对比表一个常见的问题 终端切换目录常用cd指令同一盘符内跨盘符 路径表示 在计算机文件系统中&#xff0c;路径是用来指定文件或目录位置的一种方式。路径可以是绝对路径或相对路径&#xff1a; 绝对路径 绝…

cmake 编译 vtk

1. 下载 VTK 源码 vtk 源码&#xff0c;点击&#xff1a;官网下载 在官网选择合适的版本下载&#xff0c;这里下载的是 vtk 8.2.0 版本 2. 下载 CMake CMake 工具&#xff0c;点击&#xff1a;镜像下载 下载版本比较新的 CMake 版本&#xff0c;这里使用的是 CMake 3.29.2 版…

在不支持AVX的linux上使用PaddleOCR

背景 公司的虚拟机CPU居然不支持avx, 默认的paddlepaddle的cpu版本又需要有支持avx才行,还想用PaddleOCR有啥办法呢? 是否支持avx lscpu | grep avx 支持avx的话,会显示相关信息 如果不支持的话,python运行时导入paddle会报错 怎么办呢 方案一 找公司it,看看虚拟机为什么…

C++基础:constexpr,类型转换和选择语句

constexpr 提到constexpr&#xff0c;我们会发现它和const类比 常和const类比constexpr符号常量必须给定一个在编译时已知的值&#xff0c; 若某个变量初始化时的值在编译时未知&#xff0c;但初始化后绝不变。 #include<iostream> #include<vector> #include&l…

【机器学习基础】激活函数

激活函数 1. Sigmoid函数2. Tanh&#xff08;双曲正切&#xff09;函数3. ReLU函数4. Leaky ReLU函数 1. Sigmoid函数 观察导数图像在我们深度学习里面&#xff0c;导数是为了求参数W和B&#xff0c;W和B是在我们模型model确定之后&#xff0c;找出一组最优的W和B&#xff0c;使…

Go使用exec.Command() 执行脚本时出现:file or directory not found

使用 Go 提供的 exec.Command() 执行脚本时出现了未找到脚本的 bug&#xff0c;三个排查思路 &#xff1a; exec.Command(execName, args…) 脚本名字不允许相对路径 exec.Command(execName, args…) execName 只能有脚本名&#xff0c;不允许出现参数 如果你是使用 Windows …

Python爬虫:商品详情的“八卦记者”

亲爱的代码侦探们&#xff0c;今天咱们不聊那些让人头秃的bug&#xff0c;也不谈那些让人眼花的架构图。咱们来聊聊那些在代码世界里挖掘商品秘密的“八卦记者”——Python爬虫。 Python爬虫&#xff1a;商品详情的“八卦记者” 想象一下&#xff0c;你在代码的世界里&#xf…

[笔记] ffmpeg docker编译环境搭建

文章目录 环境参考dockerfile 文件步骤常见问题docker 构建镜像出现 INTERNAL_ERROR 失败? 总结 环境 docker 环境 系统centos 7.9 (无所谓了 你用docker编译就无所谓系统了) ffmpeg3.3 参考 https://blog.csdn.net/jiedichina/article/details/71438112 dockerfile 文件 …

《等保测评新视角:安全与发展的双赢之道》

在数字化转型的浪潮中&#xff0c;企业面临的不仅是技术革新的挑战&#xff0c;更有信息安全的严峻考验。等保测评&#xff0c;作为国家网络安全等级保护的一项重要措施&#xff0c;不仅为企业的安全护航&#xff0c;更成为推动企业高质量发展的新引擎。本文将从全新的视角&…

如何将markdown文件转换为pdf

最近笔者在用vscode写markdown&#xff0c;但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先&#xff0c;需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标&#xff0c;点击&#xff0c;vscode右半面就会显示…

【论文阅读】PGAN

1. WHY 问题 图像超分辨率一直是一个热门研究课题&#xff0c;具有重要的应用价值。基于生成对抗网络GAN的单幅图像超分辨率方法显示重建图像与人类视觉特征更一致。因此&#xff0c;基于 GAN 的网络优化已成为图像超分辨率的主流。然而&#xff0c;一些最新研究表明&#xf…