您好,登錄后才能下訂單哦!
小編給大家分享一下Android中播放器MediaPlayer如何實現均衡器效果,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
具體如下:
這幾天在系統學習Android官方API Demos,看到實現均衡器效果,就把官方API中代碼copy下來,根據網上前輩的指引略有修改,添加了注釋。
public class AudioFxDemo extends Activity { private static final String TAG = "AudioFxDemo"; private static final float VISUALIZER_HEIGHT_DIP = 50f; // 定義播放器 private MediaPlayer mMediaPlayer; // 定義系統的頻譜 private Visualizer mVisualizer; // 定義系統的均衡器 private Equalizer mEqualizer; private LinearLayout mLinearLayout; private VisualizerView mVisualizerView; private TextView mStatusTextView; @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); // 音量控制 setVolumeControlStream(AudioManager.STREAM_MUSIC); mStatusTextView = new TextView(this); mLinearLayout = new LinearLayout(this); mLinearLayout.setOrientation(LinearLayout.VERTICAL); mLinearLayout.addView(mStatusTextView); setContentView(mLinearLayout); // 創建MediaPlayer對象 mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr); Log.d(TAG, "MediaPlayer audio session ID: " + mMediaPlayer.getAudioSessionId()); // 設置頻譜顯示 setupVisualizerFxAndUI(); // 設置示波器顯示 setupEqualizerFxAndUI(); // Make sure the visualizer is enabled only when you actually want to // receive data, and // when it makes sense to receive data. mVisualizer.setEnabled(true); // When the stream ends, we don't need to collect any more data. We // don't do this in // setupVisualizerFxAndUI because we likely want to have more, // non-Visualizer related code // in this callback. mMediaPlayer .setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mediaPlayer) { mVisualizer.setEnabled(false); mStatusTextView.setText("播放結束"); } }); mMediaPlayer.start(); mStatusTextView.setText("正在播放中"); } private void setupEqualizerFxAndUI() { // Create the Equalizer object (an AudioEffect subclass) and attach it // to our media player, // with a default priority (0). mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId()); mEqualizer.setEnabled(true); TextView eqTextView = new TextView(this); eqTextView.setText("Equalizer:"); mLinearLayout.addView(eqTextView); short bands = mEqualizer.getNumberOfBands(); final short minEQLevel = mEqualizer.getBandLevelRange()[0]; final short maxEQLevel = mEqualizer.getBandLevelRange()[1]; for (short i = 0; i < bands; i++) { final short band = i; TextView freqTextView = new TextView(this); freqTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); freqTextView.setGravity(Gravity.CENTER_HORIZONTAL); freqTextView.setText((mEqualizer.getCenterFreq(band) / 1000) + " Hz"); mLinearLayout.addView(freqTextView); LinearLayout row = new LinearLayout(this); row.setOrientation(LinearLayout.HORIZONTAL); TextView minDbTextView = new TextView(this); minDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); minDbTextView.setText((minEQLevel / 100) + " dB"); TextView maxDbTextView = new TextView(this); maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); maxDbTextView.setText((maxEQLevel / 100) + " dB"); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); layoutParams.weight = 1; SeekBar bar = new SeekBar(this); bar.setLayoutParams(layoutParams); bar.setMax(maxEQLevel - minEQLevel); bar.setProgress(mEqualizer.getBandLevel(band)); bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { mEqualizer.setBandLevel(band, (short) (progress + minEQLevel)); } public void onStartTrackingTouch(SeekBar seekBar) { } public void onStopTrackingTouch(SeekBar seekBar) { } }); row.addView(minDbTextView); row.addView(bar); row.addView(maxDbTextView); mLinearLayout.addView(row); } } private void setupVisualizerFxAndUI() { // Create a VisualizerView (defined below), which will render the // simplified audio // wave form to a Canvas. mVisualizerView = new VisualizerView(this); mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, (int) (VISUALIZER_HEIGHT_DIP * getResources() .getDisplayMetrics().density))); mLinearLayout.addView(mVisualizerView); // Create the Visualizer object and attach it to our media player. mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId()); mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]); mVisualizer.setDataCaptureListener( new Visualizer.OnDataCaptureListener() { public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { mVisualizerView.updateVisualizer(bytes); } public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { } }, Visualizer.getMaxCaptureRate() / 2, true, false); } @Override protected void onPause() { super.onPause(); if (isFinishing() && mMediaPlayer != null) { mVisualizer.release(); mEqualizer.release(); mMediaPlayer.release(); mMediaPlayer = null; } } } /** * 繪制波狀View * * @description: * @author ldm * @date 2016-4-20 上午9:11:49 */ class VisualizerView extends View { // 數組保存了波形抽樣點的值 private byte[] bytes; private float[] points; // 定義畫筆 private Paint paint = new Paint(); // 矩形區域 private Rect rect = new Rect(); private byte type = 0; public VisualizerView(Context context) { super(context); bytes = null; // 設置畫筆的屬性 paint.setStrokeWidth(1f);// 設置空心線寬 paint.setAntiAlias(true);// 抗鋸齒 paint.setColor(Color.BLUE);// 畫筆顏色 paint.setStyle(Style.STROKE);// 非填充模式 } public void updateVisualizer(byte[] ftt) { bytes = ftt; // 通知組件重繪 invalidate(); } @Override public boolean onTouchEvent(MotionEvent me) { // 當用戶觸碰該組件時,切換波形類型 if (me.getAction() != MotionEvent.ACTION_DOWN) { return false; } type++; if (type >= 3) { type = 0; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (bytes == null) { return; } // 繪制黑色背景 canvas.drawColor(Color.BLACK); // 使用rect對象記錄該組件的寬度和高度 rect.set(0, 0, getWidth(), getHeight()); switch (type) { // 繪制塊狀的波形圖 case 0: for (int i = 0; i < bytes.length - 1; i++) { float left = getWidth() * i / (bytes.length - 1); // 根據波形值計算該矩形的高度 float top = rect.height() - (byte) (bytes[i + 1] + 128) * rect.height() / 128; float right = left + 1; float bottom = rect.height(); canvas.drawRect(left, top, right, bottom, paint); } break; // 繪制柱狀的波形圖(每隔18個抽樣點繪制一個矩形) case 1: for (int i = 0; i < bytes.length - 1; i += 18) { float left = rect.width() * i / (bytes.length - 1); // 根據波形值計算該矩形的高度 float top = rect.height() - (byte) (bytes[i + 1] + 128) * rect.height() / 128; float right = left + 6; float bottom = rect.height(); canvas.drawRect(left, top, right, bottom, paint); } break; // -繪制曲線波形圖 case 2: // 如果point數組還未初始化 if (points == null || points.length < bytes.length * 4) { points = new float[bytes.length * 4]; } for (int i = 0; i < bytes.length - 1; i++) { // 計算第i個點的x坐標 points[i * 4] = rect.width() * i / (bytes.length - 1); // 根據bytes[i]的值(波形點的值)計算第i個點的y坐標 points[i * 4 + 1] = (rect.height() / 2) + ((byte) (bytes[i] + 128)) * 128 / (rect.height() / 2); // 計算第i+1個點的x坐標 points[i * 4 + 2] = rect.width() * (i + 1) / (bytes.length - 1); // 根據bytes[i+1]的值(波形點的值)計算第i+1個點的y坐標 points[i * 4 + 3] = (rect.height() / 2) + ((byte) (bytes[i + 1] + 128)) * 128 / (rect.height() / 2); } // 繪制波形曲線 canvas.drawLines(points, paint); break; } } }
自己新建 項目時,記得在res/raw下添加一個名為test_cbr的mp3格式文件。
以上是“Android中播放器MediaPlayer如何實現均衡器效果”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。