Android錄音播放管理工具
1、語音播放直接用系統(tǒng)工具就好了,這個就不多說了,根據(jù)傳入的路徑(網(wǎng)絡(luò)路徑或本地路徑均可)播放音頻文件
/** * Created by zhb on 2017/1/16. * 音樂在線播放 */ public class PlayManager { private Context mcontext; public PlayManager(Context context){ this.mcontext = context; } public void play(String song){ MediaPlayer mp = new MediaPlayer(); try { // 存儲在SD卡或其他文件路徑下的媒體文件 // 例如:mp.setDataSource("/sdcard/test.mp3"); // 網(wǎng)絡(luò)上的媒體文件 // 例如:mp.setDataSource("http://www...../music/test.mp3"); mp.setDataSource(song); mp.prepare(); mp.start(); } catch (Exception e) { e.printStackTrace(); } } }
2.錄制amr格式音頻文件(微信語音便用的這種格式,至于音頻文件格式之間的比較請自行百度)
/** * Created by zhb on 2017/1/16. * 本地錄音 */ public class RecordManager { //錄制成amr格式............................................................ private Context mcontext; MediaRecorder mediaRecorder ; public RecordManager(Context context){ this.mcontext = context; //TODO 初始化安裝路徑,錄音流程 } /**開始錄制*/ public void start_amr(){ mediaRecorder = new MediaRecorder(); /** * mediaRecorder.setAudioSource設(shè)置聲音來源。 * MediaRecorder.AudioSource這個內(nèi)部類詳細的介紹了聲音來源。 * 該類中有許多音頻來源,不過最主要使用的還是手機上的麥克風,MediaRecorder.AudioSource.MIC */ mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); /** * mediaRecorder.setOutputFormat代表輸出文件的格式。該語句必須在setAudioSource之后,在prepare之前。 * OutputFormat內(nèi)部類,定義了音頻輸出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR……等。 */ mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB); /** * mediaRecorder.setAddioEncoder()方法可以設(shè)置音頻的編碼 * AudioEncoder內(nèi)部類詳細定義了兩種編碼:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB */ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); /** * 設(shè)置錄音之后,保存音頻文件的位置,一般是SD卡的位置 */ mediaRecorder.setOutputFile(String.valueOf(PathManger.getVoicePath())); /** * 調(diào)用start開始錄音之前,一定要調(diào)用prepare方法。 */ try { mediaRecorder.prepare(); mediaRecorder.start(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /**停止錄音*/ public void stop_amr(){ mediaRecorder.stop(); mediaRecorder.release(); mediaRecorder = null; } /**重置錄音*/ public void reset_amr(){ mediaRecorder.reset(); } }
3、配置轉(zhuǎn)換工具包(這個比較簡單,配置以下文件即可)
添加flame.jar,并在armeabi和armeabi-v7a文件夾添加libmp3lame.so
資源文件:http://xiazai.jb51.net/201701/yuanma/androidlibmp3lame(jb51.net).rar
4、錄制MP3格式音頻文件(個人覺得這種格式能比較好的統(tǒng)一Android端和iOS端的音頻文件,雖然方法相對比較繁雜一些)
/** * Created by zhb on 2017/1/16. * 本地錄音 */ public class RecordManager { //錄制成MP3格式.............................................. /**構(gòu)造時候需要的Activity,主要用于獲取文件夾的路徑*/ private Activity activity; /**文件代號*/ public static final int RAW = 0X00000001; public static final int MP3 = 0X00000002; /**文件路徑*/ private String rawPath = null; private String mp3Path = null; /**采樣頻率*/ private static final int SAMPLE_RATE = 11025; /**錄音需要的一些變量*/ private short[] mBuffer; private AudioRecord mRecorder; /**錄音狀態(tài)*/ private boolean isRecording = false; /**是否轉(zhuǎn)換ok*/ private boolean convertOk = false; public RecordManager(Activity activity, String rawPath, String mp3Path) { this.activity = activity; this.rawPath = rawPath; this.mp3Path = mp3Path; } /**開始錄音*/ public boolean start_mp3() { // 如果正在錄音,則返回 if (isRecording) { return isRecording; } // 初始化 if (mRecorder == null) { initRecorder(); } getFilePath(); mRecorder.startRecording(); startBufferedWrite(new File(rawPath)); isRecording = true; return isRecording; } /**停止錄音,并且轉(zhuǎn)換文件,這很可能是個耗時操作,建議在后臺中做*/ public boolean stop_mp3() { if (!isRecording) { return isRecording; } // 停止 mRecorder.stop(); isRecording = false; //TODO // 開始轉(zhuǎn)換 FLameUtils lameUtils = new FLameUtils(1, SAMPLE_RATE, 96); convertOk = lameUtils.raw2mp3(rawPath, mp3Path); return isRecording ^ convertOk;// convertOk==true,return true } /**獲取文件的路徑*/ public String getFilePath(int fileAlias) { if (fileAlias == RAW) { return rawPath; } else if (fileAlias == MP3) { return mp3Path; } else return null; } /**清理文件*/ public void cleanFile(int cleanFlag) { File f = null; try { switch (cleanFlag) { case MP3: f = new File(mp3Path); if (f.exists()) f.delete(); break; case RAW: f = new File(rawPath); if (f.exists()) f.delete(); break; case RAW | MP3: f = new File(rawPath); if (f.exists()) f.delete(); f = new File(mp3Path); if (f.exists()) f.delete(); break; } f = null; } catch (Exception e) { e.printStackTrace(); } } /**關(guān)閉,可以先調(diào)用cleanFile來清理文件*/ public void close() { if (mRecorder != null) mRecorder.release(); activity = null; } /**初始化*/ private void initRecorder() { int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); mBuffer = new short[bufferSize]; mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); } /**設(shè)置路徑,第一個為raw文件,第二個為mp3文件*/ private void getFilePath() { try { String folder = "audio_recorder_2_mp3"; String fileName = String.valueOf(System.currentTimeMillis()); if (rawPath == null) { File raw = new File(activity.getDir(folder, activity.MODE_PRIVATE), fileName + ".raw"); raw.createNewFile(); rawPath = raw.getAbsolutePath(); raw = null; } if (mp3Path == null) { File mp3 = new File(activity.getDir(folder, activity.MODE_PRIVATE), fileName + ".mp3"); mp3.createNewFile(); mp3Path = mp3.getAbsolutePath(); mp3 = null; } Log.d("rawPath", rawPath); Log.d("mp3Path", mp3Path); runCommand("chmod 777 " + rawPath); runCommand("chmod 777 " + mp3Path); } catch (Exception e) { e.printStackTrace(); } } /**執(zhí)行cmd命令,并等待結(jié)果*/ private boolean runCommand(String command) { boolean ret = false; Process process = null; try { process = Runtime.getRuntime().exec(command); process.waitFor(); ret = true; } catch (Exception e) { e.printStackTrace(); } finally { try { process.destroy(); } catch (Exception e) { e.printStackTrace(); } } return ret; } /**寫入到raw文件*/ private void startBufferedWrite(final File file) { new Thread(new Runnable() { @Override public void run() { DataOutputStream output = null; try { output = new DataOutputStream(new BufferedOutputStream( new FileOutputStream(file))); while (isRecording) { int readSize = mRecorder.read(mBuffer, 0, mBuffer.length); for (int i = 0; i < readSize; i++) { output.writeShort(mBuffer[i]); } } } catch (IOException e) { e.printStackTrace(); } finally { if (output != null) { try { output.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }).start(); } }
5、最后在自己想調(diào)用的地方調(diào)用就好了,PathManger這個是我自己的路徑管理工具,這里不貼了,反正自己直接放一個路徑字符串進去就好了
/**初始化語音*/ private void initVoice() { //錄音 RecordManager = new RecordManager( CallHelpActivity.this, String.valueOf(PathManger.getVoicePathToRaw()), String.valueOf(PathManger.getVoicePathToMp3())); callHelp_Voice_longclick.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: RecordManager.start_mp3(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: RecordManager.stop_mp3(); break; } return false; } }); //語音播放 final PlayManager PlayManager = new PlayManager(this); callHelp_Voice_click.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { PlayManager.play(String.valueOf(PathManger.getVoicePathToMp3())); } }); }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android UI實現(xiàn)底部切換標簽fragment
這篇文章主要為大家詳細介紹了Android UI實現(xiàn)底部切換標簽的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12Kotlin中的惰性操作容器Sequence序列使用原理詳解
這篇文章主要為大家介紹了Kotlin中的惰性操作容器Sequence序列使用原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09ImageView的屬性android:scaleType的作用分析
本篇文章是對ImageView的屬性android:scaleType的作用進行了詳細的分析介紹,需要的朋友參考下2013-06-06使用Compose制作抖音快手視頻進度條Loading動畫效果
這篇文章主要為大家介紹了使用Compose制作抖音快手視頻進度條Loading動畫效果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-08-08Android多功能視頻播放器GSYVideoPlayer開發(fā)流程
怎么在Android中實現(xiàn)GSYVideoPlayer視頻播放器?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲2022-11-11Android?ViewPager2?+?Fragment?聯(lián)動效果的實現(xiàn)思路
這篇文章主要介紹了Android?ViewPager2?+?Fragment?聯(lián)動,本篇主要介紹一下 ViewPager2 + Fragment聯(lián)動效果的實現(xiàn)思路,需要的朋友可以參考下2022-12-12Android旋轉(zhuǎn)、平移、縮放和透明度漸變的補間動畫
這篇文章主要實現(xiàn)Android旋轉(zhuǎn)、平移、縮放和透明度漸變的補間動畫,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2018-04-04Android實用小技巧之利用Lifecycle寫出更好維護的代碼
lifecycle是一個類,用于存儲有關(guān)組件(如Activity或Fragment)的生命周期狀態(tài)的信息,并允許其他對象觀察此狀態(tài),下面這篇文章主要給大家介紹了關(guān)于Android實用小技巧之利用Lifecycle寫出更好維護的代碼的相關(guān)資料,需要的朋友可以參考下2022-05-05