热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

科大讯飞语音识别(获取音频流文件中文字)

项目中需要获取视频中的文字,将过程记录下,方便以后使用!为了确保项目在公司内网也能使用语音识别,需要确保内网可以通过HTTP访问dev.voicecloud.cn该网址不是在

项目中需要获取视频中的文字, 将过程记录下, 方便以后使用!

 为了确保项目在公司内网也能使用语音识别,需要确保内网可以通过HTTP访问dev.voicecloud.cn   该网址不是在浏览器地址栏中使用的, sdk要连接的

需求:

获取视频中的音频文件

思路:

1. 使用科大讯飞的语音听写sdk,来获取音频中的文字信息

2.科大讯飞,现在(2017年1月)支持且仅支持pcm和wav格式的音频流文件。 

那么我要从视频中获取文字, 所以需要先从视频中提取格式为pcm或wav格式的音频流文件。然后再将音频流文件传送给讯飞的sdk解析。


所需工具:

1.提取视频中的音频流文件,可以使用Linu上的ffmpeg工具完成, 需要先在Linux上安装ffmpeg,通过Java调用提取音频的命令,获取音频文件。 

我提取pcm格式文件失败, 所以提取的wav格式的文件

2. 提取命令: 

       方式一: ffmpeg -i视频文件名-f s16le -ar 16000输出的音频文件名

  命令解释:以16位,16k采样率提取视频文件中的音频文件。

  方式二:ffmpeg -i 视频文件名 -vn -ar 16000 -ac 1 -acodec pcm_s16le -y 音频文件名

提取的音频文件质量对解析结果有很大的影响。

这是他们的建议:上传的识别的音频格式是有要求的,目前支持的格式是 pcmwav格式、音频采样率要是16k或者8k、采样精度16位、单声道音频

(采样率 16k 8k 识别效果要好一些,识别的音频长度最大为60S)。


下面不在啰嗦其他的,直接写我的测试代码:

资源文档:http://download.csdn.net/detail/changerzhuo_319/9729538

1. Java调用Linux命令, 提取视频中的音频文件:

package com.iflytek;

import java.io.File;
import java.io.InputStreamReader;
import java.io.LineNumberReader;

import org.apache.log4j.Logger;

