2012-05-26 64 views
3

我正嘗試在Android上建立點對點音頻呼叫。我使用了一部android手機和一部平板電腦進行通信,但在接收到大約40個數據包後,手機幾乎停止接收數據包,然後突然收到幾個數據包並播放它們等等,但是這種等待時間增加了。類似地,平板電腦最初接收數據包並播放它們,但是滯後增加,並且在一段時間之後語音也開始中斷,就好像有些數據包丟失一樣。任何想法是什麼造成這個問題...Android上的點對點音頻呼叫:語音中斷和延遲(延遲接收數據包)增加

這是應用程序的代碼...我只是在RecordAudio類中給予發件人和接收者的IP地址,而在兩個設備上運行它。

public class AudioRPActivity extends Activity implements OnClickListener { 

    DatagramSocket socketS,socketR; 
    DatagramPacket recvP,sendP; 
    RecordAudio rt; 
    PlayAudio pt; 

    Button sr,stop,sp; 
    TextView tv,tv1; 
    File rf; 

    boolean isRecording = false; 
    boolean isPlaying = false; 

    int frequency = 44100; 
    int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; 
    int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     tv = (TextView)findViewById(R.id.text1); 
     tv1 = (TextView)findViewById(R.id.text2); 

     sr = (Button)findViewById(R.id.sr); 
     sp = (Button)findViewById(R.id.sp); 
     stop = (Button)findViewById(R.id.stop); 

     sr.setOnClickListener(this); 
     sp.setOnClickListener(this); 
     stop.setOnClickListener(this); 

     stop.setEnabled(false); 

     try 
     { 
     socketS=new DatagramSocket(); 
     socketR=new DatagramSocket(6000); 
     } 
     catch(SocketException se) 
     { 
      tv.setText(se.toString()); 
      finish(); 
     } 
    } 

    public void onClick(View v) { 

     if(v == sr) 
      record(); 
     else if(v == sp) 
      play(); 
     else if(v == stop) 
      stopPlaying(); 
    } 

    public void play() 
    { 
     stop.setEnabled(true); 
     sp.setEnabled(false); 
     pt = new PlayAudio(); 
     pt.execute(); 
    } 

    public void stopPlaying() 
    { 
     isRecording=false; 
     isPlaying = false; 
     stop.setEnabled(false); 
    } 

    public void record() 
    { 
     stop.setEnabled(true); 
     sr.setEnabled(false); 
     rt = new RecordAudio(); 
     rt.execute(); 
    } 



    private class PlayAudio extends AsyncTask<Void,String,Void> 
    { 

     @Override 
     protected Void doInBackground(Void... arg0) 
     { 
      isPlaying = true; 
      int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding); 

      byte[] audiodata = new byte[bufferSize]; 

      try 
      { 
       AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,channelConfiguration, 
                 audioEncoding,4*bufferSize,AudioTrack.MODE_STREAM); 
       audioTrack.setPlaybackRate(frequency); 
       audioTrack.play(); 

       while(isPlaying) 
       { 
        recvP=new DatagramPacket(audiodata,audiodata.length); 
        socketR.receive(recvP); 
        audioTrack.write(recvP.getData(), 0, recvP.getLength()); 
       } 
       audioTrack.stop(); 
       audioTrack.release(); 
      } 
      catch(Throwable t) 
      { 
       Log.e("Audio Track","Playback Failed"); 
      } 
      return null; 
     } 
     protected void onProgressUpdate(String... progress) 
     { 
      tv1.setText(progress[0].toString()); 
     } 

     protected void onPostExecute(Void result) 
     { 
      sr.setEnabled(true); 
      sp.setEnabled(true); 
     } 

    } 

    private class RecordAudio extends AsyncTask<Void,String,Void> 
    { 

     @Override 
     protected Void doInBackground(Void... arg0) 
     { 
      isRecording = true; 

      try 
      { 
       int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding); 

       AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequency,channelConfiguration 
                  ,audioEncoding,4*bufferSize); 
       byte[] buffer = new byte[bufferSize]; 
       audioRecord.startRecording(); 
       int r=0; 
       while(isRecording) 
       { 
        int brr = audioRecord.read(buffer,0,bufferSize); 

        sendP=new DatagramPacket(buffer,brr,InetAddress.getByName("sender's/receiver's ip"),6000); 
        socketS.send(sendP); 
        publishProgress(String.valueOf(r)); 

        r++; 
       } 

       audioRecord.stop(); 
       audioRecord.release(); 

      } 
      catch(Throwable t) 
      { 
       Log.e("AudioRecord","Recording Failed...."); 
      } 


      return null; 
     } 

     protected void onProgressUpdate(String... progress) 
     { 
      tv.setText(progress[0].toString()); 
     } 

     protected void onPostExecute(Void result) 
     { 
      sr.setEnabled(true); 
      sp.setEnabled(true); 
     } 
    } 
} 
+0

你在使用哪些設備? 2.3/3.0/4.0? – Jens

+0

我是android 2.3平臺。 – user1415385

回答

1

當通過網絡發送語音時,我遇到了麻煩,如果它只是8000的頻率。 44100聽起來很可怕。這可能只是爲了我的情況。

另一個困難是,使用UDP很難說數據包以何種順序進入。我看到一個實現將它們按正確的順序放回,但現在找不到它。