从socket继续读取音频流

时间:2015-06-14 08:33:17

标签: android sockets bluetooth stream

我正在创建一个应用程序,我需要读取以字节数组形式发送的连续声音流。服务器端记录这样的声音(基于SO的示例):

    // Get the minimum buffer size required for the successful creation of an AudioRecord object.
    int bufferSizeInBytes = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING);
    bufferSizeInBytes = 30000;

    // Initialize Audio Recorder.
    _audio_recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RECORDER_SAMPLERATE,
            RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSizeInBytes);

    // Start Recording.
    _audio_recorder.startRecording();

    int numberOfReadBytes = 0;
    byte audioBuffer[] = new byte[bufferSizeInBytes];
    boolean recording = false;
    float tempFloatBuffer[] = new float[3];
    int tempIndex = 0;
    byte totalByteBuffer[] = new byte[60 * 44100 * 2];
while (true)
{
    float totalAbsValue = 0.0f;
    short sample = 0;

    numberOfReadBytes = _audio_recorder.read(audioBuffer, 0, bufferSizeInBytes);

    for (int i = 0; i < bufferSizeInBytes; i += 2)
    {
        sample = (short) ((audioBuffer[i]) | audioBuffer[i + 1] << 8);
        totalAbsValue += Math.abs(sample) / (numberOfReadBytes / 2);
    }

    tempFloatBuffer[tempIndex % 3] = totalAbsValue;
    float temp = 0.0f;

    for (int i = 0; i < 3; ++i)
        temp += tempFloatBuffer[i];

    if ((temp >= 0 && temp <= _sensitivity) && recording == false)
    {
        Log.i("TAG", "1");
        tempIndex++;
        continue;
    }

    if (temp > _sensitivity && recording == false)
    {
        Log.i("TAG", "2");
        recording = true;
    }

    if(temp < _sensitivity && recording == true)
    {
        recording = false;
        continue;
    }

    for (int i = 0; i < numberOfReadBytes; i++)
        totalByteBuffer[i] = audioBuffer[i];

    if (prepare_sound(totalByteBuffer, numberOfReadBytes))
    {
        totalByteBuffer = new byte[60 * 44100 * 2];

        tempIndex++;
    }
}

此示例取自录制声音,并在没有更多声音要录制时将其保存到文件中。另一方面,我的目标是在有声时录制声音,并在录制时即时发送声音。因此,我想要发送声音,而不是在没有更多声音要记录时将其存储到文件中。到目前为止,我将byte []与数据一起存储并存储在一个对象中,并使用ObjectOutputStream将其发送给客户端。然后,客户端将创建一个临时声音文件并使用MediaPlayer播放它。但我觉得这不是达到目标最有效的方法。那么,有没有更有效的方法来发送连续的数据流,因为媒体播放器不支持播放纯字节[]数据?

感谢您的帮助和提示!

1 个答案:

答案 0 :(得分:0)

发现对我来说最好的解决方案是录制声音,当缓冲区已满时,它会被发送到客户端。然后,客户端使用AudioTrack实例播放包含如下数据的byte []:

public void onSoundReceived(byte[] sound)
{
    _audio_input_stream.write(sound, 0, sound.length);
}

这也使声音更加“不滞后”#34;因为这不是一个MediaPlayer实例,它会在每次播放数据后停止声音。