实现语音数据实时采集 播放Word文件下载.docx

上传人:b****6 文档编号:21399270 上传时间:2023-01-30 格式:DOCX 页数:17 大小:20.46KB
下载 相关 举报
实现语音数据实时采集 播放Word文件下载.docx_第1页
第1页 / 共17页
实现语音数据实时采集 播放Word文件下载.docx_第2页
第2页 / 共17页
实现语音数据实时采集 播放Word文件下载.docx_第3页
第3页 / 共17页
实现语音数据实时采集 播放Word文件下载.docx_第4页
第4页 / 共17页
实现语音数据实时采集 播放Word文件下载.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

实现语音数据实时采集 播放Word文件下载.docx

《实现语音数据实时采集 播放Word文件下载.docx》由会员分享,可在线阅读,更多相关《实现语音数据实时采集 播放Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。

实现语音数据实时采集 播放Word文件下载.docx

channelInConfig,audioEncoding);

//实例化AudioRecord

audioRecord=newAudioRecord(MediaRecorder.AudioSource.MIC,

frequence,channelInConfig,audioEncoding,bufferSize);

//定义缓冲数组

buffer=newbyte[bufferSize];

3、准备开始录制,使用循环不断读取数据。

audioRecord.startRecording();

//开始录制

isRecording=true;

//设置录制标记为true

while(isRecording){

//录制的内容放置到了buffer中,result代表存储长度

intresult=audioRecord.read(buffer,0,buffer.length);

/*.....result为buffer中录制数据的长度(貌似基本上都是640)。

剩下就是处理buffer了,是发送出去还是直接播放,这个随便你。

*/

}

//录制循环结束后,记得关闭录制!

