本文實例為大家分享了Android實現語音播放與錄音的具體代碼,供大家參考,具體內容如下
項目用到的技術點和亮點
- 語音錄音 (單個和列表)
- 語音播放(單個和列表)
- 語音錄音封裝
- 語音播放器封裝
- 語音列表順序播放
- 語音列表單個播放 復用問題處理
因為安裝原生錄音不能錄mp3格式文件 而mp3格式是安卓和ios公用的,所以我們需要的是能直接錄取mp3文件或者錄完的格式轉成mp3格式
下面添加這個庫 能直接錄mp3文件,我覺得是最方便的
compile ‘com.czt.mp3recorder:library:1.0.3'
1. 語音錄音封裝
代碼簡單 自己看吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
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; // 標識MediaRecorder準備完畢 private AudioManage(String dir) { mDir = dir; LogUtil.e( "AudioManage=" ,mDir); } /** * 回調“準備完畢” * @author zlc */ public interface AudioStateListenter { void wellPrepared(); // prepared完畢 } public AudioStateListenter mListenter; public void setOnAudioStateListenter(AudioStateListenter audioStateListenter) { mListenter = audioStateListenter; } /** * 使用單例實現 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; } /** * 準備錄音 */ 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可以實現錄音和錄像。需要嚴格遵守API說明中的函數調用先后順序. mRecorder = new MP3Recorder(file); mCurrentFilePath = file.getAbsolutePath(); // mMediaRecorder = new MediaRecorder(); // mCurrentFilePath = file.getAbsolutePath(); // mMediaRecorder.setOutputFile(file.getAbsolutePath()); // 設置輸出文件 // mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 設置MediaRecorder的音頻源為麥克風 // mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB); // 設置音頻的格式 // mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 設置音頻的編碼為AMR_NB // mMediaRecorder.prepare(); // mMediaRecorder.start(); mRecorder.start(); //開始錄音 isPrepared = true ; // 準備結束 if (mListenter != null ) { mListenter.wellPrepared(); } } catch (Exception e) { e.printStackTrace(); LogUtil.e( "prepareAudio" ,e.getMessage()); } } /** * 隨機生成文件名稱 * @return */ private String GenerateFileName() { // TODO Auto-generated method stub return UUID.randomUUID().toString() + ".mp3" ; // 音頻文件格式 } /** * 獲得音量等級——通過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. 語音播放器封裝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
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 { //詳見“MediaPlayer”調用過程圖 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繼續 */ 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. 語音列表順序播放
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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某一個條目的圖片控件 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) { //播放完停止動畫 重置MediaManager stopAnimation(); MediaManager.reset(); playVoice(position + 1 , "loop" ); } }); } } |
4. 語音列表單個播放 復用問題處理
播放邏輯基本同上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
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){ //點擊不同條目先停止動畫 重置音頻資源 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(); } }); } } //核心方法 //點擊了某一個條目 這個條目isSelect=true 上一個條目isSelect需要改為false 防止滑動過程中 幀動畫復用問題 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); } } /** * 適配器圖片播放的動畫處理 */ private void setVoiceAnimation(ImageView iv_voice, FendaListInfo.ObjsEntity obj) { //處理動畫復用問題 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); } } |
5.下載地址
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/rjgcszlc/article/details/78036010