听不懂《创4》外籍小哥哥在说啥?是时候写个翻译器辅助女友追星了
过年回来,程序员阿强变了。
阿强,一个向来对外宣称只关心代码的男人,近期突然加入了办公室自发组织的追星兴趣小组,热情高涨的探讨起“饭圈文学”,对新生代的明星爱豆,虽不能做到如数家珍,却透露出十足兴味,特别是在应援话术和常见追星场景上,阿强尤为认真,甚至做起了笔记……
轮番追问,才发现这个成熟coder细腻又体贴的内心。
原来,随着选秀节目《创4》的“突如其来”,阿强的女友阿珍,又粉上了新一代年轻爱豆,不同的是,这次粉的还是几位来自日、韩、俄、泰、乌克兰的国际选手。语言不通的阿珍,一如既往地淹没在饭圈女孩的茫茫人海中,粉得轰轰烈烈又平平无奇。
阿强深知,饭圈内卷丝毫不比开发圈轻松。会写彩虹文的比不上会p美图的,会设计灯牌的较之扛长焦的又稍显逊色……
想让女友的追星体验更佳,甚至脱颖而出,阿强很快找到了突破口——为女友开发一个追星翻译神器。
说干就干,阿强迅速构思出这个翻译器的重点功能,包含但不限于:
1、支持文本和语音输入;
2、支持多国语言;
3、译文支持生成语音……
阿强想,该翻译器不仅适用于追星场景,日后出国旅游、社交交流、语言学习也能扛起大任。
实现原理
借助华为机器学习能力,任何人都可以简单便捷的使用原本复杂的机器学习能力,助力开发者更快更好地开发各类AI应用。
开发准备
1、配置华为Maven仓地址
2、添加编译SDK依赖
打开应用级的“build.gradle”文件
dependencies { ... // 引入实时语音识别服务插件 implementation 'com.huawei.hms:ml-computer-voice-asr-plugin:2.0.3.300' // 引入文本翻译服务SDK implementation 'com.huawei.hms:ml-computer-translate:2.0.4.300' // 引入文本翻译算法包 implementation 'com.huawei.hms:ml-computer-translate-model:2.0.4.300' // 引入语音合成服务SDK implementation 'com.huawei.hms:ml-computer-voice-tts:2.0.4.300' // 引入离线语音合成bee语音包 implementation 'com.huawei.hms:ml-computer-voice-tts-model-bee:2.0.4.300' }
上述步骤可以参考开发者网站中的应用开发介绍:https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides-V5/config-agc-0000001050990353-V5
3、在AndroidManifest.xml中添加权限
打开main中的AndroidManifest.xml文件,在<application 前添加所需的权限
<uses-permission android:name="android.permission.INTERNET" /> <!-- 访问网络 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 获取网络状态 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 升级算法版本 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!-- 获取Wi-Fi状态 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /><!-- 通过录音机获取声音 -->
开发步骤
页面设计
参考activity_main.xml布局文件,设计专属自己好用的页面app页面
点击“开始识别”按钮,加载ASR模块,识别用户说话的内容。
点击“合成语音”,加载TTS模块,把翻译后的内容直接朗读出来。
功能开发
1. 使用实时语音识别服务插件,快速集成ASR能力
public void startAsr(View view) { // 通过intent进行识别设置。 Intent intent = new Intent(this, MLAsrCaptureActivity.class) // 设置识别语言为英语,若不设置,则默认识别英语。支持设置:"zh-CN":中文;"en-US":英语;"fr-FR":法语;"es-ES":西班牙语;"de-DE":德语;"it-IT":意大利语。 .putExtra(MLAsrCaptureConstants.LANGUAGE, Constants.ASR_SOURCE[spinnerInput.getSelectedItemPosition()]) // 设置拾音界面是否显示识别结果,MLAsrCaptureConstants.FEATURE_ALLINONE为不显示,MLAsrCaptureConstants.FEATURE_WORDFLUX为显示。 .putExtra(MLAsrCaptureConstants.FEATURE, MLAsrCaptureConstants.FEATURE_WORDFLUX); // 100表示当前Activity和拾音界面Activity之间的请求码,通过该码可以在当前Activity中获取拾音界面的处理结果。 startActivityForResult(intent, 100); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); String text; // 100是第2步中定义的当前Activity和拾音界面Activity之间的请求码。 if (requestCode == 100) { switch (resultCode) { // 返回值为MLAsrCaptureConstants.ASR_SUCCESS表示识别成功。 case MLAsrCaptureConstants.ASR_SUCCESS: if (data != null) { Bundle bundle = data.getExtras(); // 获取语音识别得到的文本信息。 if (bundle != null && bundle.containsKey(MLAsrCaptureConstants.ASR_RESULT)) { text = bundle.getString(MLAsrCaptureConstants.ASR_RESULT); // 识别得到的文本信息处理。 textViewInput.setText(text); Translation.run(this, textViewOutput, spinnerInput.getSelectedItemPosition(), spinnerOutput.getSelectedItemPosition(), text); } } break; ... } } }
2. 新建Translation类,用于调用文本翻译的能力
首先暴露公共方法,根据参数判断使用在线翻译或者离线翻译
public static void run(Activity activity, TextView textView, int sourcePosition, int targetPosition, String sourceText) { Log.d(TAG, Constants.TRANSLATE[sourcePosition] + ", " + Constants.TRANSLATE[targetPosition] + ", " + sourceText); if (isOffline) { onDeviceTranslation(activity, textView, sourcePosition, targetPosition, sourceText); } else { realTimeTranslation(textView, sourcePosition, targetPosition, sourceText); } }
接着分别引入在线和离线翻译的具体方法
private static void realTimeTranslation(final TextView textView, int sourcePosition, final int targetPosition, String sourceText) { Log.d(TAG, "realTimeTranslation"); ... } private static void onDeviceTranslation(final Activity activity, final TextView textView, final int sourcePosition, final int targetPosition, final String sourceText) { Set<String> result = MLTranslateLanguage.syncGetLocalAllLanguages(); Log.d(TAG, "本地离线翻译支持的语种: " + Arrays.toString(result.toArray())); ... }
新建TTS类,用于调用语音合成的能力
同Translation一样,首先暴露公共方法,根据参数判断使用在线语音合成或者离线语音合成
public static void run(Activity activity, int targetPosition, String sourceText) { Log.d(TAG, sourceText); if (isNotAuto || sourceText.isEmpty()) { return; } if (isOffline) { if (0 == targetPosition) { Toast.makeText(activity, "暂不支持离线中文发音", Toast.LENGTH_SHORT).show(); return; } offlineTts(activity, Constants.TTS_TARGET[targetPosition], Constants.TTS_TARGET_SPEAKER_OFFLINE[targetPosition], sourceText); } else { onlineTts(Constants.TTS_TARGET[targetPosition], Constants.TTS_TARGET_SPEAKER[targetPosition], sourceText); } }
接着,分别引入在线和离线语音合成的具体实现
private static void onlineTts(String language, String person, String sourceText) { Log.d(TAG, language + ", " + person + ", " + sourceText); ... } private static void offlineTts(final Activity activity, String language, final String person, final String sourceText) { // 使用自定义参数配置创建语音合成引擎。 // 发音人名称请参见“音色试听”章节。 final MLTtsConfig mlTtsConfig = new MLTtsConfig().setLanguage(language) .setPerson(person) // 设置语音合成的模式为离线模式,不设置默认为在线模式。 .setSynthesizeMode(MLTtsConstants.TTS_OFFLINE_MODE); ... }
添加自定义语言支持
1、分别在多语言的values/arrays.xml文件中,添加需要的语言(比如Italian)
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="languages"> ... <item>Spanish</item> <!--add next line--> <item>Italian</item> </string-array> </resources>
2、在Language枚举类中,添加ASR/Translate/TTS模块的语言代码
public enum Language { ... ES(MLAsrConstants.LAN_ES_ES, "es", MLTtsConstants.TTS_LAN_ES_ES, MLTtsConstants.TTS_SPEAKER_FEMALE_ES, MLTtsConstants.TTS_SPEAKER_OFFLINE_ES_ES_FEMALE_BEE), // add next line IT("it-IT", "it", MLTtsConstants.TTS_LAN_IT_IT, MLTtsConstants.TTS_SPEAKER_FEMALE_IT, MLTtsConstants.TTS_SPEAKER_OFFLINE_IT_IT_FEMALE_BEE); ...
从前往后各字段的含义分别是ASR输入语言,翻译目标语言,TTS输出语言,TTS输出语言音色。
完成以上两步,就可以在App中使用意大利语了。
最终效果
阿强相信,凭借此神器,女友阿珍必定能克服了语言障碍,于千篇一律的彩虹应援词中,使用爱豆母语发送问候,瞬间突出!在公演现场和见面会,用爱豆熟悉的语言呼唤他,收获了身处异国的爱豆的注意!甚至荣升爱豆国际后援团中国区团长,与全球团长共商应援大事,都指日可待!
而成就这一切背后的男人,就是深处功与名的阿强,一个做事低调的coder而已。
>>访问华为开发者联盟官网,了解更多相关内容
>>获取开发指导文档
>>华为移动服务开源仓库地址:GitHub、Gitee
点击右上角头像右方的关注,第一时间了解华为移动服务最新技术~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Kafka 中所谓的 ‘零拷贝’ 技术到底是什么?
文章收录地址:Java-Bang 专注于系统架构、高可用、高性能、高并发类技术分享 除了消息顺序追加、页缓存等技术,Kafka 还使用零拷贝技术来进一步提升性能。所谓的零拷贝是指将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序之手。零拷贝大大提高了应用程序的性能,减少了内核和用户模式之间的上下文切换。对 Linux 操作系统而言,零拷贝技术依赖于底层的 sendfile() 方法实现。对应于 Java 语言,FileChannal.transferTo() 方法的底层实现就是 sendfile() 方法。 单纯从概念上理解“零拷贝”比较抽象,这里简单地介绍一下它。考虑这样一种常用的情形:你需要将静态内容(类似图片、文件)展示给用户。这个情形就意味着需要先将静态内容从磁盘中复制出来放到一个内存 buf 中,然后将这个 buf 通过套接字(Socket)传输给用户,进而用户获得静态内容。这看起来再正常不过了,但实际上这是很低效的流程,我们把上面的这种情形抽象成下面的过程: read(file, tmp_buf, len); write(socket, tmp_buf, le...
- 下一篇
云计算必备知识:公有云与私有云
在公共云中,第三方提供商通过Internet向公众提供了一系列服务。来自多个公司或个人客户端的数据可能共享同一台服务器。私有云在原理上类似,但是建立在防火墙之后,并且仅向有限数量的已批准用户提供托管服务。 辅助功能公有云可以将数据复制到许多位置,因此遍布世界各地的用户可以将公有云用作内容分发网络的替代方案。因为公共云是通过Internet访问的,所以它们可能会受到带宽限制,而私有云则是通过以太网LAN高速访问的。 安全因为公共云是可公开访问的,所以拥有敏感数据或需要保证可用性和熟练技术支持的用户可能更喜欢使用私有云。由于访问受限,因此某些人将私有云计算视为解决公共云安全问题的一种方法。 在公共云与私有云之间进行选择 公共云易于实施,并且由于硬件,应用程序和带宽的成本由提供商承担,因此用户只需为使用的内容付费。公共云提供了较低的前期成本和无限的可扩展性。小型企业可能会因为其成本较低而更喜欢公共云,但是在选择公共云之前,用户应先研究其提供商的安全策略。Netflix和Amazon等公司也使用公共云。 私有云的专用硬件使其效率更高。就像公共云一样,它按需提供资源,但是部署在组织的内部IT基础...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS关闭SELinux安全模块
- CentOS8编译安装MySQL8.0.19
- CentOS7设置SWAP分区,小内存服务器的救世主
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题