這次為了要趕工做出一個Voip 的實作
所以就特別寫了一個 Java 使用 UDP 的Voip 傳送資料
以下就先列出 Connect 的程式碼
private boolean callFlag = false;
private udpTClass UTC;
private void jButton12MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if (callFlag == false) {
String addrIP = this.jTextField1.getText();
//String addrIP = "127.0.0.1";
this.jTextArea1.setText("");
// collection IP and connection IP use Port 1200 UDP protocol
UTC = new udpTClass(addrIP, 1200);
this.jTextArea1.append("Connection to: " + addrIP);
this.jButton12.setText("disconnect");
callFlag = true;
} else {
UTC.CloseTrans();
UTC = null;
this.jTextArea1.append("Close Connect");
this.jButton12.setText("connection");
callFlag = false;
}
}
當按下 Connection 時
會new udpTClass 並將 目標IP傳過去
package udp_voipv1;
import java.io.*;
import java.lang.Thread.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.*;
public class udpTClass extends Thread{
private int portNo;
private String addrIP;
private listener listBack;
public udpTClass(String addrIP, int portNo) {
this.addrIP = addrIP;
this.portNo = portNo;
listBack = new listener(this.portNo);
listBack.start();
this.InitRecord();
this.start();
}
TargetDataLine targetDL = null; // input Voice device
private void InitRecord() {
// encode PCM unsigned, 8000Hz, 1ch
AudioFormat af = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED, // Encoding
6300.0F, // SampleRate
8, // sampleSizeInBits
1, // channels
1, // frameSize
6300.0F, // frameRate
false); // bitEndian
try {
DataLine.Info infoT = new DataLine.Info(TargetDataLine.class, af);
//get target line
targetDL = (TargetDataLine) AudioSystem.getLine(infoT);
targetDL.open(af);
targetDL.start();
recordFlag = true;
} catch (Exception e) {
System.out.println("" + e);
throw new ArithmeticException();
}
System.out.println("Init Record OK...");
}
public void CloseTrans() {
this.CloseRecord();
listBack.CloseList();
listBack.socket.close();
}
public void CloseRecord() {
targetDL.close();
this.recordFlag = false;
}
boolean recordFlag;
public DatagramSocket socket; // udp socket
@Override
public void run() {
InetAddress addr = null;
try { // get addr
addr = InetAddress.getByName(addrIP);
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
System.out.println("start output");
try {
DatagramPacket packet = null;
do { // trans data from target data line
byte[] audioData = new byte[60];
int byteRead = targetDL.read(audioData, 0, audioData.length); // audio Record data
if (byteRead > 0) {
//System.out.println(new String (audioData));
packet = new DatagramPacket(audioData, audioData.length, addr, portNo);
socket = new DatagramSocket(); // UDP socket
socket.send(packet);
//socket.close();
}
/*packet = new DatagramPacket(audioData, audioData.length, addr, portNo);
socket = new DatagramSocket(); // UDP socket
socket.send(packet);*/
} while(recordFlag);
packet = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
接著在這裡就直接去實作了UDP 的傳送與PCM 的擷取
再把 擷取資料的Thread 去listener 實做
package udp_voipv1;
import javax.sound.sampled.*;
import java.net.*;
import java.lang.Thread.*;
public class listener extends Thread{
private int portNo;
AudioInputStream ais = null; // input stream
AudioFormat af = null; // data format is AU file
SourceDataLine sourceDL = null; // output Voice device
public listener(int portNo) {
this.portNo = portNo;
this.InitListener();
}
private void InitListener() {
// encode PCM unsigned, 8000Hz, 1ch
af = new AudioFormat(AudioFormat.Encoding.PCM_UNSIGNED, // Encoding
6300.0F, // SampleRate
8, // sampleSizeInBits
1, // channels
1, // frameSize
6300.0F, // frameRate
false); // bitEndian
try {
DataLine.Info infoS = new DataLine.Info(SourceDataLine.class, af);
//get source line
sourceDL = (SourceDataLine) AudioSystem.getLine(infoS);
sourceDL.open(af);
sourceDL.start();
this.listenerFlag = true;
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean listenerFlag;
public void CloseList() {
sourceDL.close();
this.listenerFlag = false;
}
public DatagramSocket socket;
@Override
public void run() {
DatagramPacket packet = null;
try {
byte[] listData = new byte[60];
socket = new DatagramSocket(this.portNo); // start udp trans set port
System.out.println("start receive");
do {
packet = new DatagramPacket(listData, listData.length); // prepare receive packet
socket.receive(packet); // blocking waiting receive
sourceDL.write(listData, 0, listData.length); // output to headphone
//String msg = new String(buf, 0, packet.getLength());
//System.out.println(msg);
}while (listenerFlag);
packet = null;
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
就完成了這次所寫的Voip 使用 UDP
結論:
JAVA 在網路方面的使用真的很方便...