Android音频实时传输与播放(二):服务端
2015-09-25 11:51
791 查看
原文链接:http://blog.csdn.net/zgyulongfei/article/details/7750707
我偷懒就用java写了个简单的服务器,大家明白原理就好。
服务端共开放两个端口,一个udp上行端口用来接收amr音频流,另一个tcp下行端口用来发送amr音频流。
我这里写的服务端实现了组播的功能,即一个人在录音,可以同时让很多人同时听到。
简而言之,服务端做的唯一一件事情就是转发音频流,囧rz。。。
在这里,我只贴出一部分代码,后面我会上传资源供大家下载。
接收udp传送的音频码流:
[java] view
plaincopy
while (isServerRunning()) {
try {
DatagramPacket pack = new DatagramPacket(data, data.length);
udpServer.receive(pack);
addPacketToBuffer(new FramePacket(pack.getData(), pack.getLength()));
} catch (Exception e) {
System.out.println(e.toString());
}
}
用tcp转发收到的音频流:
[java] view
plaincopy
public void sendDataToAllClient() throws Exception {
if (isBufferEmpty() || clientList.size() <= 0) {
return;
}
boolean bufEmpty = isBufferEmpty();
byte[] block = takeAwayFirstFrame();
ArrayList<Integer> disConnectClient = new ArrayList<Integer>();
for (int ix = 0; ix < clientList.size(); ++ix) {
Client client = clientList.get(ix);
Socket clientSocket = client.getSocket();
if (clientSocket.isConnected()) {
try {
if (!bufEmpty) {
if (block == null) {
continue;
}
OutputStream output = clientSocket.getOutputStream();
output.write(block);
output.flush();
}
} catch (Exception err) {
disConnectClient.add(ix);
}
} else {
disConnectClient.add(ix);
}
}
for (int ix = 0; ix < disConnectClient.size(); ++ix) {
int index = disConnectClient.get(ix);
clientList.remove(index);
}
disConnectClient.clear();
disConnectClient = null;
block = null;
}
我偷懒就用java写了个简单的服务器,大家明白原理就好。
服务端共开放两个端口,一个udp上行端口用来接收amr音频流,另一个tcp下行端口用来发送amr音频流。
我这里写的服务端实现了组播的功能,即一个人在录音,可以同时让很多人同时听到。
简而言之,服务端做的唯一一件事情就是转发音频流,囧rz。。。
在这里,我只贴出一部分代码,后面我会上传资源供大家下载。
接收udp传送的音频码流:
[java] view
plaincopy
while (isServerRunning()) {
try {
DatagramPacket pack = new DatagramPacket(data, data.length);
udpServer.receive(pack);
addPacketToBuffer(new FramePacket(pack.getData(), pack.getLength()));
} catch (Exception e) {
System.out.println(e.toString());
}
}
用tcp转发收到的音频流:
[java] view
plaincopy
public void sendDataToAllClient() throws Exception {
if (isBufferEmpty() || clientList.size() <= 0) {
return;
}
boolean bufEmpty = isBufferEmpty();
byte[] block = takeAwayFirstFrame();
ArrayList<Integer> disConnectClient = new ArrayList<Integer>();
for (int ix = 0; ix < clientList.size(); ++ix) {
Client client = clientList.get(ix);
Socket clientSocket = client.getSocket();
if (clientSocket.isConnected()) {
try {
if (!bufEmpty) {
if (block == null) {
continue;
}
OutputStream output = clientSocket.getOutputStream();
output.write(block);
output.flush();
}
} catch (Exception err) {
disConnectClient.add(ix);
}
} else {
disConnectClient.add(ix);
}
}
for (int ix = 0; ix < disConnectClient.size(); ++ix) {
int index = disConnectClient.get(ix);
clientList.remove(index);
}
disConnectClient.clear();
disConnectClient = null;
block = null;
}
相关文章推荐
- Android动态设置控件大小以及设定margin以及padding值
- Android音频实时传输与播放(一):写在开头
- android 的四种枚举Context.MODE_PRIVATE
- Android基础入门教程——2.4.12 ExpandableListView(可折叠列表)的基本使用
- Android项目上传到SVN,需要上传的文件和不需要上传的文件
- Android学习—自定义组件
- android sdk 打包混淆
- 关于android服务
- Android改变手机屏幕朝向的方法
- android中的lint工具
- Android中Application、静态变量和Sharedpreferences的使用与区别
- Android万能适配器
- Android UI学习 - Menu
- android中Handle类的用法实例分析
- android 混淆打包
- Android - 线程同步
- android sdk 加密 混淆
- 安卓APK反编译与混淆编译
- Android中插件开发篇之----动态加载Activity(免安装运行程序)
- Android中ClearEditText实现点击EditText输入框右边清除图标来清除输入内容的两种方式