我试图从麦克风流音频从 1 Android 到另一个通过 WiFi。看了一些例子后,我做了 2 个应用程序与每个单一的活动,1 捕获和发送音频和其他接收。
我已经使用 Audiorecord 和 Audiotrack 类捕获和播放。但是,我只是听到一些噼啪声(虽然我恢复了一些变化,但现在已经停止)
要发送语音的活动。
public class VoiceSenderActivity extends Activity {
private EditText target;
private TextView streamingLabel;
private Button startButton,stopButton;
public byte[] buffer;
public static DatagramSocket socket;
private int port=50005; //which port??
AudioRecord recorder;
//Audio Configuration.
private int sampleRate = 8000; //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
target = (EditText) findViewById (R.id.target_IP);
streamingLabel = (TextView) findViewById(R.id.streaming_label);
startButton = (Button) findViewById (R.id.start_on);
stopButton = (Button) findViewById (R.id.stop_on);
streamingLabel.setText("Press Start! to begin");
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 {
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
DatagramSocket socket = new DatagramSocket();
Log.d("VS", "Socket Created");
byte[] buffer = new byte[minBufSize];
Log.d("VS","Buffer created of size " + minBufSize);
DatagramPacket packet;
final InetAddress destination = InetAddress.getByName(target.getText().toString());
Log.d("VS", "Address retrieved");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,channelConfig,audioFormat,minBufSize);
Log.d("VS", "Recorder initialized");
recorder.startRecording();
while(status == true) {
//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);
}
} catch(UnknownHostException e) {
Log.e("VS", "UnknownHostException");
} catch (IOException e) {
Log.e("VS", "IOException");
}
}
});
streamThread.start();
}
}
要接收语音的活动
public class VoiceReceiverActivity extends Activity {
private Button receiveButton,stopButton;
public static DatagramSocket socket;
private AudioTrack speaker;
//Audio Configuration.
private int sampleRate = 8000; //How much will be ideal?
private int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
receiveButton = (Button) findViewById (R.id.receive_on);
stopButton = (Button) findViewById (R.id.stop_on);
findViewById(R.id.receive_label);
receiveButton.setOnClickListener(receiveListener);
stopButton.setOnClickListener(stopListener);
}
private final OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View v) {
status = false;
speaker.release();
Log.d("VR","Speaker released");
}
};
private final OnClickListener receiveListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = true;
startReceiving();
}
};
public void startReceiving() {
Thread receiveThread = new Thread (new Runnable() {
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(50005);
Log.d("VR", "Socket Created");
byte[] buffer = new byte[256];
//minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced
int minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
speaker = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate,channelConfig,audioFormat,minBufSize,AudioTrack.MODE_STREAM);
speaker.play();
while(status == true) {
try {
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
Log.d("VR", "Packet Received");
//reading content from packet
buffer=packet.getData();
Log.d("VR", "Packet data read into buffer");
//sending data to the Audiotrack obj i.e. speaker
speaker.write(buffer, 0, minBufSize);
Log.d("VR", "Writing buffer content to speaker");
} catch(IOException e) {
Log.e("VR","IOException");
}
}
} catch (SocketException e) {
Log.e("VR", "SocketException");
}
}
});
receiveThread.start();
}
}
我使用 wireshark 来检查数据包是否正在发送,我可以看到数据包。然而,源是发送设备的 MAC 地址和目的地也像物理地址。不知道这是否相关。
有什么问题吗?
Hey there is an Open Source library called“Libstreaming”that is used for streaming voice / video over the network using WIFI.Just Have a look at it:
https://github.com/fyhertz/libstreaming还提供了一些例子,请看一下:
https://github.com/fyhertz/libstreaming-examples我已经使用该库通过网络流式传输 RTSP 音频,希望它可能有用。
我试着把问题分成三个部分。
Part1通过注释与音频相关的所有内容,确保Socket Connection工作正常
Part2只需从发送方发送任意文本消息 [Hello WiFi],然后在接收方应用程序中接收并打印它。
Part3录音机是否实际工作?尝试在单独的项目中测试您的录制方式,看看它是否正常工作。
使用this代码捕获麦克风并播放它。
我的经验
我曾经在一个类似的项目,并测试它,我所做的是记录后,我写的记录的音频数据作为 SD 卡上的文件
(这将是原始音频,所以大多数音乐播放器将无法播放它...我猜 mPlayer 应该播放它)
您需要仔细考虑使用 UDP(DatagramSocket 类)作为网络协议。
UDP 是一种轻量级协议,不能保证保持接收到的数据包的顺序。这可能是音频乱码的部分原因。无序接收的数据包将导致音频数据包无序播放。在这些乱序数据包的边界,您将听到音频样本实际上已损坏的点击 / 弹出。除此之外,不能保证 UDP 数据包能够成功传递。任何丢失的数据包显然会增加任何乱码。
TCP (套接字类) 将是最佳音频质量的更好选择。TCP 是一种更健壮的协议,它将保持接收数据包的顺序。它还具有内置的错误检查功能,并将重新发送任何丢弃的数据包。但是,由于这种引人注目的功能,TCP 的网络开销更高。
我开始这个回应说,你需要仔细考虑你使用哪种协议,这是因为有一个使用的情况取决于什么对你很重要..
如果你想要超低延迟播放,但很乐意牺牲音频质量,那么 UDP 将起作用。但是,需要一些实验才能找到最佳的缓冲区和样本大小。
如果你想要最好的音频再现零失真,但很乐意引入更多的延迟,那么 TCP 是要走的路。
我不能说 TCP 会增加多少延迟。但有可能它可以在不影响用户体验的情况下实现。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(70条)