2019独角兽企业重金招聘Python工程师标准>>>

这里只是功能实现(个人非android开发),可能有很多更好的实现方式,该功能的开发是之前看到过阿里的实时语音转文字的接口,当时就想把这个功能做到手机上,自己又是java开发,就百度了点基础的android知识做了个简单的实现。

主方法(手机端),主要任务采集声音,流形式发送到后台

package com.hht.myapplication;import android.Manifest;
import android.text.ClipboardManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;/*** 语音小助手* hht*/
public class MainActivity extends AppCompatActivity {//接收转换的文字流DataInputStream dis;//音频流上传通道OutputStream ous;String serverIp = "101.201.XXX.XXX";int serverPort = 5555;private TextView realText;private TextView finalText;//音频相关AudioRecord audioRecord=null;int bufferSize=0;//最小缓冲区大小int sampleRateInHz = 16000;//采样率int channelConfig = AudioFormat.CHANNEL_IN_DEFAULT; //单声道int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //量化位数private boolean isRecording = true;private Handler handler=null;private  String content ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);realText = (TextView) findViewById(R.id.textView2);finalText = (TextView) findViewById(R.id.textView);finalText.setMovementMethod(ScrollingMovementMethod.getInstance()) ;handler = new Handler();if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)  != PackageManager.PERMISSION_GRANTED)  {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO},1);} else {init();}}public void onClickCopy(View v) {// 从API11开始android推荐使用android.content.ClipboardManager// 为了兼容低版本我们这里使用旧版的android.text.ClipboardManager,虽然提示deprecated,但不影响使用。ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);// 将文本内容放到系统剪贴板里。cm.setText(finalText.getText());Toast.makeText(this, "复制成功,可以发给朋友们了。", Toast.LENGTH_LONG).show();}public void init(){System.out.println("初始化录音");bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat)+1000;//计算最小缓冲区try{audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,channelConfig, audioFormat, bufferSize);//创建AudioRecorder对象Runnable startRunnable = new Runnable(){@Overridepublic void run() {connect();new sendDataThread().start();new getDataThread().start();}};new Thread(startRunnable).start();}catch (Exception e){e.printStackTrace();}System.out.println("初始化录音成功");}public void connect(){try{Socket socket = new Socket(serverIp,serverPort);InputStream is=socket.getInputStream();ous = socket.getOutputStream();dis=new DataInputStream(is);}catch(IOException e){e.printStackTrace();}}//发送数据class sendDataThread extends Thread {public void run() {byte[] buffer = new byte[bufferSize];audioRecord.startRecording();//开始录音int r = 0;try {while (isRecording&&audioRecord.read(buffer,0,bufferSize)>0) {ous.write(buffer);ous.flush();}audioRecord.stop();//停止录音} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//接收数据class getDataThread extends Thread {public void run() {while (true) {String msg;try {msg = dis.readUTF();if (!"status".equals(msg)&&!"".equals(msg)) {//status 为心跳检测content=msg;handler.post(runnableUi);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}// 构建Runnable对象,在runnable中更新界面Runnable   runnableUi=new  Runnable(){@Overridepublic void run() {//更新界面realText.setText(content);finalText.append(content);//跳转到底部int offset=finalText.getLineCount()*finalText.getLineHeight();if(finalText.getLineCount()>15 && offset>finalText.getHeight()){finalText.scrollTo(0,offset-finalText.getHeight());}}};@Overridepublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {switch (requestCode) {case 1: {if (grantResults.length > 0  && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 权限被用户同意,可以去放肆了。init();} else {// 权限被用户拒绝了,洗洗睡吧。}return;}}}
}

服务器端,接收流信息上传阿里获取实时转换结果,这里应该有自己的控制策略,我这里只做了实现,策略没有哦

这部分代码是接收和处理客户端请求

