2012-11-20 21 views
3

我正在开发语音应用程序。在队列中记录语音<byte[]>并将其发送到服务器

我需要某种缓冲队列,以便我在一个线程中连续记录,将缓冲区充满字节放入队列并发送到服务器,然后从队列中取下一个缓冲区。

这里是记录代码:

 Queue<byte[]> qArray = new LinkedList<byte[]>(); 
    recordingThread = new Thread(new Runnable() { 

     @Override 
     public void run() { 

      bData = new byte[BufferElements]; 

      while (isRecording) { 
       recorder.read(bData, 0, BufferElements); 
       qArray.add(bData); 
       if (AudioRecord.ERROR_INVALID_OPERATION != 0) { 
        SendAudio(); 

       } 

      } 
     } 
    }, "AudioRecorder Thread"); 
    recordingThread.start(); 

但还是缺了几个字节[]数据的同时发送给服务器

这里是发送语音服务器代码:

  try { 
      HttpClient httpclient = new DefaultHttpClient(); 


      HttpPost httppost = new HttpPost(ServerUrl.url_audio); 

      // Json Format 
      JSONObject holder = new JSONObject(); 
      JSONArray jArray = new JSONArray(); 
      try { 

       byte[] tmparr = qArray.poll(); 
       for (int i = 0; i < tmparr.length; i++) { 
        jArray.put(i, tmparr[i]); 
       } 

       holder.put("Voice", jArray); 

我不想错过任何正在录制的数据。

任何帮助将不胜感激。谢谢

回答

3

当您将一个字节[]放入队列中时,您需要创建一个新的缓冲区。否则,下一个记录将覆盖相同的缓冲区。只是移动的bData初始化进入循环:

Queue<byte[]> qArray = new LinkedList<byte[]>(); 
recordingThread = new Thread(new Runnable() { 

    @Override 
    public void run() { 
     while (isRecording) { 
      bData = new byte[BufferElements]; 
      recorder.read(bData, 0, BufferElements); 
      qArray.add(bData); 
      if (AudioRecord.ERROR_INVALID_OPERATION != 0) { 
       SendAudio(); 
      } 
     } 
    } 
}, "AudioRecorder Thread"); 
recordingThread.start(); 

您还应该添加逻辑来限制队列的大小。如果队列溢出,您仍然会丢失数据,但至少您不会因内存不足错误而崩溃。

编辑这里是一个修改版本的记录循环,做了适当的错误检查。它采用的Queue<ByteBuffer>代替Queue<byte[]>

public void run() { 
    bData = ByteBuffer.allocate(BufferElements); 
    while (isRecording && !isInterrupted()) { 
     int result = recorder.read(bData, 0, BufferElements); 
     if (result > 0) { 
      qArray.add(bData); 
      SendAudio(); 
      bData = ByteBuffer.allocate(BufferElements); 
     } else if (result == AudioRecord.ERROR_INVALID_OPERATION) { 
      Log.e("Recording", "Invalid operation error"); 
      break; 
     } else if (result == AudioRecord.ERROR_BAD_VALUE) { 
      Log.e("Recording", "Bad value error"); 
      break; 
     } else if (result == AudioRecord.ERROR) { 
      Log.e("Recording", "Unknown error"); 
      break; 
     } 
     try { 
      Thread.sleep(50); 
     } catch (InterruptedException e) { 
      break; 
     } 
    } 
} 

当然,地方你就需要调用recorder.startRecording()否则你不会得到任何数据。

+0

它在发送音频数据时不工作......如果我在while循环中移动它,它将所有空值发送到服务器 –

+0

@GMRamesh - 如果调试,是否从队列中检索到所有的空值? –

+0

是的,即使在调试模式也显示空值 –

相关问题