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