韓奇峰高級講師
多年實戰(zhàn)工作經(jīng)驗曾參與制作寶馬Usage Training項目、DMS項目,奧迪全
息投影項目,奔馳等多家汽車門戶行業(yè)大型項目,負(fù)責(zé)UI設(shè)計、界面設(shè)計、3D模型制作、前端開發(fā)等職務(wù)。
從事設(shè)計行業(yè)多年,精通PhotoShop、UI設(shè)計、AfterEffects、Flash、
Actionscript、HTML、CSS、JavaScript、jQuery、資深動畫設(shè)計師,設(shè)計作品曾獲得全國動畫設(shè)計三等獎。
課程講解注重實戰(zhàn)應(yīng)用,對講述知識點穿插案例制作,使課程內(nèi)容更加接近
工作中實際的項目。授課風(fēng)格注重實戰(zhàn)經(jīng)驗分析,深受學(xué)生喜歡。
Java工程師就業(yè)前景
Java工程師就業(yè)前景
2015年,在美國、加拿大、澳大利亞、新加坡等發(fā)達(dá)國家和中等發(fā)達(dá)國家,
JAVA軟件工程師年薪均在4—15萬美金,而在國內(nèi),JAVA軟件工程師也有極好的工作機會和很高的薪水。
在未來5年內(nèi),合格軟件人才的需求將遠(yuǎn)大于供給。JAVA軟件工程師是目前
國際高端計算機領(lǐng)域就業(yè)薪資非常高的一類軟件工程師。
一般情況下的JAVA軟件工程師是分四個等級,從軟件技術(shù)員到助理軟件工程
師,再到軟件工程師,**后成為高級軟件工程師。
根據(jù)IDC的統(tǒng)計數(shù)字,在所有軟件開發(fā)類人才的需求中,對JAVA工程師的需
求達(dá)到全部需求量的60%—70%。同時,JAVA軟件工程師的工資待遇相對較高。
通常來說,具有3—5年開發(fā)經(jīng)驗的工程師,擁有年薪15萬元是很正常的一個
薪酬水平。80%的學(xué)生畢業(yè)后年薪都超過了8萬元。
根據(jù)專業(yè)數(shù)據(jù)分析,由于我國經(jīng)濟發(fā)展不均衡因素,JAVA軟件工程師工資待
遇在城市之間的差異也較大,一級城市(如北京、上海等),初級軟件工程師的待遇大概在4000-6000之間,中級軟件工程師的待遇在6000—8000之間,
而高級軟件工程師的待遇基本破萬。
全新升級企業(yè)需求的Java課程
歷經(jīng)16年累計10余萬Java學(xué)員。打造專業(yè)的課程體系,值得你的信賴
Java基礎(chǔ)
深入解析Java基礎(chǔ),直擊面試常見問題。——184課時
數(shù)據(jù)庫
及Web前端技術(shù)
包含主流Oracle和MySQL數(shù)據(jù)庫,先進(jìn)的Web前端技術(shù),熱門的JS語言 ——160課時
Java Web
開發(fā)及服務(wù)端框架
定制開發(fā)企業(yè)級框架,教授Spring技術(shù)核心,企業(yè)開發(fā)部署環(huán)境,規(guī)范代碼
開發(fā)流程及文檔——176課時
綜合項目實戰(zhàn)
飛揚小鳥、飛機大戰(zhàn)、俄羅斯方塊、T-DMS數(shù)據(jù)采集項目、T-netctoss項目
、云筆記系統(tǒng)——136小時2W代碼量
搭建自己網(wǎng)站
16小時課程實戰(zhàn)演練
——企業(yè)扶持
android示波器,音頻頻譜繪制
>
很久沒寫過博客作技術(shù)總結(jié)了,主要是做著這行不比做業(yè)務(wù)或者其他的,會越做越?jīng)]激情,慢慢的讓自己喪失斗志,其他的話就不多說了,在工作中就能慢慢體會到了,今天將對音頻播放方面的視圖繪制作一次總結(jié)和分享,如果有這方面經(jīng)驗或者有更好idea的同學(xué)歡迎出來指正和分享。
下面就說說這個當(dāng)播放音樂時,我們將對音頻數(shù)據(jù)進(jìn)行捕獲,然后進(jìn)行一個界面的繪制,這里我只是做了幾種類型的繪制,這里只說其中一種類型,其他2個都很簡單的算法就不論述了;
就來說說這個柱形繪制吧,先上代碼,這里只有一個界面,點擊可切換顯示模式,先看看Activity的代碼:
package com.asir.Flashview;
import android.annotation.SupPRessLint;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@SuppressLint("NewApi")
public class FlashActivity extends Activity {
// 定義播放聲音的MediaPlayer
private MediaPlayer mPlayer;
// 定義系統(tǒng)的示波器
private Visualizer mVisualizer;
private LinearLayout layout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設(shè)置控制音樂聲音
setVolumeControlStream(AudioManager.STREAM_MUSIC);
layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
// 創(chuàng)建MediaPlayer對象
mPlayer = MediaPlayer.create(this, R.raw.test);
// 初始化示波器
setupVisualizer();
// 開發(fā)播放音樂
mPlayer.start();
}
private void setupVisualizer() {
// 創(chuàng)建PlayFlashView組件,用于顯示波形圖
final PlayFlashView mVisualizerView = new PlayFlashView(this);
mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// 將MyVisualizerView組件添加到layout容器中
layout.addView(mVisualizerView);
// 以MediaPlayer的AudiosessionId創(chuàng)建Visualizer
// 相當(dāng)于設(shè)置Visualizer負(fù)責(zé)顯示該MediaPlayer的音頻數(shù)據(jù)
mVisualizer = new Visualizer(mPlayer.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
// 為mVisualizer設(shè)置監(jiān)聽器
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
// 用waveform波形數(shù)據(jù)更新mVisualizerView組件
mVisualizerView.updateVisualizer(fft);
}
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
// 用waveform波形數(shù)據(jù)更新mVisualizerView組件
mVisualizerView.updateVisualizer(waveform);
}
}, Visualizer.getMaxCaptureRate() / 2, true, false);
mVisualizer.setEnabled(true);
}
@Override
protected void onPause() {
super.onPause();
if (isFinishing() && mPlayer != null) {
// 釋放所有對象
mVisualizer.release();
mPlayer.release();
mPlayer = null;
}
}
}
然后再自定義一個view根據(jù)音頻數(shù)據(jù)來繪制視圖就好
package com.asir.flashview;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@SuppressLint("NewApi")
public class FlashActivity extends Activity {
// 定義播放聲音的MediaPlayer
private MediaPlayer mPlayer;
// 定義系統(tǒng)的示波器
private Visualizer mVisualizer;
private LinearLayout layout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 設(shè)置控制音樂聲音
setVolumeControlStream(AudioManager.STREAM_MUSIC);
layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
// 創(chuàng)建MediaPlayer對象
mPlayer = MediaPlayer.create(this, R.raw.beautiful);
// 初始化示波器
setupVisualizer();
// 開發(fā)播放音樂
mPlayer.start();
}
private void setupVisualizer() {
// 創(chuàng)建PlayFlashView組件,用于顯示波形圖
final PlayFlashView mVisualizerView = new PlayFlashView(this);
mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
// 將MyVisualizerView組件添加到layout容器中
layout.addView(mVisualizerView);
// 以MediaPlayer的AudioSessionId創(chuàng)建Visualizer
// 相當(dāng)于設(shè)置Visualizer負(fù)責(zé)顯示該MediaPlayer的音頻數(shù)據(jù)
mVisualizer = new Visualizer(mPlayer.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
// 為mVisualizer設(shè)置監(jiān)聽器
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
// 用waveform波形數(shù)據(jù)更新mVisualizerView組件
mVisualizerView.updateVisualizer(fft);
}
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
// 用waveform波形數(shù)據(jù)更新mVisualizerView組件
mVisualizerView.updateVisualizer(waveform);
}
}, Visualizer.getMaxCaptureRate() / 2, true, false);
mVisualizer.setEnabled(true);
}
@Override
protected void onPause() {
super.onPause();
if (isFinishing() && mPlayer != null) {
// 釋放所有對象
mVisualizer.release();
mPlayer.release();
mPlayer = null;
}
}
}
沒用gif錄制,就簡單上個效果圖好了:
大概就是這么一個顯示方式。
首先先對代碼思路做個解析,也方便以后自己回來使用時快速理清這個使用方法。先定義16個柱子即是16個音頻數(shù)據(jù),從回調(diào)方法中返回回來的數(shù)據(jù)長度是1024個字節(jié),這邊就利用**開始的16個字節(jié)來繪制就好了,定義兩組音頻bytes,一組是當(dāng)前獲取到的**新的字節(jié)數(shù)組,另外一組是上一次獲取到的字節(jié)數(shù)組,這些個獲取到的字節(jié)數(shù)中的每一個字節(jié)會根據(jù)音樂播放時頻率的變化而變化,這邊用**新的數(shù)據(jù)來繪制柱形圖,然后用2組bytes數(shù)據(jù)來交替繪制柱子上方的橫線,邏輯就這么一點,具體在代碼中也注釋的很清楚。主要是一個位置的問題,柱子和線的左右都可以**屏幕寬度固定好,高度跳動效果就用這個bytes就可以了,然后加一個開關(guān),當(dāng)音樂停止播放時就停止當(dāng)前的繪制,就這么點東西,至于定義畫筆,初始化數(shù)據(jù)什么的,我覺得也還真是沒什么好說的了,到此柱形顯示方式就算是實現(xiàn)了吧,
大家發(fā)揮自己的邏輯思維和使用數(shù)學(xué)不同算法去想象繪制更多炫麗的效果吧,到時記得也分享給我就好了
**后還有一個是音頻播放時的權(quán)限:
源碼點擊**
后續(xù)有激情的話,將會對我學(xué)習(xí)到的android framework層這方面的知識作個總結(jié)和分享給大家.這方面的知識我也是不太懂歡迎來一起交流心得。
相關(guān)推薦:
蘇州JAVA培訓(xùn) 蘇州JAVA培訓(xùn)班 蘇州JAVA培訓(xùn)機構(gòu)