国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android使用音頻信息繪制動態波紋

2020-04-11 10:50:11
字體:
來源:轉載
供稿:網友

在一些音樂類應用中, 經常會展示隨著節奏上下起伏的波紋信息, 這些波紋形象地傳達了聲音信息, 可以提升用戶體驗, 那么是如何實現的呢? 可以使用Visualizer類獲取當前播放的聲音信息, 并繪制在畫布上, 使用波紋展示即可. 我來講解一下使用方法.

音樂

主要

(1) Visualizer類提取波紋信息的方式.
(2) 應用動態權限管理的方法.
(3) 分離自定義視圖的展示和邏輯.

1. 基礎準備

Android 6.0引入動態權限管理, 在這個項目中, 會使用系統的音頻信息, 因此把權限管理引入這個項目, 參考. Gradle配置引入了Lambda表達式, 參考.

頁面布局, 使用自定義的波紋視圖控件.

<!--波紋視圖--><me.chunyu.spike.wcl_visualizer_demo.visualizers.WaveformViewandroid:id="@+id/main_wv_waveform"android:layout_width="match_parent"android:layout_height="match_parent"/>

效果

波紋


2. 首頁邏輯

添加動態權限管理, 在啟動頁面時, 獲取應用所需的音頻權限.
RendererFactory工廠類創建波紋的繪制類SimpleWaveformRender.
startVisualiser方法獲取當前播放音樂的音頻信息.
注意頁面關閉, 在onPause時, 釋放Visualiser類.

