changeset 291:a310be14d757

send rtp+sound packet(client node version).
author oc
date Tue, 13 Jan 2015 06:43:15 +0900
parents c10e0dee7bbb
children 6c6960291f81
files src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java src/viewer_swing/java/com/glavsoft/viewer/swing/SwingViewerWindow.java
diffstat 3 files changed, 134 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java	Tue Jan 13 05:22:53 2015 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/SendSound.java	Tue Jan 13 06:43:15 2015 +0900
@@ -1,26 +1,128 @@
 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 {
 
-    TreeRFBProto rfb;
+    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() {
-        for(;;) {
-            if (rfb.isTreeManager()) {
-                // root version (send packet to other nodes)
-                System.out.println("root : share sound!!\n");
-            } else {
-                // node version (send packet+RTP to root)
-                System.out.println("client node : share sound!!\n");
+        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();
+    }
+}
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Tue Jan 13 05:22:53 2015 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java	Tue Jan 13 06:43:15 2015 +0900
@@ -3,11 +3,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
-import java.net.BindException;
-import java.net.NetworkInterface;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
+import java.net.*;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Iterator;
@@ -756,8 +752,13 @@
     /**
      * Create send sound thread.
      */
-    public void createShareSoundThread(TreeRFBProto rfb) {
-        SendSound sendSound = new SendSound(rfb);
+    public void createShareSoundThread(TreeRFBProto rfb) throws SocketException, UnknownHostException {
+        SendSound sendSound;
+        if(rfb.isTreeManager()) {
+            sendSound = new SendSound(rfb);
+        } else {
+            sendSound = new SendSound(rfb, "133.13.57.59", "60004");
+        }
         Thread sendSoundThread = new Thread(sendSound, "send-sound");
         sendSoundThread.start();
     }
--- a/src/viewer_swing/java/com/glavsoft/viewer/swing/SwingViewerWindow.java	Tue Jan 13 05:22:53 2015 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/swing/SwingViewerWindow.java	Tue Jan 13 06:43:15 2015 +0900
@@ -44,6 +44,8 @@
 
 import java.awt.*;
 import java.awt.event.*;
+import java.net.SocketException;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -901,15 +903,21 @@
         final JButton soundButton = buttonsBar.createButton("share-sound", "Share Sound", new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                if (viewer.getRfb().isTreeManager()) {
-                    // send用thread立ち上げのメソッドに飛ぶ
+                // send用thread立ち上げのメソッドに飛ぶ
+                try {
+                    if (viewer.getRfb().isTreeManager()) {
+                        viewer.getRfb().createShareSoundThread(viewer.getRfb());
+                        return;
+                    }
+                    // rootにMsgを送信する
+                    context.sendMessage(new ReadyShareSound());
+                    // 送信用threadを立ち上げるメソッドに飛ぶ
                     viewer.getRfb().createShareSoundThread(viewer.getRfb());
-                    return;
+                } catch (SocketException e1) {
+                    e1.printStackTrace();
+                } catch (UnknownHostException e1) {
+                    e1.printStackTrace();
                 }
-                // rootにMsgを送信する
-                context.sendMessage(new ReadyShareSound());
-                // 送信用threadを立ち上げるメソッドに飛ぶ
-                viewer.getRfb().createShareSoundThread(viewer.getRfb());
             }
         });
         kbdButtons.add(adjustHdSizeButton);