if(audioRecord!

=null){

audioRecord.stop();

二、AudioTrack代码实现介绍如下:

1、声明播放相关配置。

privateAudioTracktrack=null;

//录音文件播放对象

privateintbufferSize=-1;

//播放缓冲大小

2、初始化AudioTrack对象(初始化一次,该对象可重复使用)

//获取缓冲大小

bufferSize=AudioTrack.getMinBufferSize(frequence,channelInConfig,

audioEncoding);

//实例AudioTrack

track=newAudioTrack(AudioManager.STREAM_MUSIC,frequence,

channelInConfig,audioEncoding,bufferSize,

AudioTrack.MODE_STREAM);

3、使用AudioTrack播放语音数据。

//将语音数据写入即可。

track.write(dataArray,buffer,len);

问题一:

由于目前的项目是实时采集,实时发送,所以需要考虑到包的大小,经测试,我们使用160个byte作为一个包传递可以做到比较良好的播放效果(也就是将一份buffer拆分成四个发送)。

处理代码如下:

//将数据通过监听接口回调出去

if(audioRecordingCallback!

intoffset=result%MAX_DATA_LENGTH>

0?

1:

0;

//将一个buffer拆分成几份小数据包MAX_DATA_LENGTH为包的最大byte数

for(inti=0;

i<

result/MAX_DATA_LENGTH+offset;

i++){

intlength=MAX_DATA_LENGTH;

if((i+1)*MAX_DATA_LENGTH>

result){

length=result-i*MAX_DATA_LENGTH;

}

//写到回调接口

audioRecordingCallback.onRecording(buffer,i

*MAX_DATA_LENGTH,length);

问题二:

有时候传输的过来播放声音会一卡一卡的,为了解决这样的问题,暂时使用了语音双缓冲机制来解决,问题优化很明显。

代码和示意图如下:

双缓冲示意图

【有朋友说要源码,那我就贴下】

【声音采集的源码】

 

/**

*实时音频录制处理类<

br/>

*记得申明系统权限:

MODIFY_AUDIO_SETTINGS、RECORD_AUDIO<

*使用实例代码:

*

*<

pre>

*audioRecoderHandler=newAudioRecoderHandler(this);

*audioRecoderHandler.startRecord(newAudioRecordingCallback(){

*&

#064;

Override

*publicvoidonStopRecord(StringsavedPath){

*}

*publicvoidonRecording(byte[]data,intstartIndex,intlength){

*//TODO录制监听。

处理data即可。

立即播放or发送出去,随你。

*});

/pre>

*@author李长军

*/

@SuppressWarnings("

deprecation"

publicclassAudioRecoderHandler{

privateContextcontext=null;

/**

*录音数据单次回调数组最大为多少

privatestaticintMAX_DATA_LENGTH=160;

privateAudioRecordaudioRecord;

privatebooleanisRecording=false;

//标记是否正在录音中

privateintfrequence=8000;

privateintchannelInConfig=AudioFormat.CHANNEL_CONFIGURATION_MONO;

//定义采样通道(过时,但是使用其他的又不行

privateintaudioEncoding=AudioFormat.ENCODING_PCM_16BIT;

privatebyte[]buffer=null;

privateFilelastCacheFile=null;

//记录上次录制的文件名

privateCommonSharedpreferenceHelpercommonSharedpreferenceHelper;

privatebooleanshouldSaveAudio=false;

//标记是否保存录音历史记录

publicAudioRecoderHandler(Contextcontext){

if(context==null){

thrownewRuntimeException("

Contextcouldnotbenull!

"

);

this.context=context;

commonSharedpreferenceHelper=CommonSharedpreferenceHelper

.getInstance(context);

*设置处理对象是否保存录音历史记录(如果设置为false表示不保存)

*@paramshouldSaveAudio

*true表示保存(默认),false不保存,onStopRecord回调将会返回null

publicvoidsetShouldSaveAudio(booleanshouldSaveAudio){

this.shouldSaveAudio=shouldSaveAudio;

*开始录制音频

*@paramcallBackListener

*录制过程中的回调函数

publicvoidstartRecord(AudioRecordingCallbackaudioRecordingCallback){

RecordTasktask=newRecordTask(audioRecordingCallback);

task.execute();

//开始执行

*停止录制

publicvoidstoppRecord(){

isRecording=false;

*删除上次录制的文件(一般是用户取消发送导致删除上次录制的内容)

*@returntrue表示删除成功,false表示删除失败,一般是没有上次录制的文件,或者文件已经被删除了

publicbooleandeleteLastRecordFile(){

booleansuccess=false;

if(lastCacheFile!

=null&

&

lastCacheFile.exists()){

success=lastCacheFile.delete();

returnsuccess;

*获取音频文件的缓存地址(获取的地址都是可以直接存储的,也就是文件夹已建立好),需要注意的是,缓存地址和用户的ID有关

*@return音频文件的缓存地址路径,如果获取失败,返回null

privateStringgetOutputDir(){

Stringpath=null;

FilecacheFile=null;

if(context!

cacheFile=context

.getExternalFilesDir(android.os.Environment.DIRECTORY_MUSIC);

if(cacheFile==null){

Toast.makeText(context,"

您的SD卡不可用"

Toast.LENGTH_SHORT).show();

}else{

path=cacheFile.getAbsolutePath()+"

/"

+commonSharedpreferenceHelper.getCurrentUserID()

+"

/record"

;

//创建文件夹

newFile(path).mkdirs();

returnpath;

*录制音频的任务类

privateclassRecordTaskextendsAsyncTask<

String,Integer,String>

{

privateAudioRecordingCallbackaudioRecordingCallback=null;

publicRecordTask(AudioRecordingCallbackaudioRecordingCallback){

this.audioRecordingCallback=oRecordingCallback;

@Override

protectedvoidonPreExecute(){

//根据定义好的几个配置,来获取合适的缓冲大小

//intbufferSize=800;

intbufferSize=AudioRecord.getMinBufferSize(frequence,

//实例化AudioRecord

audioRecord=newAudioRecord(MediaRecorder.AudioSource.MIC,

//定义缓冲数组

buffer=newbyte[bufferSize];

audioRecord.startRecording();

isRecording=true;

protectedvoidonPostExecute(Stringresult){

audioRecord=null;

if(result==null){

lastCacheFile=null;

lastCacheFile=newFile(result);

if(audioRecordingCallback!

audioRecordingCallback.onStopRecord(result);

protectedStringdoInBackground(String...params){

StringcacheDir=getOutputDir();

StringtempFileName=null;

//输出的文件流

DataOutputStreamdataOutputStream=null;

//如果设置了要保存历史录音文件,则创建临时文件

if(shouldSaveAudio&

cacheDir!

tempFileName=cacheDir+"

+System.currentTimeMillis();

cacheFile=newFile(pFileName);

try{

dataOutputStream=newDataOutputStream(

newBufferedOutputStream(newFileOutputStream(

cacheFile)));

}catch(FileNotFoundExceptione){

e.printStackTrace();

//开始录制

while(isRecording){

//录制的内容放置到了buffer中,result代表存储长度

intresult=audioRecord.read(buffer,0,buffer.length);

//如果设置需要保存录音文件

dataOutputStream!

result;

//将录制到的内容放置到文件中

dataOutputStream.write(buffer[i]);

}catch(IOExceptione){

//将数据回调出去

if(audioRecord!

if(dataOutputStream!

dataOutputStream.close();

returntempFileName;

*监听录制过程,用于实时获取录音数据

publicstaticinterfaceAudioRecordingCallback{

*录音数据获取回调

*@paramdata

*数据数组对象

*@paramstartIndex

*数据其开始

*@paramlength

*数据的结尾

publicvoidonRecording(byte[]data,intstartIndex,intlength);

*录音结束后的回调

*@paramsavedPath

*录音文件存储的路径

publicvoidonStopRecord(StringsavedPath);

*释放资源

publicvoidrelease(){

audioRecord.release();

【声音播放的源码】

*实时音频播放处理类<

*使用示例代码如下:

*audioPlayerHandler=newAudioPlayerHandler();

*audioPlayerHandler.prepare();

//播放前需要prepare。

可以重复prepare

*//直接将需要播放的数据传入即可

*audioPlayerHandler.onPlaying(data,0,data.length);

publicclassAudioPlayerHandlerimplementsRunnable{

privateAudioTracktrack=null;

privatebooleanisPlaying=false;

privateintbufferSize=-1;

//使用双缓冲机制

privateByteArrayOutputStreambufferStream0=newByteArrayOutputStream();

privateByteArrayOutputStreambufferStream1=newByteArrayOutputStream();

privateintcurrentBuffer=-1;

//记录当前哪个buffer填充完毕,并正在播放中。

-1表示都没有。

0表示第一个,1表示第二个

//互斥信号量

privateSemaphoresemaphore=newSemaphore

(1);

//是否释放资源的标志位

privatebooleanrelease=false;

publicAudioPlayerHandler(){

//获取缓冲大小

bufferSize=AudioTrack.getMinBufferSize(frequence,channelInCo

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1