public class MainActivity extends AppCompatActivity {private static final int CAPTURE_SIZE = 256; // 獲取這些數據, 用于顯示private static final int REQUEST_CODE = 0;// 權限private static final String[] PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO,Manifest.permission.MODIFY_AUDIO_SETTINGS};@Bind(R.id.main_wv_waveform) WaveformView mWvWaveform; // 波紋視圖private Visualizer mVisualizer; // 音頻可視化類@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);RendererFactory rendererFactory = new RendererFactory();mWvWaveform.setRenderer(rendererFactory.createSimpleWaveformRender(ContextCompat.getColor(this, R.color.colorPrimary), Color.WHITE));}@Override protected void onResume() {super.onResume();PermissionsChecker checker = new PermissionsChecker(this);if (checker.lakesPermissions(PERMISSIONS)) {PermissionsActivity.startActivityForResult(this, REQUEST_CODE, PERMISSIONS);} else {startVisualiser();}}@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE && resultCode == PermissionsActivity.PERMISSIONS_DENIED) {finish();}}// 設置音頻線private void startVisualiser() {mVisualizer = new Visualizer(0); // 初始化mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {@Overridepublic void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {if (mWvWaveform != null) {mWvWaveform.setWaveform(waveform);}}@Overridepublic void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {}}, Visualizer.getMaxCaptureRate(), true, false);mVisualizer.setCaptureSize(CAPTURE_SIZE);mVisualizer.setEnabled(true);}// 釋放@Override protected void onPause() {if (mVisualizer != null) {mVisualizer.setEnabled(false);mVisualizer.release();}super.onPause();}}

Visualizer類

new Visualizer(0), 初始化; setCaptureSize, 獲取波紋數量; setEnabled, 啟動監聽;
setDataCaptureListener, 第一個參數是回調, 使用WaveFormData或FftData; 第二個是更新率; 第三個是判斷使用WaveFormData; 第四個是判斷使用FftData, 第三/四個均與回調的返回值有關.

3. 波紋視圖

頁面框架, 分離顯示和邏輯, 使用接口渲染, 輸入畫布Canvas和波紋Waveform.

/*** 音頻波紋視圖* <p>* Created by wangchenlong on 16/2/11.*/public class WaveformView extends View {private WaveformRenderer mRenderer; // 繪制類private byte[] mWaveform; // 波紋形狀public WaveformView(Context context) {super(context);}public WaveformView(Context context, AttributeSet attrs) {super(context, attrs);}public WaveformView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@TargetApi(21)public WaveformView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}public void setRenderer(WaveformRenderer renderer) {mRenderer = renderer;}public void setWaveform(byte[] waveform) {mWaveform = Arrays.copyOf(waveform, waveform.length); // 數組復制invalidate(); // 設置波紋之后, 需要重繪}@Override protected void onDraw(Canvas canvas) {super.onDraw(canvas);if (mRenderer != null) {mRenderer.render(canvas, mWaveform);}}}

數組復制Arrays.copyOf(), 在設置波紋后重繪頁面invalidate().

4. 波紋邏輯

核心部分renderWaveform, 渲染波紋.
把頁面分為網格樣式, 根據波紋值, 繪制曲線; 沒有波紋, 繪制居中水平直線.

/*** 波紋渲染邏輯* <p>* Created by wangchenlong on 16/2/12.*/public class SimpleWaveformRenderer implements WaveformRenderer {private static final int Y_FACTOR = 0xFF; // 2的8次方 = 256private static final float HALF_FACTOR = 0.5f;@ColorInt private final int mBackgroundColor;private final Paint mForegroundPaint;private final Path mWaveformPath;private SimpleWaveformRenderer(@ColorInt int backgroundColor, Paint foregroundPaint, Path waveformPath) {mBackgroundColor = backgroundColor;mForegroundPaint = foregroundPaint;mWaveformPath = waveformPath;}public static SimpleWaveformRenderer newInstance(@ColorInt int backgroundColor, @ColorInt int foregroundColour) {Paint paint = new Paint();paint.setColor(foregroundColour);paint.setAntiAlias(true); // 抗鋸齒paint.setStrokeWidth(8.0f); // 設置寬度paint.setStyle(Paint.Style.STROKE); // 填充Path waveformPath = new Path();return new SimpleWaveformRenderer(backgroundColor, paint, waveformPath);}@Override public void render(Canvas canvas, byte[] waveform) {canvas.drawColor(mBackgroundColor);float width = canvas.getWidth();float height = canvas.getHeight();mWaveformPath.reset();// 沒有數據if (waveform != null) {// 繪制波形renderWaveform(waveform, width, height);} else {// 繪制直線renderBlank(width, height);}canvas.drawPath(mWaveformPath, mForegroundPaint);}private void renderWaveform(byte[] waveform, float width, float height) {float xIncrement = width / (float) (waveform.length); // 水平塊數float yIncrement = height / Y_FACTOR; // 豎直塊數int halfHeight = (int) (height * HALF_FACTOR); // 居中位置mWaveformPath.moveTo(0, halfHeight);for (int i = 1; i < waveform.length; ++i) {float yPosition = waveform[i] > 0 ?height - (yIncrement * waveform[i]) : -(yIncrement * waveform[i]);mWaveformPath.lineTo(xIncrement * i, yPosition);}mWaveformPath.lineTo(width, halfHeight); // 最后的點, 水平居中}// 居中畫一條直線private void renderBlank(float width, float height) {int y = (int) (height * HALF_FACTOR);mWaveformPath.moveTo(0, y);mWaveformPath.lineTo(width, y);}}

繪制移動moveTo, 繪制直線lineTo.

動畫效果

通過繪制波紋, 可以類似地繪制一些連續數據, 更加直觀地展示, 提升用戶體驗.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 右玉县| 遂昌县| 泰州市| 榆树市| 瓮安县| 沂水县| 西乌珠穆沁旗| 沙雅县| 荣成市| 阿图什市| 夏河县| 明星| 会泽县| 铜川市| 南开区| 彰化县| 岳阳市| 建瓯市| 彭泽县| 冷水江市| 高淳县| 锦屏县| 景德镇市| 湾仔区| 余姚市| 永胜县| 礼泉县| 旌德县| 温泉县| 临桂县| 黄石市| 孝感市| 宜阳县| 嘉定区| 吴桥县| 廉江市| 玉门市| 枝江市| 贵南县| 香格里拉县| 建瓯市|