Android錄音播放管理工具
1、語音播放直接用系統(tǒng)工具就好了,這個就不多說了,根據傳入的路徑(網絡路徑或本地路徑均可)播放音頻文件
/**
* 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");
// 網絡上的媒體文件
// 例如: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設置聲音來源。
* MediaRecorder.AudioSource這個內部類詳細的介紹了聲音來源。
* 該類中有許多音頻來源,不過最主要使用的還是手機上的麥克風,MediaRecorder.AudioSource.MIC
*/
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
/**
* mediaRecorder.setOutputFormat代表輸出文件的格式。該語句必須在setAudioSource之后,在prepare之前。
* OutputFormat內部類,定義了音頻輸出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR……等。
*/
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
/**
* mediaRecorder.setAddioEncoder()方法可以設置音頻的編碼
* AudioEncoder內部類詳細定義了兩種編碼:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB
*/
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
/**
* 設置錄音之后,保存音頻文件的位置,一般是SD卡的位置
*/
mediaRecorder.setOutputFile(String.valueOf(PathManger.getVoicePath()));
/**
* 調用start開始錄音之前,一定要調用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、配置轉換工具包(這個比較簡單,配置以下文件即可)
添加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格式..............................................
/**構造時候需要的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;
/**是否轉換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;
}
/**停止錄音,并且轉換文件,這很可能是個耗時操作,建議在后臺中做*/
public boolean stop_mp3() {
if (!isRecording) {
return isRecording;
}
// 停止
mRecorder.stop();
isRecording = false;
//TODO
// 開始轉換
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();
}
}
/**關閉,可以先調用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);
}
/**設置路徑,第一個為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命令,并等待結果*/
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、最后在自己想調用的地方調用就好了,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()));
}
});
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android源碼中final關鍵字的用法及final,finally,finalize的區(qū)別
Android的源碼中很多地方對final關鍵字的用法很是“別出心裁”,之所以這么說是因為我從沒看過是這么使用final關鍵字的,通過本文給大家分享Android源碼中final關鍵字的用法及final,finally,finalize的區(qū)別,感興趣的朋友一起學習吧2015-12-12
Android?EventBus粘性事件實現(xiàn)機制探究
最近項目做組件化,需要進行組件化的通信,有時候可能會出現(xiàn)異步的情況,事件接收方還沒準備好事件就已經發(fā)送過來了,這時候想到了EventBus的粘性事件,這篇文章主要給大家介紹了關于Android?EventBus粘性事件實現(xiàn)機制的相關資料,需要的朋友可以參考下2022-05-05
Android編程記錄ListView標記行狀態(tài)的方法
這篇文章主要介紹了Android編程記錄ListView標記行狀態(tài)的方法,結合實例分析了ListView標記的相關實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11