package com.hmkx.freezingapi.rest.jkjweb;import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.hmkx.freezingapi.util.ali.RealtimeAsrDemo;/*** 语音转换服务 监听* * @author hht* @since 2018-06-12*/
public class AudioChangeServerThread extends Thread {private static Logger log = LoggerFactory.getLogger(AudioChangeServerThread.class);static int cCount = 0;//当前连接数static int maxCount = 10;//最大连接数static ServerSocket server = null;static List<DataOutputStream>socketsOut = new ArrayList<DataOutputStream>();static List<Socket>sockets = new ArrayList<Socket>();public static boolean runStatus = false;//标记状态 关闭后不再接受连接public void run(){runStatus = true;if(server==null){//语音转换服务监听try {server = new ServerSocket(5555);} catch (IOException e) {     e.printStackTrace();}while (runStatus) {//每接受一个连接,清理半关闭的连接validateSocket();if(cCount<=maxCount){try {Socket temp = server.accept();sockets.add(temp);OutputStream os=temp.getOutputStream();DataOutputStream dos=new DataOutputStream(os);InputStream ins = temp.getInputStream();RealtimeAsrDemo lun = new RealtimeAsrDemo(ins,dos);log.error("audio change start ....");new Thread(lun).start();  cCount++;} catch (IOException e) {log.error("has connected io exception");}log.error("has connected "+cCount);}}}}/*** 清楚已经断开的连接* @param i*/public static void removeSocket(int i){Aclose(sockets.get(i));Aclose(socketsOut.get(i));sockets.remove(i);socketsOut.remove(i);cCount--;}/*** 清楚已经断开的连接* @param i*/public void validateSocket(){for(int i=0;i<socketsOut.size();i++){try {DataOutputStream temp = socketsOut.get(i);temp.writeUTF("status");temp.flush();} catch (Exception e) {removeSocket(i);}}}/*** 连接关闭方法* @param o*/public static  void Aclose(Object...o){for(int i=0;i<o.length;i++){if(o[i] instanceof Closeable){try {Closeable c = (Closeable)o[i];c.close();} catch (IOException e) {e.printStackTrace();}}if(o[i] instanceof ServerSocket){try {ServerSocket c = (ServerSocket)o[i];c.close();} catch (IOException e) {e.printStackTrace();}}if(o[i] instanceof Socket){try {Socket c = (Socket)o[i];c.close();} catch (IOException e) {e.printStackTrace();}}}}}

下面这部分代码是处理流和阿里云服务接口的交互,用到阿里的包这个自行引入,(最近科大讯飞也提供了类似的接口,貌似效果更好)可以替换这部分逻辑就可以

package com.hmkx.freezingapi.util.ali;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;
import com.alibaba.idst.nls.realtime.NlsClient;
import com.alibaba.idst.nls.realtime.NlsFuture;
import com.alibaba.idst.nls.realtime.event.NlsEvent;
import com.alibaba.idst.nls.realtime.event.NlsListener;
import com.alibaba.idst.nls.realtime.protocol.NlsRequest;
import com.alibaba.idst.nls.realtime.protocol.NlsResponse;
import com.hmkx.freezingapi.rest.jkjweb.AudioChangeServerThread;/*** 语音实时转文字工具类* * @author hht**/
public class RealtimeAsrDemo implements NlsListener,Runnable{protected NlsClient client = new NlsClient();protected static final String asrSC = "pcm";static Logger logger = LoggerFactory.getLogger(RealtimeAsrDemo.class);public String appKey = "XXX";protected String ak_id = "XXX";protected String ak_secret = "XXX";private InputStream fis = null;private DataOutputStream dos = null;public RealtimeAsrDemo(InputStream fis, DataOutputStream dos) {this.fis = fis;this.dos = dos;}public void shutDown() {logger.error("close NLS client manually!");client.close();logger.error("demo done");}public void init() {logger.error("init Nls client...");client.init();}public void process() {logger.error("open audio file...");if (fis != null) {logger.error("create NLS future");process(fis);logger.error("calling NLS service end");}}public void process(InputStream ins) {try {NlsRequest req = buildRequest();NlsFuture future = client.createNlsFuture(req, this);logger.error("call NLS service");byte[] b = new byte[8000];int len = 0;while (AudioChangeServerThread.runStatus && (len = ins.read(b)) > 0 ) {future.sendVoice(b, 0, len);}logger.error("send finish signal!");future.sendFinishSignal();logger.error("main thread enter waiting .");future.await(100000);} catch (Exception e) {StringWriter sw = new StringWriter();e.printStackTrace(new PrintWriter(sw));logger.error(sw.toString());}}protected NlsRequest buildRequest() {NlsRequest req = new NlsRequest();req.setAppkey(appKey);req.setFormat(asrSC);req.setResponseMode("streaming");req.setSampleRate(16000);// 用户根据[热词文档](~~49179~~) 设置自定义热词。// 通过设置VocabularyId调用热词。// req.setVocabularyId("");// 设置关键词库ID 使用时请修改为自定义的词库ID// req.setKeyWordListId("c1391f1c1f1b4002936893c6d97592f3");// the id and the id secretreq.authorize(ak_id, ak_secret);return req;}@Overridepublic void onMessageReceived(NlsEvent e) {NlsResponse response = e.getResponse();response.getFinish();if (response.result != null) {logger.error(response.getResult().toString());if(response.getResult().getStatus_code()==0&&!"".equals(response.getText())){String content = response.getText();logger.error(content);try {dos.writeUTF(content);dos.flush();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}} else {logger.error(JSON.toJSONString(response));}}@Overridepublic void onOperationFailed(NlsEvent e) {logger.error("status code is {}, on operation failed: {}"+ e.getResponse().getStatusCode()+e.getErrorMessage());}@Overridepublic void onChannelClosed(NlsEvent e) {logger.error("on websocket closed.");}@Overridepublic void run() {init();process();shutDown();}}

这样就可以了,先启动服务端,然后启动app就可以实现语音是说转文字了哦

补充代码

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.hht.myapplication.MainActivity"><TextViewandroid:text=""android:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/textView2"android:maxLines="5"android:layout_alignParentTop="true"android:layout_alignParentStart="true" /><TextViewandroid:text=""android:layout_width="wrap_content"android:layout_height="wrap_content"android:textIsSelectable="true"android:focusable="true"android:layout_centerVertical="true"android:layout_alignParentStart="true"android:scrollbars="vertical"android:maxLines="15"android:fadeScrollbars="false"android:id="@+id/textView" /><Buttonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:onClick="onClickCopy"android:text="复制上面的文本内容"android:id="@+id/button"android:layout_marginBottom="12dp"android:layout_alignParentBottom="true"android:layout_alignParentEnd="true"android:layout_marginEnd="7dp" /></RelativeLayout>

转载于:https://my.oschina.net/haitaohu/blog/1921796

实时语音转文字app简易demo(这里使用了阿里的接口,可以替换成科大讯飞)相关推荐

