成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android通過流播放聲音

移動(dòng)開發(fā) Android
AudioRecord和AudioTrack類是Android獲取和播放音頻流的重要類,下面是對(duì)AudioRecord和AudioTrack類在使用方面的經(jīng)驗(yàn)總結(jié)。

AudioRecord和AudioTrack類是Android獲取和播放音頻流的重要類,放置在android.media包中。與該包中的 MediaRecorder和MediaPlayer類不同,AudioRecord和AudioTrack類在獲取和播放音頻數(shù)據(jù)流時(shí)無(wú)需通過文件保存 和文件讀取,可以動(dòng)態(tài)地直接獲取和播放音頻流,在實(shí)時(shí)處理音頻數(shù)據(jù)流時(shí)非常有用。

當(dāng)然,如果用戶只想錄音后寫入文件或從文件中取得音頻流進(jìn)行播放,那么直接使用MediaRecorder和MediaPlayer類是***方案,因?yàn)?這兩個(gè)類使用非常方便,而且成功率很高。而AudioRecord和AudioTrack類的使用卻比較復(fù)雜,我們發(fā)現(xiàn)很多人都不能成功地使用這兩個(gè)類, 甚至認(rèn)為Android的這兩個(gè)類是不能工作的。

其實(shí),AudioRecord和AudioTrack類的使用雖然比較復(fù)雜,但是可以工作,我們不僅可以很好地使用了這兩個(gè)類,而且還通過套接字 (Socket)實(shí)現(xiàn)了音頻數(shù)據(jù)的網(wǎng)絡(luò)傳輸,做到了一端使用AudioRecord獲取音頻流然后通過套接字傳輸出去,而另一端通過套接字接收后使用 AudioTrack類播放。

下面是對(duì)AudioRecord和AudioTrack類在使用方面的經(jīng)驗(yàn)總結(jié):

(1)創(chuàng)建AudioRecord和AudioTrack類對(duì)象:創(chuàng)建這兩個(gè)類的對(duì)象比較復(fù)雜,通過對(duì)文檔的反復(fù)和仔細(xì)理解,并通過多次失敗的嘗試,并在 北理工的某個(gè)Android大牛的網(wǎng)上的文章啟發(fā)下,我們也最終成功地創(chuàng)建了這兩個(gè)類的對(duì)象。創(chuàng)建AudioRecord和AudioTrack類對(duì)象的 代碼如下:

AudioRecord類:

  1. m_in_buf_size =AudioRecord.getMinBufferSize(8000
  2. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  3. AudioFormat.ENCODING_PCM_16BIT); 
  4.  
  5.  
  6. m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC,8000
  7. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  8. AudioFormat.ENCODING_PCM_16BIT, 
  9. m_in_buf_size) ;  

AudioTrack類:

  1. m_out_buf_size = android.media.AudioTrack.getMinBufferSize(8000
  2. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  3. AudioFormat.ENCODING_PCM_16BIT); 
  4.  
  5.  
  6. m_out_trk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000
  7. AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT, 
  8. m_out_buf_size, 
  9. AudioTrack.MODE_STREAM);  

(2)關(guān)于AudioRecord和AudioTrack類的監(jiān)聽函數(shù),不用也行。

(3)調(diào)試方面,包括初始化后看logcat信息,以確定類的工作狀態(tài),初始化是否成功等。

