Mercurial > hg > Applications > TreeVNC
view src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java @ 291:a310be14d757
send rtp+sound packet(client node version).
author | oc |
---|---|
date | Tue, 13 Jan 2015 06:43:15 +0900 |
parents | c10e0dee7bbb |
children | d1ceb4b7097a |
line wrap: on
line source
package jp.ac.u_ryukyu.treevnc; import javax.sound.sampled.*; import java.io.ByteArrayOutputStream; import java.net.*; /** * Created by OcBookPro on 15/01/13. */ public class SendSound implements Runnable { public static final int recvPort = 60004; private TreeRFBProto rfb; private DatagramSocket socket; private boolean isStop; private int sequenceNum; private int timeStamp; private int syncSourceId; private byte marker; // Destination ip and port. private String destIp; private String destPort; // Constructor root version. public SendSound(TreeRFBProto rfb) { this.rfb = rfb; } // Constructor node version. public SendSound(TreeRFBProto rfb, String destIp, String destPort) throws UnknownHostException, SocketException { this.rfb = rfb; this.socket = new DatagramSocket(recvPort, InetAddress.getLocalHost()); this.destIp = destIp; this.destPort = destPort; } @Override public void run() { try { byte[] soundPacket = new byte[160]; AudioFormat linearFormat = new AudioFormat(8000,16,1,true,false); AudioFormat ulawFormat = new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false); DataLine.Info info = new DataLine.Info(TargetDataLine.class,linearFormat); TargetDataLine targetDataLine = (TargetDataLine) AudioSystem.getLine(info); targetDataLine.open(linearFormat); targetDataLine.start(); AudioInputStream linearStream = new AudioInputStream(targetDataLine); AudioInputStream ulawStream = AudioSystem.getAudioInputStream(ulawFormat,linearStream); byte[] byteaddress; byte[] rtpPacket; DatagramPacket packet = null; InetSocketAddress address = null; if (!rfb.isTreeManager()) { // rtp+sound packet rtpPacket = new byte[172]; address = new InetSocketAddress(this.destIp, Integer.parseInt(this.destPort)); } while(!isStop) { try { ulawStream.read(soundPacket,0,soundPacket.length); if (rfb.isTreeManager()) { // soundPacketをframebufferUpdateに乗せて送信する処理 return; } // client node version. rtpPacket = this.addRtpHeader(soundPacket); packet = new DatagramPacket(rtpPacket,rtpPacket.length,address); this.socket.send(packet); } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } public void stopSendSound() { this.isStop = true; } private byte[] addRtpHeader(byte[] voiceData) { byte[] rtpHeader = new byte[12]; // RTPヘッダ byte version = -128; // バージョン番号10000000 byte padding = 0; // パディング byte extention = 0; // 拡張ビット byte contribute = 0; // コントリビュートカウント byte payload = 0; // ペイロードタイプ // RTPヘッダーの生成 rtpHeader[0] = (byte)(version | padding | extention | contribute); rtpHeader[1] = (byte)(marker | payload); rtpHeader[2] = (byte)(this.sequenceNum >> 8); rtpHeader[3] = (byte)(this.sequenceNum >> 0); rtpHeader[4] = (byte)(this.timeStamp >> 24); rtpHeader[5] = (byte)(this.timeStamp >> 16); rtpHeader[6] = (byte)(this.timeStamp >> 8); rtpHeader[7] = (byte)(this.timeStamp >> 0); rtpHeader[8] = (byte)(this.syncSourceId >> 24); rtpHeader[9] = (byte)(this.syncSourceId >> 16); rtpHeader[10] = (byte)(this.syncSourceId >> 8); rtpHeader[11] = (byte)(this.syncSourceId >> 0); // シーケンス番号、タイムスタンプ、マーカービット移行 this.sequenceNum ++; this.timeStamp += 160; if(this.marker == -128) this.marker = 0; // RTPヘッダー+音声データ = RTPパケット ByteArrayOutputStream out = new ByteArrayOutputStream(172); out.write(rtpHeader,0,12); out.write(voiceData,0,160); return out.toByteArray(); } }