  1. java文字转语音支持ubuntu系统_9个(实时)语音转文字APP分享(推荐收藏)

    " 做会议记录.看无字幕网课再也不用担心,解放双手,提高效率." 随着语音转文字技术的发展,我们记录会议.上课内容等有了更好的方式. 实时语音转文字实现边听边看,并且还可回看转译记 ...

  2. 度秘语音引擎app_「资源」9个(实时)语音转文字APP分享(推荐收藏)

    " 做会议记录.看无字幕网课再也不用担心,解放双手,提高效率." 随着语音转文字技术的发展,我们记录会议.上课内容等有了更好的方式. 实时语音转文字实现边听边看,并且还可回看转译记 ...

  3. 普通话转粤语_语音转文字评测:几款语音转文字app,你了解多少?

    语音转文字有必要吗?能用在哪里?这是大多数人对于语记类app的疑问所在,今天为大家简单介绍一下几款实用的语记app以及简单的应用描述. 1. 讯飞语记 讯飞语记是讯飞旗下的语音转文字产品,如我们所知, ...

  4. 科大讯飞语音转文字_科大讯飞推出TWS真无线耳机:主打商务沟通,实时语音转文字...

    昨日,科大讯飞正式发布了旗下首款真无线耳机"IFLYBUDS",在目前无线耳机的功能的基础上,增添了实时语音转文字功能,可替代录音笔等设备,主打商务沟通. 单从外观来看,IFLYB ...

