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

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

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

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

音樂

主要

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

1. 基礎(chǔ)準(zhǔn)備

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

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

<!--波紋視圖-->
<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)權(quán)限管理, 在啟動頁面時, 獲取應(yīng)用所需的音頻權(quán)限.
RendererFactory工廠類創(chuàng)建波紋的繪制類SimpleWaveformRender.
startVisualiser方法獲取當(dāng)前播放音樂的音頻信息.
注意頁面關(guān)閉, 在onPause時, 釋放Visualiser類.

public class MainActivity extends AppCompatActivity {
private static final int CAPTURE_SIZE = 256; // 獲取這些數(shù)據(jù), 用于顯示
private static final int REQUEST_CODE = 0;
// 權(quán)限
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();
}
}
// 設(shè)置音頻線
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, 獲取波紋數(shù)量; setEnabled, 啟動監(jiān)聽;
setDataCaptureListener, 第一個參數(shù)是回調(diào), 使用WaveFormData或FftData; 第二個是更新率; 第三個是判斷使用WaveFormData; 第四個是判斷使用FftData, 第三\四個均與回調(diào)的返回值有關(guān).

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); // 數(shù)組復(fù)制
invalidate(); // 設(shè)置波紋之后, 需要重繪
}
@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mRenderer != null) {
mRenderer.render(canvas, mWaveform);
}
}
}

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

4. 波紋邏輯

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

/**
* 波紋渲染邏輯
* <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); // 設(shè)置寬度
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();
// 沒有數(shù)據(jù)
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); // 水平塊數(shù)
float yIncrement = height / Y_FACTOR; // 豎直塊數(shù)
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); // 最后的點(diǎn), 水平居中
}
// 居中畫一條直線
private void renderBlank(float width, float height) {
int y = (int) (height * HALF_FACTOR);
mWaveformPath.moveTo(0, y);
mWaveformPath.lineTo(width, y);
}
}

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

動畫效果

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

相關(guān)文章

  • android實現(xiàn)簡單拼圖游戲

    android實現(xiàn)簡單拼圖游戲

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

    Android微信右滑退出功能的實現(xiàn)代碼

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

    Android實現(xiàn)通話最小化懸浮框效果

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

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

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

    Android Service的啟動過程分析

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

    Android App中實現(xiàn)簡單的刮刮卡抽獎效果的實例詳解

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

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

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

    Android 大文件切割與合并的實現(xiàn)代碼

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

    Android自定義view倒計時60秒

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

    Android Dialog對話框用法實例詳解

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

最新評論