




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android如何實(shí)現(xiàn)語音播放與錄音功能
這篇文章主要介紹Android如何實(shí)現(xiàn)語音播放與錄音功能,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!具體內(nèi)容如下項(xiàng)目用到的技術(shù)點(diǎn)和亮點(diǎn)語音錄音(單個(gè)和列表)語音播放(單個(gè)和列表)語音錄音封裝語音播放器封裝語音列表順序播放語音列表單個(gè)播放復(fù)用問題處理因?yàn)榘惭b原生錄音不能錄mp3格式文件而mp3格式是安卓和ios公用的,所以我們需要的是能直接錄取mp3文件或者錄完的格式轉(zhuǎn)成mp3格式下面添加這個(gè)庫能直接錄mp3文件,我覺得是最方便的compile‘com.czt.mp3recorder:library:1.0.3'1.語音錄音封裝代碼簡(jiǎn)單自己看吧package
com.video.zlc.audioplayer;
import
com.czt.mp3recorder.MP3Recorder;
import
com.video.zlc.audioplayer.utils.LogUtil;
import
java.io.File;
import
java.io.IOException;
import
java.util.UUID;
/**
*
@author
zlc
*/
public
class
AudioManage
{
private
MP3Recorder
mRecorder;
private
String
mDir;
//
文件夾的名稱
private
String
mCurrentFilePath;
private
static
AudioManage
mInstance;
private
boolean
isPrepared;
//
標(biāo)識(shí)MediaRecorder準(zhǔn)備完畢
private
AudioManage(String
dir)
{
mDir
=
dir;
LogUtil.e("AudioManage=",mDir);
}
/**
*
回調(diào)“準(zhǔn)備完畢”
*
@author
zlc
*/
public
interface
AudioStateListenter
{
void
wellPrepared();
//
prepared完畢
}
public
AudioStateListenter
mListenter;
public
void
setOnAudioStateListenter(AudioStateListenter
audioStateListenter)
{
mListenter
=
audioStateListenter;
}
/**
*
使用單例實(shí)現(xiàn)
AudioManage
*
@param
dir
*
@return
*/
public
static
AudioManage
getInstance(String
dir)
{
if
(mInstance
==
null)
{
synchronized
(AudioManage.class)
{
//
同步
if
(mInstance
==
null)
{
mInstance
=
new
AudioManage(dir);
}
}
}
return
mInstance;
}
/**
*
準(zhǔn)備錄音
*/
public
void
prepareAudio()
{
try
{
isPrepared
=
false;
File
dir
=
new
File(mDir);
if
(!dir.exists())
{
dir.mkdirs();
}
String
fileName
=
GenerateFileName();
//
文件名字
File
file
=
new
File(dir,
fileName);
//
路徑+文件名字
//MediaRecorder可以實(shí)現(xiàn)錄音和錄像。需要嚴(yán)格遵守API說明中的函數(shù)調(diào)用先后順序.
mRecorder
=
new
MP3Recorder(file);
mCurrentFilePath
=
file.getAbsolutePath();
//
mMediaRecorder
=
new
MediaRecorder();
//
mCurrentFilePath
=
file.getAbsolutePath();
//
mMediaRecorder.setOutputFile(file.getAbsolutePath());
//
設(shè)置輸出文件
//
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//
設(shè)置MediaRecorder的音頻源為麥克風(fēng)
//
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
//
設(shè)置音頻的格式
//
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//
設(shè)置音頻的編碼為AMR_NB
//
mMediaRecorder.prepare();
//
mMediaRecorder.start();
mRecorder.start();
//開始錄音
isPrepared
=
true;
//
準(zhǔn)備結(jié)束
if
(mListenter
!=
null)
{
mListenter.wellPrepared();
}
}
catch
(Exception
e)
{
e.printStackTrace();
LogUtil.e("prepareAudio",e.getMessage());
}
}
/**
*
隨機(jī)生成文件名稱
*
@return
*/
private
String
GenerateFileName()
{
//
TODO
Auto-generated
method
stub
return
UUID.randomUUID().toString()
+
".mp3";
//
音頻文件格式
}
/**
*
獲得音量等級(jí)——通過mMediaRecorder獲得振幅,然后換算成聲音Level
*
maxLevel最大為7;
*
@return
*/
public
int
getVoiceLevel(int
maxLevel)
{
if
(isPrepared)
{
try
{
mRecorder.getMaxVolume();
return
maxLevel
*
mRecorder.getMaxVolume()
/
32768
+
1;
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
return
1;
}
/**
*
釋放資源
*/
public
void
release()
{
if(mRecorder
!=
null)
{
mRecorder.stop();
mRecorder
=
null;
}
}
/**
*
停止錄音
*/
public
void
stop(){
if(mRecorder!=null
&&
mRecorder.isRecording()){
mRecorder.stop();
}
}
/**
*
取消(釋放資源+刪除文件)
*/
public
void
delete()
{
release();
if
(mCurrentFilePath
!=
null)
{
File
file
=
new
File(mCurrentFilePath);
file.delete();
//刪除錄音文件
mCurrentFilePath
=
null;
}
}
public
String
getCurrentFilePath()
{
return
mCurrentFilePath;
}
public
int
getMaxVolume(){
return
mRecorder.getMaxVolume();
}
public
int
getVolume(){
return
mRecorder.getVolume();
}
}2.語音播放器封裝package
com.video.zlc.audioplayer.utils;
import
android.content.Context;
import
android.media.AudioManager;
import
android.media.MediaPlayer;
import
.Uri;
/**
*
*
@author
zlc
*
*/
public
class
MediaManager
{
private
static
MediaPlayer
mMediaPlayer;
//播放錄音文件
private
static
boolean
isPause
=
false;
static
{
if(mMediaPlayer==null){
mMediaPlayer=new
MediaPlayer();
mMediaPlayer.setOnErrorListener(
new
MediaPlayer.OnErrorListener()
{
@Override
public
boolean
onError(MediaPlayer
mp,
int
what,
int
extra)
{
mMediaPlayer.reset();
return
false;
}
});
}
}
/**
*
播放音頻
*
@param
filePath
*
@param
onCompletionListenter
*/
public
static
void
playSound(Context
context,String
filePath,
MediaPlayer.OnCompletionListener
onCompletionListenter){
if(mMediaPlayer==null){
mMediaPlayer
=
new
MediaPlayer();
mMediaPlayer.setOnErrorListener(
new
MediaPlayer.OnErrorListener()
{
@Override
public
boolean
onError(MediaPlayer
mp,
int
what,
int
extra)
{
mMediaPlayer.reset();
return
false;
}
});
}else{
mMediaPlayer.reset();
}
try
{
//詳見“MediaPlayer”調(diào)用過程圖
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnCompletionListener(onCompletionListenter);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepare();
mMediaPlayer.start();
}
catch
(Exception
e)
{
//
TODO
Auto-generated
catch
block
e.printStackTrace();
LogUtil.e("語音error==",e.getMessage());
}
}
/**
*
暫停
*/
public
synchronized
static
void
pause(){
if(mMediaPlayer!=null
&&
mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
isPause=true;
}
}
//停止
public
synchronized
static
void
stop(){
if(mMediaPlayer!=null
&&
mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
isPause=false;
}
}
/**
*
resume繼續(xù)
*/
public
synchronized
static
void
resume(){
if(mMediaPlayer!=null
&&
isPause){
mMediaPlayer.start();
isPause=false;
}
}
public
static
boolean
isPause(){
return
isPause;
}
public
static
void
setPause(boolean
isPause)
{
MediaManager.isPause
=
isPause;
}
/**
*
release釋放資源
*/
public
static
void
release(){
if(mMediaPlayer!=null){
isPause
=
false;
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer
=
null;
}
}
public
synchronized
static
void
reset(){
if(mMediaPlayer!=null)
{
mMediaPlayer.reset();
isPause
=
false;
}
}
/**
*
判斷是否在播放視頻
*
@return
*/
public
synchronized
static
boolean
isPlaying(){
return
mMediaPlayer
!=
null
&&
mMediaPlayer.isPlaying();
}
}3.語音列表順序播放
private
int
lastPos
=
-1;
//播放語音
private
void
playVoice(final
int
position,
String
from)
{
LogUtil.e("playVoice
position",position+"");
if(position
>=
records.size())
{
LogUtil.e("playVoice","全部播放完了");
stopAnimation();
MediaManager.reset();
return;
}
String
voicePath
=
records.get(position).getPath();
LogUtil.e("playVoice",voicePath);
if(TextUtils.isEmpty(voicePath)
||
!voicePath.contains(".mp3")){
Toast.makeText(this,"語音文件不合法",Toast.LENGTH_LONG).show();
return;
}
if(lastPos
!=
position
&&
"itemClick".equals(from)){
stopAnimation();
MediaManager.reset();
}
lastPos
=
position;
//獲取listview某一個(gè)條目的圖片控件
int
pos
=
position
-
id_list_voice.getFirstVisiblePosition();
View
view
=
id_list_voice.getChildAt(pos);
id_iv_voice
=
(ImageView)
view.findViewById(R.id.id_iv_voice);
LogUtil.e("playVoice
position",pos+"");
if(MediaManager.isPlaying()){
MediaManager.pause();
stopAnimation();
}else
if(MediaManager.isPause()){
startAnimation();
MediaManager.resume();
}else{
startAnimation();
MediaManager.playSound(this,voicePath,
new
MediaPlayer.OnCompletionListener()
{
@Override
public
void
onCompletion(MediaPlayer
mediaPlayer)
{
//播放完停止動(dòng)畫
重置MediaManager
stopAnimation();
MediaManager.reset();
playVoice(position
+
1,
"loop");
}
});
}
}4.語音列表單個(gè)播放復(fù)用問題處理播放邏輯基本同上private
int
lastPosition
=
-1;
private
void
playVoice(FendaListInfo.ObjsEntity
obj,
int
position)
{
String
videoPath
=
obj.path;
if(TextUtils.isEmpty(videoPath)
||
!videoPath.contains(".mp3")){
Toast.makeText(this,"語音文件不合法",Toast.LENGTH_LONG).show();
return;
}
if(position
!=
lastPosition){
//點(diǎn)擊不同條目先停止動(dòng)畫
重置音頻資源
stopAnimation();
MediaManager.reset();
}
if(mAdapter!=null)
mAdapter.selectItem(position,
lastPosition);
lastPosition
=
position;
id_iv_voice.setBackgroundResource(R.drawable.animation_voice);
animationDrawable
=
(AnimationDrawable)
id_iv_voice.getBackground();
if(MediaManager.isPlaying()){
stopAnimation();
MediaManager.pause();
}else
if(MediaManager.isPause()){
startAnimation();
MediaManager.resume();
}else{
startAnimation();
MediaManager.playSound(this,videoPath,
new
MediaPlayer.OnCompletionListener()
{
@Override
public
void
onCompletion(MediaPlayer
mp)
{
LogUtil.e("onCompletion","播放完成");
stopAnimation();
MediaManager.stop();
}
});
}
}
//核心方法
//點(diǎn)擊了某一個(gè)條目
這個(gè)條目isSelect=true
上一個(gè)條目isSelect需要改為false
防止滑動(dòng)過程中
幀動(dòng)畫復(fù)用問題
public
void
selectItem(int
position,
int
lastPosition)
{
LogUtil.e("selectItem","
;lastPosition="+lastPosition+"
;position="+position);
if(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度商務(wù)樓簡(jiǎn)易租房合同
- 二零二五年度新型城鎮(zhèn)化住宅安全建設(shè)合同
- 2025年度餐飲行業(yè)員工勞動(dòng)合同范本及操作細(xì)則
- 2025年度民事糾紛和解協(xié)議書與后續(xù)訴訟風(fēng)險(xiǎn)防范合同
- 2025年度電力設(shè)備維護(hù)與故障快速響應(yīng)合同
- 二零二五年度股東協(xié)議書:XX航空運(yùn)輸集團(tuán)股東權(quán)益保障及航線拓展協(xié)議
- 養(yǎng)殖場(chǎng)租賃合同(2025年度)含農(nóng)業(yè)產(chǎn)業(yè)鏈整合服務(wù)
- 二零二五年度高校學(xué)生國際貿(mào)易與物流實(shí)習(xí)合同
- 建設(shè)工程合同延期執(zhí)行申請(qǐng)書范文
- 林木采伐安全協(xié)議書與林木采伐安全合同書7篇
- 部隊(duì)花樣主食培訓(xùn)課件
- 駕駛員安全培訓(xùn)(客運(yùn))-駕駛員職業(yè)道德
- 二《市場(chǎng)調(diào)查》(課件)-【中職專用】高二語文同步課件(高教版2023·職業(yè)模塊)
- 安全總監(jiān)安全教育培訓(xùn)課件
- 主動(dòng)脈球囊反搏術(shù)患者的護(hù)理查房
- 說課的技巧和方法專題講座
- 新概念英語1一課一練全冊(cè)1-144課
- 教師專業(yè)發(fā)展與教育教學(xué)質(zhì)量提升的關(guān)系研究
- SolidWorks 2020 建模與仿真 課件全套 第1-6章 SolidWorks 2020 入門-動(dòng)畫與仿真
- 微生物技術(shù)發(fā)展史(食品微生物課件)
- 養(yǎng)老護(hù)理技術(shù)操作規(guī)范及評(píng)分標(biāo)準(zhǔn)
評(píng)論
0/150
提交評(píng)論