欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android使用音頻信息繪制動態(tài)波紋

 更新時間:2016年02月13日 17:13:14   作者:SpikeKing  
這篇文章主要介紹了Android使用音頻信息繪制動態(tài)波紋 的相關資料,需要的朋友可以參考下

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

音樂

主要

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

1. 基礎準備

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

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

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

效果

波紋


2. 首頁邏輯

添加動態(tài)權限管理, 在啟動頁面時, 獲取應用所需的音頻權限.
RendererFactory工廠類創(chuàng)建波紋的繪制類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; // 音頻可視化類
@Override
protected 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() {
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
if (mWvWaveform != null) {
mWvWaveform.setWaveform(waveform);
}
}
@Override
public 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, 啟動監(jiān)聽;
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次方 = 256
private 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.

動畫效果

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

相關文章

  • android實現簡單拼圖游戲

    android實現簡單拼圖游戲

    這篇文章主要為大家詳細介紹了android實現簡單拼圖游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android微信右滑退出功能的實現代碼

    Android微信右滑退出功能的實現代碼

    這篇文章主要介紹了Android微信右滑退出功能的實現代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Android實現通話最小化懸浮框效果

    Android實現通話最小化懸浮框效果

    本片內容給大家介紹了Android音視頻通話過程中最小化成懸浮框的實現的方法以及代碼寫法。
    2017-11-11
  • Android應用啟動速度優(yōu)化

    Android應用啟動速度優(yōu)化

    這篇文章主要介紹了Android應用啟動速度優(yōu)化的相關資料,需要的朋友可以參考下
    2016-01-01
  • Android Service的啟動過程分析

    Android Service的啟動過程分析

    這篇文章主要介紹了Android Service的啟動過程分析的相關資料,需要的朋友可以參考下
    2017-04-04
  • Android App中實現簡單的刮刮卡抽獎效果的實例詳解

    Android App中實現簡單的刮刮卡抽獎效果的實例詳解

    這篇文章主要介紹了Android App中實現簡單的刮刮卡抽獎效果的實例詳解,文中主要借助Bitmap的canvas.drawPath的api來實現,需要的朋友可以參考下
    2016-03-03
  • Android四大組件:Activity/Service/Broadcast/ContentProvider作用示例

    Android四大組件:Activity/Service/Broadcast/ContentProvider作用示例

    Android是一種基于Linux,自由及開放源代碼的操作系統(tǒng),Android分為四個層,從高層到底層分別是應用程序層、應用程序框架層、系統(tǒng)運行庫層和Linux內核層,Android有四大基本組件:Activity、Service服務、BroadcastReceiver廣播接收器、Content Provider內容提供者
    2023-11-11
  • Android 大文件切割與合并的實現代碼

    Android 大文件切割與合并的實現代碼

    這篇文章主要介紹了Android 大文件切割與合并,實現了很多發(fā)文件和視頻的切割,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • Android自定義view倒計時60秒

    Android自定義view倒計時60秒

    這篇文章主要為大家詳細介紹了Android自定義view倒計時60秒,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Android Dialog對話框用法實例詳解

    Android Dialog對話框用法實例詳解

    這篇文章主要介紹了Android Dialog對話框用法,結合實例形式分析了Android使用Dialog對話框過程中所涉及的創(chuàng)建、保存、回復等操作相關技巧與注意事項,需要的朋友可以參考下
    2016-07-07

最新評論