這篇文章主要介紹Android如何實(shí)現(xiàn)語(yǔ)音播放與錄音功能,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、普安網(wǎng)絡(luò)推廣、成都微信小程序、普安網(wǎng)絡(luò)營(yíng)銷、普安企業(yè)策劃、普安品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供普安建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.rwnh.cn
具體內(nèi)容如下
項(xiàng)目用到的技術(shù)點(diǎn)和亮點(diǎn)
語(yǔ)音錄音 (單個(gè)和列表)
語(yǔ)音播放(單個(gè)和列表)
語(yǔ)音錄音封裝
語(yǔ)音播放器封裝
語(yǔ)音列表順序播放
語(yǔ)音列表單個(gè)播放 復(fù)用問(wèn)題處理
因?yàn)榘惭b原生錄音不能錄mp3格式文件 而mp3格式是安卓和ios公用的,所以我們需要的是能直接錄取mp3文件或者錄完的格式轉(zhuǎn)成mp3格式
下面添加這個(gè)庫(kù) 能直接錄mp3文件,我覺(jué)得是最方便的
compile ‘com.czt.mp3recorder:library:1.0.3'
1. 語(yǔ)音錄音封裝
代碼簡(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說(shuō)明中的函數(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(); //開(kāi)始錄音 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í)——通過(guò)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. 語(yǔ)音播放器封裝
package com.video.zlc.audioplayer.utils; import android.content.Context; import android.media.AudioManager; import android.media.MediaPlayer; import android.net.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 { //詳見(jiàn)“MediaPlayer”調(diào)用過(guò)程圖 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("語(yǔ)音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. 語(yǔ)音列表順序播放
private int lastPos = -1; //播放語(yǔ)音 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,"語(yǔ)音文件不合法",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. 語(yǔ)音列表單個(gè)播放 復(fù)用問(wèn)題處理
播放邏輯基本同上
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,"語(yǔ)音文件不合法",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)過(guò)程中 幀動(dòng)畫復(fù)用問(wèn)題 public void selectItem(int position, int lastPosition) { LogUtil.e("selectItem"," ;lastPosition="+lastPosition+" ;position="+position); if(lastPosition >= 0 && lastPosition < mDatas.size() && lastPosition != position){ FendaListInfo.ObjsEntity bean = mDatas.get(lastPosition); bean.isSelect = false; mDatas.set(lastPosition, bean); notifyDataSetChanged(); } if(position < mDatas.size() && position != lastPosition){ FendaListInfo.ObjsEntity bean = mDatas.get(position); bean.isSelect = true; mDatas.set(position,bean); } } /** * 適配器圖片播放的動(dòng)畫處理 */ private void setVoiceAnimation(ImageView iv_voice, FendaListInfo.ObjsEntity obj) { //處理動(dòng)畫復(fù)用問(wèn)題 AnimationDrawable animationDrawable; if(obj.isSelect){ iv_voice.setBackgroundResource(R.drawable.animation_voice); animationDrawable = (AnimationDrawable) iv_voice.getBackground(); if(MediaManager.isPlaying() && animationDrawable!=null){ animationDrawable.start(); }else{ iv_voice.setBackgroundResource(R.drawable.voice_listen); animationDrawable.stop(); } }else{ iv_voice.setBackgroundResource(R.drawable.voice_listen); } }
以上是“Android如何實(shí)現(xiàn)語(yǔ)音播放與錄音功能”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
本文名稱:Android如何實(shí)現(xiàn)語(yǔ)音播放與錄音功能
本文URL:http://www.rwnh.cn/article42/ghccec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、品牌網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、定制開(kāi)發(fā)、網(wǎng)站建設(shè)、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)