  5. 工具学习——有哪些好用的语音转文字app

    网易见外工作台 https://jianwai.youdao.com/index/0 安全免费的 AI 智能语音转写听翻平台. 支持不超过 500M 文件的语音文字在线转换. 点击网页右上角的[新建项 ...

  6. 讯飞语音转文字 PHP demo

    讯飞语音转文字PHP tp6 demo 讯飞官网没有PHP demo我是很诧异的 改成了我需要的tp6 demo 讯飞官网没有PHP demo我是很诧异的 我php天下第一就这么没牌面吗 网上找了很久 ...

  7. 5款软件做访谈 | 语音转文字 | 实时转录 | 简单高效

    最近在做访谈,所以整理了一些好用的录音转文字的软件和APP,跟大家分享下,希望能够对大家有用- 1.百度输入法的语音输入 需要先下载百度输入法,然后打开一份空白的Word文件,点击"语音输入 ...

  8. 【Buzz】离线语音转文字、实时语音识别

    Buzz是基于 OpenAI Whisper的离线语音转文字(字幕),实时语音识别工具. 功能 实时语音转文字.实时翻译(需麦克风权限) 导入音频.视频文件(mp3.wav.m4a.ogg.mp4.w ...

  9. 微软推出“ Group Transcribe”应用,多人多语言会议实时高准确度文字转录并翻译

    近期,微软针对面对面对话和会议推出了免费实时语音到文字转录和翻译应用程序--Group Transcribe.一方面,Group Transcribe可以通过手机把会议的语音内容实时转录为文本,供与会 ...

最新文章

  1. 前期绑定 vs 后期绑定
  2. POJ 1330 Nearest Common Ancestors 【LCA模板题】
  3. 获取控件坐标位置一直是0
  4. 网络服务器开发总结(转:http://my.oschina.net/u/181613/blog/596022)
  5. JFreeChart基本的用法实例(一)
  6. sap.ui.layout.form.SimpleForm.prototype
  7. Neo4j:特定关系与一般关系+属性
  8. 向银行贷款20万, 分期三年买50万的车,个人借款40万, 贷款10年买200万的房子,再贷款120万分创业...
  9. 执行Dockerfile构建基础镜像,建立python工作环境
  10. linux android ndk
  11. 实践证明,SQL Server 2000 + 2005 + 2008,完全可以共存
  12. 突然想 写个 接口定义 【来源于华为和海康 设备接口同步】
  13. hive partition 分区详解一
  14. ubuntu系统grub引导修复
  15. SDL Trados2017及SDL MultiTerm安装
  16. idea activation code记录
  17. ❤️UNITY实战进阶-OBB包围盒详解-6
  18. 快速获取网页元素xpath的方法
  19. 农场(JQuery版)
  20. 亚马逊推出的「距离助手」,好像孙悟空给唐僧画的圈圈啊

热门文章

  1. Mininet系列实验(七):Mininet脚本实现控制交换机行为
  2. 小红书直播收益怎么算?有效提高直播收益的小技巧
  3. PXE+Kickstart 无人值守安装系统
  4. RPM包安装的数据库进行版本升级
  5. 2023必火的5种服装店装修风格,看看哪种风格适合你家店?
  6. Linux查看系统版号
  7. 到处excel表格的数据和页面的数据不一致
  8. js实现下雪雪花特效
  9. 罗克韦尔(AB)PLC与MySQL/SQLServer/PostgreSQL数据库对接
  10. 【建议收藏】新到手的电脑Windows10/11系统优化、使用规范和技巧及软件推荐,提升范电脑性能和体验