編寫好代碼,沒有語(yǔ)法錯(cuò)誤,調(diào)用模擬器運(yùn)行、調(diào)試代碼時(shí),logcat發(fā)揮了很好的功用。剛調(diào)試時(shí),經(jīng)常會(huì)出現(xiàn)模擬器顯示出現(xiàn)異常,這時(shí)我們可以在代碼 的一些關(guān)鍵語(yǔ)句后添加如Log.d(“test1″,”OK”);這樣的語(yǔ)句進(jìn)行標(biāo)識(shí),出現(xiàn)異常時(shí)我們就可以在logcat窗口觀察代碼執(zhí)行到哪里出現(xiàn)異 常,然后進(jìn)行相應(yīng)的修改、調(diào)試。模擬器不會(huì)出現(xiàn)異常時(shí),又遇到了錄放音的問題。錄音方面,剛開始選擇將語(yǔ)音編碼數(shù)據(jù)存放在多個(gè)固定大小的文件中進(jìn)行傳送, 但是這種情況下會(huì)出現(xiàn)聲音斷續(xù)的現(xiàn)象,而且要反復(fù)的建立文件,比較麻煩,后來想到要進(jìn)行網(wǎng)上傳輸,直接將語(yǔ)音編碼數(shù)據(jù)以數(shù)據(jù)流的形式傳送,經(jīng)過驗(yàn)證,這種 方法可行并且使代碼更加簡(jiǎn)潔。放音方面,將接收到的數(shù)據(jù)流存放在一個(gè)數(shù)組中,然后將數(shù)組中數(shù)據(jù)寫到AudioTrack中。剛開始只是“嘟”幾聲,經(jīng)過檢 查發(fā)現(xiàn)只是把數(shù)據(jù)寫一次,加入循環(huán),讓數(shù)據(jù)反復(fù)寫到AudioTrack中,就可以聽到正常的語(yǔ)音了。接下來的工作主要是改善話音質(zhì)量與話音延遲,在進(jìn)行 通話的過程中,觀察logcat窗口,發(fā)現(xiàn)向數(shù)組中寫數(shù)據(jù)時(shí)會(huì)出現(xiàn)Bufferflow的情況,于是把重心轉(zhuǎn)移到數(shù)組大小的影響上,經(jīng)過試驗(yàn),發(fā)現(xiàn) AudioRecord一次會(huì)讀640個(gè)數(shù)據(jù),然后就對(duì)錄音和放音中有數(shù)組的地方進(jìn)行實(shí)驗(yàn)修改。AudioRecord和AudioTrack進(jìn)行實(shí)例化 時(shí),參數(shù)中各有一個(gè)數(shù)組大小,經(jīng)過試驗(yàn)這個(gè)數(shù)組大小和AudioRecord和AudioTrack能正常實(shí)例化所需的最小Buffer大小(即上面實(shí)例 化時(shí)的m_in_buf_size和m_out_buf_size參數(shù))相等且服務(wù)器方進(jìn)行緩存數(shù)據(jù)的數(shù)組尺寸是上述數(shù)值的2倍時(shí),語(yǔ)音質(zhì)量***。由于錄 音和放音的速度不一致,受到北理工大牛的啟發(fā),在錄音方面,將存放錄音數(shù)據(jù)的數(shù)組放到LinkedList中,當(dāng)LinkedList中數(shù)組個(gè)數(shù)達(dá)到 2(這個(gè)也是經(jīng)過試驗(yàn)驗(yàn)證話音質(zhì)量***時(shí)的數(shù)據(jù))時(shí),將先錄好的數(shù)組中數(shù)據(jù)傳送出去。經(jīng)過上述反復(fù)試驗(yàn)和修改,最終使雙方通話質(zhì)量較好,且延時(shí)較短。

(4)通過套接字傳輸和接收數(shù)據(jù)

數(shù)據(jù)傳送部分,使用的是套接字。通信雙方,通過不同的端口向服務(wù)器發(fā)送請(qǐng)求,與服務(wù)器連接上后,開始通話向服務(wù)器發(fā)送數(shù)據(jù),服務(wù)器通過一個(gè)套接字接收到一 方的數(shù)據(jù)后,先存在一個(gè)數(shù)組中,然后將該數(shù)組中數(shù)據(jù)以數(shù)據(jù)流的形式再通過另一個(gè)套接字傳送到另一方。這樣就實(shí)現(xiàn)了雙方數(shù)據(jù)的傳送。

(5)代碼架構(gòu)

為避免反復(fù)錄入和讀取數(shù)據(jù)占用較多資源,使程序在進(jìn)行錄放音時(shí)不能執(zhí)行其他命令,故將錄音和放音各寫成一個(gè)線程類,然后在主程序中,通過MENU控制通話的開始、停止、結(jié)束。

***說明,AudioRecord和AudioTrack類可以用,只是稍微復(fù)雜些。以下貼出雙方通信的源碼,希望對(duì)大家有所幫助:

