如何构建低延迟音频流android应用程序



我们正在尝试将实时音频记录从手机的麦克风流式传输到服务器,但遇到200ms的延迟,并希望将其最小化。

是否有一个好的API/有效的方法或协议来做到这一点?我们考虑过使用SIP/RTP协议,它会更有效吗?

这是代码,你有什么建议修改的吗?
package com.awesome.audiostream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button startButton,stopButton;
public byte[] buffer;
public static DatagramSocket socket;
private int port=12345;
AudioRecord recorder;
private int sampleRate = 176400;
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
private boolean status = true;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
View mv = getLayoutInflater().inflate(R.layout.activity_main, null);
setContentView(mv);
startButton = (Button) findViewById (R.id.start_button);
stopButton = (Button) findViewById (R.id.stop_button);
startButton.setOnClickListener (startListener);
stopButton.setOnClickListener (stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = false;
recorder.release();
Log.d("VS","Recorder released");
}
};
private final OnClickListener startListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = true;
startStreaming();
}
};
public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket();
Log.d("VS", "Socket Created");
byte[] buffer = new byte[minBufSize];
Log.d("VS","Buffer created of size " + minBufSize);
DatagramPacket packet;
// The IP address of the server receiving the audio stream
final InetAddress destination = InetAddress.getByName("192.168.43.204");
Log.d("VS", "Address retrieved");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize*10);
Log.d("VS", "Recorder initialized");
recorder.startRecording();
while(status) {
//reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);
//putting buffer in the packet
packet = new DatagramPacket (buffer,buffer.length,destination,port);
socket.send(packet);
System.out.println("MinBufferSize: " +minBufSize);
}
} catch(UnknownHostException e) {
Log.e("VS", "UnknownHostException");
} catch (IOException e) {
e.printStackTrace();
Log.e("VS", "IOException");
}
}
});
streamThread.start();
}
}

回答晚了,但是,它可能是值得的,Android的主要瓶颈通常是音频捕获最小缓冲区大小,没有多少设备能够提供小缓冲区。你得到了什么值?

关于api,如果你还没有,你可能想看看这个文档:

https://developer.android.com/ndk/guides/audio/audio-latency

然后在接收端有缓冲,以补偿无法满足所需音频比特率的瞬间高网络负载:这是延迟和流稳定性之间的权衡,缓冲区运行不足将转化为声音伪影。你需要选择一个传输协议,一个编解码器和一个媒体播放器,让你最小化缓冲。

最新更新