androidaudiotrack播放
『壹』 Android播放音頻AudioManager踩坑
問題描述:某些APP會調用該介面實現靜音鈴聲播放或將手機切換為振鈴模式的功能,用戶在使用此類APP進行上述兩種操作中任意一種後,會導致手機系統中所有與鈴聲相關音頻都會被靜音,用戶接收不到鈴聲、手機提示音等,嚴重影響用戶使用體驗。
建議:非聲音設置類型的應用不調用setRingerMode介面,交由手機系統控制。
問題描述:語音社交類APP為滿足用戶語音外放的需求,會調用此介面,但若未在播放結束後,將該介面參數設置為false,會導致之後語音和通話音頻流會一直被強制從揚聲器輸出,影響用戶使用其他APP。
建議:一旦APP調用了setSpeakerphoneOn(此時參數為true),
在播放音頻流結束後,需要設置setSpeakerphoneOn參數為false,把音頻通路還原。
問題描述:該介面會使得用戶在使用APP時,靜音了某個音頻流後,手機中已安裝的其他APP,其相應類型的音頻流都會被設置為靜音。
建議:setStreamMute介面即將被廢除,建議開發者使用相應音頻實例對應的調節音量參數來實現靜音APP自身播放的音頻流的功能,例如:AudioTrack實例中的setVolume;MediaPlayer實例中的setVolume;mPlayer.setVolume(0)。
問題描述:在不同的使用場景,用戶會有調節不同音頻流音量的需求,APP可以調用介面setStreamVolume(int streamType, int index, int flags)來滿足這一需求,但往往開發者並沒有將streamType參數與當前場景正在播放的音頻流類型設置一致,並且該介面可以截獲系統的音量按鍵,導致用戶使用APP時,按音量鍵調節音量後,當前的聲音音量大小卻沒有變化。
建議:
(1)當前vivo手機系統已經可以實現智能識別用戶調節音量的場景,並且精準定位用戶需要調節的音頻流類型,因此建議音量按鍵交由手機系統來控制。
(2)如若開發者需要調節特定音量,要使用setStreamVolume介面,請設置好符合用戶需求場景的正確音頻流類型。
問題描述:當前很多APP(常見於社交類)使用這個介面來設置手機通話模式,改變手機聲音的輸出設備。用戶在使用APP時,使用「語音通話模式」(AudioManager.MODE_IN_COMMUNICATION)後,手機會默認從聽筒輸出音頻,導致用戶聽不見手機提示音、來電鈴聲等音頻。
建議:開發過程中,需要注意在播放音頻流結束後,調用介面setMode (AudioManager. MODE_NORMAL),把手機模式還原為正常模式。
問題描述:當用戶需要聲音從藍牙輸出時,某些APP會使用藍牙Sco-link通路來傳送語音數據到藍牙耳機。如果開發者沒有使用startBluetoothSco成功建立 sco-link連接通路後就直接調用setBluetoothScoOn(true
),會使得藍牙耳機無聲音輸出。
建議:開發者應使用startBluetoothSco和stopBluetoothSco介面來建立/斷開sco-link連接通路,在建立sco-link連接後,有場景需要將音頻從藍牙切換到手機上時候,調用setBluetoothScoOn(false),再次將音頻切換回藍牙播放時,使用setBluetoothScoOn(true)。
問題描述:某些社交/直播類APP會調用該介面實現語音靜音發送的功能,但有些開發者在APP退出的時候沒有設置介面為unmute,導致後續其他APP使用手機麥克風錄制出來的音頻都是靜音狀態的,影響用戶的使用。
建議:由於這個介面直接作用在手機的底層麥克風數據通路,影響范圍很大,不建議使用這個介面來實現語音靜音發送的需求。開發者可以通過將APP獲取到的音頻數據直接替換為值=0(靜音)的方式,或採取把錄制上來的數據直接丟棄不處理的方式來實現這種需求。
『貳』 Android AudioTrack詳解
我們知道播放聲音能夠用MediaPlayer和AudioTrack,MediaPlayer會在framework層創建相應的音頻解碼器。而AudioTrack僅僅能播放已經解碼的PCM流,MediaPlayer在framework層還是會創建AudioTrack,把解碼後的PCM數流傳遞給AudioTrack。AudioTrack再傳遞給AudioFlinger進行混音,然後才傳遞給硬體播放,所以是MediaPlayer包括了AudioTrack
每個音頻流相應著一個AudioTrack類的一個實例,每個AudioTrack會在創建時注冊到 AudioFlinger中。由AudioFlinger把全部的AudioTrack進行混合(Mixer)。然後輸送到AudioHardware中進行播放。眼下Android同一時候最多能夠創建32個音頻流,也就是說。Mixer最多會同一時候處理32個AudioTrack的數據流。
在4000到48000之間
AudioTrack有兩種數據載入模式:
1.MODE_STREAM
在這樣的模式下,應用程序持續地write音頻數據流到AudioTrack中,而且write動作將堵塞直到數據流從java層傳輸到native層,同一時候增加到播放隊列中。這樣的模式適用於播放大音頻數據,但該模式也造成了一定的延時;
2.MODE_STATIC
在播放之前,先把全部數據一次性write到AudioTrack的內部緩沖區中。適用於播放內存佔用小、延時要求較高的音頻數據。
『叄』 Android 如何生成一個音頻的正弦聲音信號, 並通過AudioTrack連續不間斷播放
參考答案: 女兒年幾十五六,窈窕無雙顏如玉。
『肆』 android audiotrack 可以播放什麼格式
播放mp3的總是噪音,不知道原因,後來播放wav的倒是可以,
wav是沒有壓縮的pcm
Java代碼
package com.lp;
import java.io.IOException; import java.io.InputStream;
import android.app.Activity; import android.content.Context;
import android.media.AudioFormat; import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.AudioTrack.;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button play;
private Button stop;
private AudioTrack at;
private AudioManager am; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
play = (Button)findViewById(R.id.main_play);
stop = (Button)findViewById(R.id.main_stop);
play.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(am.isSpeakerphoneOn()){
am.setSpeakerphoneOn(false);
}
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
am.setMode(AudioManager.MODE_IN_CALL); System.out.println(am.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL));
System.out.println("&&&&&&&&&&&&&"); System.out.println(am.getStreamVolume(AudioManager.STREAM_VOICE_CALL)); int bufferSizeInBytes = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); if(at==null){
at = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
System.out.println("22222");
new AudioTrackThread().start();
}else{
if(at.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){
System.out.println("111111111");
}else{
System.out.println("33333");
at = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
new AudioTrackThread().start();
}
} }
});
stop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
at.stop();
at.release();
am.setMode(AudioManager.MODE_NORMAL);
}
});
}
class AudioTrackThread extends Thread{
@Override
public void run() {
byte[] out_bytes = new byte[44100];
InputStream is = getResources().openRawResource(R.raw.start);
int length ;
at.play();
try {
while((length = is.read(out_bytes))!=-1){
System.out.println(length);
at.write(out_bytes, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
if(at.getPlayState()==AudioTrack.PLAYSTATE_PLAYING){
at.stop();
at.release();
am.setMode(AudioManager.MODE_NORMAL);
}
}
}
}
『伍』 Android音頻播放
最近需要在Android的客戶端中使用PCM聲音播放和錄制,簡單學習了一下。有不正確的地方還請指出。
首先有幾個概念需要了解一下:采樣頻率、聲道數、采樣位數。
采樣頻率一般是sample rate, 代表的是數字化音頻時每秒采樣的次數。常見的有44.1KHz(CD品質)、48KHz等。
這個很好理解,單聲道Mono就是聲音從一個方向傳出來;雙聲道Stereo也叫立體聲,聲音是從兩個方向傳來。通常的流行音樂中,仔細聽能發現每個聲道可能側重不同的樂曲聲部,比如左聲道吉他,右聲道鋼琴,人聲似乎兩個聲道都有,聽起來就像站在中間一樣。(這里沒有考證,隨便舉例)
每一個采樣都是一個數據點,采樣位數是指這個數據點使用了幾位來記錄。AudioTrack類只支持8位和16位的PCM音頻。8位就是2的8次方,即256個值;而16位則是2的16次方,有65536個值。
這個在音頻的編解碼中還是比較常用的。在PCM格式中,1秒鍾音頻的數據大小是SampleRate×Channel×Bit/8,單位是byte位元組。由於PCM本身沒有音頻幀的概念,所以通過這個公式就能計算出任意時長音頻的大小,或者得到任意大小音頻的時長。如果規定1個音頻幀是「每個聲道256個采樣」,雙聲道下就是512個采樣,那麼1幀的數據量就是256×Channel×Bit/8,同理可以推斷出1秒鍾有多少音頻幀等等。音頻幀的概念在各種編解碼中各有不同,但計算公式大同小異,這里不展開。
Android中音頻的播放使用的是AudioTrack類,具體用法非常簡單。
首先設置buffer大小。AudioTrack播放時需要先寫入buffer,如果這個buffer沒有寫滿,那麼這部分是不會播放的。所以buffer不能設置太小,這樣會導致播放不連貫;而buffer也不能設置太小,這樣不間斷寫入會消耗許多CPU資源。AudioTrack自帶了getMinBufferSize方法可以給出一個最小buffer,一般用這個值就可以。getMinBufferSize方法三個參數分別是sample rate、channel和bit。
設置完buffer size就可以實例化一個AudioTrack。其中第一個參數streamType是指不同的音頻流類型,包括STREAM_MUSIC、STREAM_ALARM、STREAM_VOICE_CALL、STREAM_RING等,是Android對不同音頻的分類。中間三個參數很好理解,第四個是buffer size,剛剛計算出來了。最後一個參數mode有兩種:MODE_STREAM和MODE_STATIC。前者是以流形式播放,後者則是一次性全部寫入然後播放。
調用實例的play()方法就可以開始播放了。不過播放得要有數據吧?要填寫數據就要用到write()方法。write方法中第一個參數是一個byte[]類型,是要寫入的數據源,可以是從文件流中讀取出來的;第二個參數offset是初始位移,即從source的哪個位置開始;第三個參數則是輸入長度。
當write方法寫滿一個AudioTrack的buffer時,就會有聲音播放出來了。
當播放完成後記得要把AudioTrack停止並釋放。
『陸』 Android音視頻【十二】使用OpenSLES和AudioTrack進行播放PCM
本節我們學習下如何播放pcm數據,在Android中有兩種方法:一種是使用java層的 AudioTrack 方法,一種是使用底層的 OpenSLES 直接在 jni 層調用系統的 OpenSLES的c方法 實現。
兩種使用場景不一樣:
AudioTrack 一般用於 比如本地播放一個pcm文件/流,又或者播放解碼後的音頻的pcm流,API較簡單。
OpenSLES 一般用於一些播放器中開發中,比如音頻/視頻播放器,聲音/音頻的播放採用的OpenSLES,一是播放器一般是c/c++實現,便於直接在c層調用OpenSLES的API,二也是如果用AudioTrack進行播放,務必會帶來java和jni層的反射調用的開銷,API較復雜。
可以根據業務自行決定來進行選擇。
AudioTrack的方式使用較簡單,直接在java層。
指定采樣率,采樣位數,聲道數進行創建。
其中44100是采樣率, AudioFormat.CHANNEL_OUT_STEREO 為雙聲道,還有 CHANNEL_OUT_MONO 單聲道。 AudioFormat.ENCODING_PCM_16BIT 為采樣位數16位,還有 ENCODING_PCM_8BIT 8位。 minBufferSize 是播放器緩沖的大小,也是根據采樣率和采樣位數,聲道數 進行獲取,只有滿足最小的buffer才去操作底層進程播放。
最後一個參數mode。可以指定的值有 AudioTrack.MODE_STREAM 和 AudioTrack.MODE_STATIC 。
MODE_STREAM 適用於大多數的場景,比如動態的處理audio buffer,或者播放很長的音頻文件,它是將audio buffers從java層傳遞到native層。音頻播放時音頻數據從Java流式傳輸到native層的創建模式。
MODE_STATIC 適用場景,比如播放很短的音頻,它是一次性將全部的音頻資源從java傳遞到native層。音頻數據在音頻開始播放前僅從Java傳輸到native層的創建模式。
是的,就這么一個方法。注意此方法是同步方法,是個耗時方法,一般是開啟一個線程循環調用 write 方法進行寫入。
注意在調用 write 方法前需要調用 audioTrack.play() 方法開始播放。
因為是pcm裸數據,無法像mediaplayer一樣提供了API。所以需要自己處理下。可以利用 getPlaybackHeadPosition 方法。
getPlaybackHeadPosition() 的意思是返回以幀為單位表示的播放頭位置
getPlaybackRate() 的意思是返回以Hz為單位返回當前播放采樣率。
所以當前播放時間可以通過如下方式獲取
OpenSLES:(Open Sound Library for Embedded Systems).
OpenSLES是跨平台是針對嵌入式系統精心優化的硬體音頻加速API。使用OpenSLES進行音頻播放的好處是可以不依賴第三方。比如一些音頻或者視頻播放器中都是用OpenSLES進行播放解碼後的pcm的,這樣免去了和java層的交互。
在Android中使用OpenSLES首先需要把Android 系統提供的so鏈接到外面自己的so。在CMakeLists.txt腳本中添加鏈接庫OpenSLES。庫的名字可以在 類似如下目錄中
需要去掉lib
然後導入頭文件即可使用了OpenSLES提供的底層方法了。
創建&使用的步驟大致分為:
一個 SLObjectItf 裡面可能包含了多個Interface,獲取Interface通過 GetInterface 方法,而 GetInterface 方法的地2個參數 SLInterfaceID 參數來指定到的需要獲取Object裡面的那個Interface。比如通過指定 SL_IID_ENGINE 的類型來獲取 SLEngineItf 。我們可以通過 SLEngineItf 去創建各種Object,例如播放器、錄音器、混音器的Object,然後在用這些Object去獲取各種Interface去實現各種功能。
如上所說,SLEngineItf可以創建混音器的Object。
在創建播放器前需要創建音頻的配置信息(比如采樣率,聲道數,每個采樣的位數等)
開始播放後會不斷的回調這個 pcmBufferCallBack 函數將音頻數據壓入隊列
(*pcmBufferQueue)->RegisterCallback(pcmBufferQueue, pcmBufferCallBack, this);
如果想要暫停播放參數直接設置為SL_PLAYSTATE_PAUSED,若暫停後繼續播放設置參數為SL_PLAYSTATE_PLAYING即可。若想要停止播放參數設置為SL_PLAYSTATE_STOPPED即可。
首先獲取播放器的用於控制音量的介面SLVolumeItf pcmVolumePlay
然後動態設置
首先也是獲取播放器的用於控制音量的介面SLMuteSoloItf pcmMutePlay
然後動態設置
看起來控制還是蠻簡單的哈。先熟悉這么多,OpenSLES還是蠻強大的。
https://github.com/ta893115871/PCMPlay
『柒』 android AudioTrack.play怎麼判斷播放完成
根據你的描述:
audioTrack.getPlayState() == AudioTrack.PLAYSTATE_STOPPED;
希望能幫助到你。
『捌』 android點擊播放為什麼出現Error creating AudioTrack
android soundpool 沒有聲音可能是系統故障,解決方法為:
1、備份重要數據,對手機進行恢復出廠設置。
2、在專業人士指導下刷機,具體步驟為:
a、打開「刷機助手」官方網站,在頁面中下載刷機助手。下載完成後安裝並啟動刷機助手。
b、用手機原裝數據線將手機與電腦相連接,然後等待刷機助手完成初始化工作。待刷機助手成功識別手機後,可以點擊「一鍵刷機」按鈕開始刷機。
c、點擊「瀏覽」按鈕選擇之前下載的刷機包,若沒有下載可以使用刷機助手市場下載ROM包。選擇手機對應的型號開始下載ROM。
d、選擇刷機包後點擊「下一步」按鈕備份手機數據,以免數據丟失。備份開始前,在手機中允許刷機助手讀取簡訊、聯系人等記錄。然後點擊「刷機」按鈕開始備份並刷機,慢慢等待刷機完成。
3、到手機維修店維修。
『玖』 Android MediaCodec 編碼後解碼播放出來聲音變了。
也遇到了,還沒找到解決方法
『拾』 android audiotrack同時播放
把他寫到service裡面,開啟兩次service就好了,mediaPlayer底層代碼也是用service管理的