主程序

  1. package eoe.demo; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5. import android.view.Menu; 
  6. import android.view.MenuItem; 
  7.  
  8. public class Daudioclient extends Activity { 
  9.  
  10. public static final int MENU_START_ID = Menu.FIRST ; 
  11. public static final int MENU_STOP_ID = Menu.FIRST + 1 ; 
  12. public static final int MENU_EXIT_ID = Menu.FIRST + 2 ; 
  13.  
  14. protected Saudioserver m_player ; 
  15. protected Saudioclient m_recorder ; 
  16.  
  17. @Override 
  18. public void onCreate(Bundle savedInstanceState) { 
  19. super.onCreate(savedInstanceState); 
  20. setContentView(R.layout.main); 
  21.  
  22. public boolean onCreateOptionsMenu(Menu aMenu) 
  23. boolean res = super.onCreateOptionsMenu(aMenu) ; 
  24.  
  25. aMenu.add(0, MENU_START_ID, 0, “START”) ; 
  26. aMenu.add(0, MENU_STOP_ID, 0, “STOP”) ; 
  27. aMenu.add(0, MENU_EXIT_ID, 0, “EXIT”) ; 
  28.  
  29. return res ; 
  30. public boolean onOptionsItemSelected(MenuItem aMenuItem) 
  31. switch (aMenuItem.getItemId()) { 
  32. case MENU_START_ID: 
  33. m_player = new Saudioserver() ; 
  34. m_recorder = new Saudioclient() ; 
  35.  
  36. m_player.init() ; 
  37. m_recorder.init() ; 
  38.  
  39. m_recorder.start() ; 
  40. m_player.start() ; 
  41.  
  42. break ; 
  43. case MENU_STOP_ID: 
  44. m_recorder.free() ; 
  45. m_player.free() ; 
  46.  
  47. m_player = null ; 
  48. m_recorder = null ; 
  49. break ; 
  50. case MENU_EXIT_ID: 
  51. int pid = android.os.Process.myPid() ; 
  52. android.os.Process.killProcess(pid) ; 
  53. break ; 
  54. default
  55. break ; 
  56.  
  57. return super.onOptionsItemSelected(aMenuItem); 

錄音程序Saudioclient:

  1. package eoe.demo; 
  2.  
  3. import java.io.DataOutputStream; 
  4. import java.io.IOException; 
  5. import java.net.Socket; 
  6. import java.net.UnknownHostException; 
  7. import java.util.LinkedList; 
  8.  
  9. import android.media.AudioFormat; 
  10. import android.media.AudioRecord; 
  11. import android.media.MediaRecorder; 
  12. import android.util.Log; 
  13.  
  14. public class Saudioclient extends Thread 
  15.  
  16. protected AudioRecord m_in_rec ; 
  17. protected int m_in_buf_size ; 
  18. protected byte [] m_in_bytes ; 
  19. protected boolean m_keep_running ; 
  20. protected Socket s; 
  21. protected DataOutputStream dout; 
  22. protected LinkedList<byte[]> m_in_q ; 
  23.  
  24. public void run() 
  25. try 
  26. byte [] bytes_pkg ; 
  27. m_in_rec.startRecording() ; 
  28. while(m_keep_running) 
  29. m_in_rec.read(m_in_bytes, 0, m_in_buf_size) ; 
  30. bytes_pkg = m_in_bytes.clone() ; 
  31. if(m_in_q.size() >= 2
  32. dout.write(m_in_q.removeFirst() , 0, m_in_q.removeFirst() .length); 
  33. m_in_q.add(bytes_pkg) ; 
  34.  
  35. m_in_rec.stop() ; 
  36. m_in_rec = null ; 
  37. m_in_bytes = null ; 
  38. dout.close(); 
  39.  
  40. catch(Exception e) 
  41. e.printStackTrace(); 
  42.  
  43. public void init() 
  44. m_in_buf_size = AudioRecord.getMinBufferSize(8000
  45. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  46. AudioFormat.ENCODING_PCM_16BIT); 
  47.  
  48. m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC, 
  49. 8000
  50. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  51. AudioFormat.ENCODING_PCM_16BIT, 
  52. m_in_buf_size) ; 
  53.  
  54. m_in_bytes = new byte [m_in_buf_size] ; 
  55.  
  56. m_keep_running = true ; 
  57. m_in_q=new LinkedList<byte[]>(); 
  58.  
  59. try 
  60. s=new Socket(“192.168.1.100″,4332); 
  61. dout=new DataOutputStream(s.getOutputStream()); 
  62. //new Thread(R1).start(); 
  63. catch (UnknownHostException e) 
  64. // TODO Auto-generated catch block 
  65. e.printStackTrace(); 
  66. catch (IOException e) 
  67. // TODO Auto-generated catch block 
  68. e.printStackTrace(); 
  69.  
  70.  
  71. public void free() 
  72. m_keep_running = false ; 
  73. try { 
  74. Thread.sleep(1000) ; 
  75. catch(Exception e) { 
  76. Log.d(“sleep exceptions…\n”,”") ; 

放音程序Saudioserver:

  1. package eoe.demo; 
  2.  
  3. import java.io.DataInputStream; 
  4. import java.io.IOException; 
  5. import java.net.Socket; 
  6.  
  7. import android.media.AudioFormat; 
  8. import android.media.AudioManager; 
  9. import android.media.AudioTrack; 
  10. import android.util.Log; 
  11.  
  12. public class Saudioserver extends Thread 
  13. protected AudioTrack m_out_trk ; 
  14. protected int m_out_buf_size ; 
  15. protected byte [] m_out_bytes ; 
  16. protected boolean m_keep_running ; 
  17. private Socket s; 
  18. private DataInputStream din; 
  19. public void init() 
  20. try 
  21. s=new Socket(“192.168.1.100″,4331); 
  22. din=new DataInputStream(s.getInputStream()); 
  23.  
  24. m_keep_running = true ; 
  25.  
  26. m_out_buf_size = AudioTrack.getMinBufferSize(8000
  27. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  28. AudioFormat.ENCODING_PCM_16BIT); 
  29.  
  30. m_out_trk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000
  31. AudioFormat.CHANNEL_CONFIGURATION_MONO, 
  32. AudioFormat.ENCODING_PCM_16BIT, 
  33. m_out_buf_size, 
  34. AudioTrack.MODE_STREAM); 
  35.  
  36. m_out_bytes=new byte[m_out_buf_size]; 
  37.  
  38. // new Thread(R1).start(); 
  39.  
  40. catch(Exception e) 
  41. e.printStackTrace(); 
  42.  
  43. public void free() 
  44. m_keep_running = false ; 
  45. try { 
  46. Thread.sleep(1000) ; 
  47. catch(Exception e) { 
  48. Log.d(“sleep exceptions…\n”,”") ; 
  49.  
  50. public void run() 
  51. byte [] bytes_pkg = null ; 
  52. m_out_trk.play() ; 
  53. while(m_keep_running) { 
  54. try 
  55. din.read(m_out_bytes); 
  56. bytes_pkg = m_out_bytes.clone() ; 
  57. m_out_trk.write(bytes_pkg, 0, bytes_pkg.length) ; 
  58. catch(Exception e) 
  59. e.printStackTrace(); 
  60.  
  61.  
  62. m_out_trk.stop() ; 
  63. m_out_trk = null ; 
  64. try { 
  65. din.close(); 
  66. catch (IOException e) { 
  67. // TODO Auto-generated catch block 
  68. e.printStackTrace(); 
責(zé)任編輯:徐川 來源: OSChina
相關(guān)推薦

2011-07-22 15:59:15

iPhone 聲音 文件

2013-06-14 17:28:11

Windows PhoWP開發(fā)播放聲音

2010-01-11 17:30:40

VB.NET播放聲音

2011-08-08 10:23:41

iPhone 流播放 文件

2018-08-17 22:00:22

Linux輸出設(shè)備音頻

2009-09-22 14:20:39

C#播放聲音

2018-08-16 14:40:53

Linux輸出設(shè)備播放聲音

2013-04-08 09:31:05

iOS開發(fā)系統(tǒng)聲音服務(wù)

2013-05-21 14:10:11

Android游戲開發(fā)SoundPool類同時(shí)多音效

2022-06-01 08:21:24

Java內(nèi)存API

2013-05-21 13:33:02

Android游戲開發(fā)異步音樂播放

2010-09-01 08:40:38

蘋果Apple TV

2020-02-20 20:51:09

FedoraLinux播放音樂

2020-09-28 06:50:02

DuerOS 智能語(yǔ)音

2009-04-22 08:57:25

Windows 7微軟操作系統(tǒng)

2018-05-18 14:12:41

Chrome 66自動(dòng)播放

2010-01-07 18:22:40

VB.NET聲音播放

2010-01-13 11:03:13

VB.NET聲音播放

2010-02-20 09:48:59

Windows 7qq故障

2014-03-18 15:39:36

Fedora屏幕亮度
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91精品国产美女在线观看 | 在线视频一区二区三区 | 久久久久亚洲精品中文字幕 | 亚洲免费在线观看视频 | 国产不卡一区在线观看 | 国产精品欧美一区二区三区 | 嫩草视频在线 | 久草青青草 | 国产黄色在线观看 | 日日操操| 精精精精xxxx免费视频 | 美女艹b | 国产精品久久一区二区三区 | 国产视频中文字幕 | 国产精品久久久 | 精品国产一区探花在线观看 | 亚洲国产一区二区三区 | 日韩在线播放第一页 | 视频二区| 亚洲成人av在线播放 | 九九九久久国产免费 | 国产区视频在线观看 | 羞羞视频在线观看免费观看 | 午夜ww| 欧美人人| 中文字幕亚洲在线 | 一区二区三区免费看 | 久久69精品久久久久久久电影好 | 日韩一| 99亚洲精品 | 久久国产高清 | 国产精品99久久久久久www | 97视频人人澡人人爽 | 免费黄色片在线观看 | 国产一区二区三区四区hd | 午夜男人视频 | 波多野结衣中文视频 | 欧美三区| 免费a网 | 久久国产高清 | 四虎影视1304t |