public class Video2Voice {

private static Logger logger = Logger.getLogger(Video2Voice.class);
/**
* 提取视频中的音频文件
* @param fileName
* @return 音频文件名
* @throws Exception
*/
public static String transform(String fileName) throws Exception {

File file = new File(fileName);
if(!file.exists()) {
logger.error("文件不存在:"+fileName);
throw new RuntimeException("文件不存在:"+fileName);
}

//讯飞现在支持pcm,wav的语音流文件
String name = fileName.substring(0, fileName.lastIndexOf(".")) + ".wav";
logger.info("获取到的音频文件:"+name);

// 提取视频中的音频文件。 根据讯飞要求设置采样率, 位数,
String cmd = "ffmpeg -i "+ fileName +" -f s16le -ar 16000 "+ name;
Process process = Runtime.getRuntime().exec(cmd);//执行命令

//
InputStreamReader ir = new InputStreamReader(process.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
String line;
//输出结果,需要有这部分代码, 否则不能生产抽取的音频文件
while ((line = input.readLine()) != null) {
System.out.println(line);
}
process.destroy();
return name;
}

public static void main(String[] args) {
try {
transform(args[0]);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

2. 从音频文件中获取文字信息, 这段代码是修改的讯飞demo中的代码,仅保留了语音识别的代码

package com.iflytek;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

import com.iflytek.cloud.speech.DataUploader;
import com.iflytek.cloud.speech.LexiconListener;
import com.iflytek.cloud.speech.RecognizerListener;
import com.iflytek.cloud.speech.RecognizerResult;
import com.iflytek.cloud.speech.Setting;
import com.iflytek.cloud.speech.SpeechConstant;
import com.iflytek.cloud.speech.SpeechError;
import com.iflytek.cloud.speech.SpeechListener;
import com.iflytek.cloud.speech.SpeechRecognizer;
import com.iflytek.cloud.speech.SpeechSynthesizer;
import com.iflytek.cloud.speech.SpeechUtility;
import com.iflytek.cloud.speech.SynthesizeToUriListener;
import com.iflytek.cloud.speech.UserWords;

public class MscTest {

private static final String APPID = "5860ec57";

private StringBuffer mResult = new StringBuffer();

/** 最大等待时间, 单位ms */
private int maxWaitTime = 500;
/** 每次等待时间 */
private int perWaitTime = 100;
/** 出现异常时最多重复次数 */
private int maxQueueTimes = 3;
/** 音频文件 */
private String fileName = "";

static {
Setting.setShowLog( false );
SpeechUtility.createUtility("appid=" + APPID);
}

public String voice2words(String fileName) throws InterruptedException {
return voice2words(fileName, true);
}

/**
*
* @desc: 工具类,在应用中有一个实例即可, 但是该实例是有状态的, 因此要消除其他调用对状态的修改,所以提供一个init变量
* @auth: zona
* 2017年1月4日 下午4:38:45
* @param fileName
* @param init 是否初始化最大等待时间。
* @return
* @throws InterruptedException
*/
public String voice2words(String fileName, boolean init) throws InterruptedException {
if(init) {
maxWaitTime = 500;
maxQueueTimes = 3;
}
if(maxQueueTimes <= 0) {
mResult.setLength(0);
mResult.append("解析异常!");
return mResult.toString();
}
this.fileName = fileName;

return recognize();
}


// *************************************音频流听写*************************************

/**
* 听写
* @return
* @throws InterruptedException
*/
private String recognize() throws InterruptedException {
if (SpeechRecognizer.getRecognizer() == null)
SpeechRecognizer.createRecognizer();
return RecognizePcmfileByte();
}

/**
* 自动化测试注意要点 如果直接从音频文件识别,需要模拟真实的音速,防止音频队列的堵塞
* @throws InterruptedException
*/
private String RecognizePcmfileByte() throws InterruptedException {
// 1、读取音频文件
FileInputStream fis = null;
byte[] voiceBuffer = null;
try {
fis = new FileInputStream(new File(fileName));
voiceBuffer = new byte[fis.available()];
fis.read(voiceBuffer);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fis) {
fis.close();
fis = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 2、音频流听写
if (0 == voiceBuffer.length) {
mResult.append("no audio avaible!");
} else {
//解析之前将存出结果置为空
mResult.setLength(0);
SpeechRecognizer recognizer = SpeechRecognizer.getRecognizer();
recognizer.setParameter(SpeechConstant.DOMAIN, "iat");
recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
recognizer.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
//写音频流时,文件是应用层已有的,不必再保存
// recognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH,
// "./iflytek.pcm");
recognizer.setParameter( SpeechConstant.RESULT_TYPE, "plain" );
recognizer.startListening(recListener);
ArrayList buffers = splitBuffer(voiceBuffer,
voiceBuffer.length, 4800);
for (int i = 0; i // 每次写入msc数据4.8K,相当150ms录音数据
recognizer.writeAudio(buffers.get(i), 0, buffers.get(i).length);
try {
Thread.sleep(150);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
recognizer.stopListening();

// 在原有的代码基础上主要添加了这个while代码等待音频解析完成,recognizer.isListening()返回true,说明解析工作还在进行
while(recognizer.isListening()) {
if(maxWaitTime <0) {
mResult.setLength(0);
mResult.append("解析超时!");
break;
}
Thread.sleep(perWaitTime);
maxWaitTime -= perWaitTime;
}
}
return mResult.toString();
}

/**
* 将字节缓冲区按照固定大小进行分割成数组
*
* @param buffer
* 缓冲区
* @param length
* 缓冲区大小
* @param spsize
* 切割块大小
* @return
*/
private ArrayList splitBuffer(byte[] buffer, int length, int spsize) {
ArrayList array = new ArrayList();
if (spsize <= 0 || length <= 0 || buffer == null
|| buffer.length return array;
int size = 0;
while (size int left = length - size;
if (spsize byte[] sdata = new byte[spsize];
System.arraycopy(buffer, size, sdata, 0, spsize);
array.add(sdata);
size += spsize;
} else {
byte[] sdata = new byte[left];
System.arraycopy(buffer, size, sdata, 0, left);
array.add(sdata);
size += left;
}
}
return array;
}

/**
* 听写监听器
*/
private RecognizerListener recListener = new RecognizerListener() {

public void onBeginOfSpeech() { }

public void onEndOfSpeech() { }

public void onVolumeChanged(int volume) { }

public void onResult(RecognizerResult result, boolean islast) {
mResult.append(result.getResultString());
}

public void onError(SpeechError error) {
try {
voice2words(fileName);
maxQueueTimes--;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}

public void onEvent(int eventType, int arg1, int agr2, String msg) { }

};

}

3. main代码:

package com.iflytek;

import java.util.Scanner;


/**
* @desc:
* @auth: zona
* 2017年1月4日 上午10:08:21
*/
public class Test {

private static String fileName = "1481023006148.wav";
public static void main(String[] args) throws InterruptedException {

Scanner scanner =new Scanner(System.in);

MscTest mObject = new MscTest();
int a = 1;
boolean flag = true;
for(int i=0; i<200; i++) {
// MscTest mObject = new MscTest();
if(flag) {
System.out.print("place input num:");
int num = scanner.nextInt();
if(num > 10) {
flag = false;
}
}
//语音识别, 并给mResult赋值, 在获取音频文件中的文字代码中添加while就是为了确保该行代码执行完成时,
// 语音识别解析工作已经完成,否则可能获取不到识别结果, 或仅仅是获取到识别结果的一部分
String result = mObject.voice2words(fileName);
System.out.println(a+"--->MscTest.main()--"+result);
a++;
}
}
}





推荐阅读
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • 2018深入java目标计划及学习内容
    本文介绍了作者在2018年的深入java目标计划,包括学习计划和工作中要用到的内容。作者计划学习的内容包括kafka、zookeeper、hbase、hdoop、spark、elasticsearch、solr、spring cloud、mysql、mybatis等。其中,作者对jvm的学习有一定了解,并计划通读《jvm》一书。此外,作者还提到了《HotSpot实战》和《高性能MySQL》等书籍。 ... [详细]
author-avatar
我是风一样的我们
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有