2014-05-24 157 views
1

所以,我正在尋找一個麥克風數據發送嘖嘖,但我還沒有找到任何。 因此,我讀了關於行打開的Oracles tut,並且我能夠將音頻記錄到ByteArrayOutputStream,但是現在我有兩個問題!通過UDP發送音頻

第一張: 如何播放錄製的音頻。

第二:如果我將它錄製到BAOS,我將如何動態發送它。 我想我會發送數據數組,但是如果每次收到BAOS時寫入BAOS會不會太浪費處理器呢,或者我可以以不同的方式做呢?

當前代碼:

import java.io.ByteArrayOutputStream; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.TargetDataLine; 

public class MicrophoneRecorder { 
    static boolean stopped = false; 

    public static void main(String[] args) { 
     AudioFormat format = new AudioFormat(8000.0f, 16, 1, true, true); 
     TargetDataLine line = null; 
     DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); 
     if (!AudioSystem.isLineSupported(info)) { 
      System.out.println("Not supported!"); 
     } 
     try { 
      line = (TargetDataLine) AudioSystem.getLine(info); 
      line.open(format); 
     } catch (LineUnavailableException ex) { 
      ex.printStackTrace(); 
     } 
     ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     int numBytesRead = 0; 
     byte[] data = new byte[line.getBufferSize()/5]; 
     line.start(); 

     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        Thread.sleep(3000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       stopped = true; 
      } 
     }).start(); 
     while (!stopped) { 
      numBytesRead = line.read(data, 0, data.length); 
      out.write(data, 0, numBytesRead); 
     } 
    } 

} 

感謝給予任何幫助。 此致RobertoAnićBanić

P.S. 看到這個,不起作用http://javasolution.blogspot.com/2007/04/voice-chat-using-java.html P.P.S. UDP是一個很好的解決方案,或者我應該使用RTSP

+0

爲什麼不運作的?您可能想要這樣做... –

+0

代碼被擰緊 –

+0

您確實似乎在重新創建輪子:[RTSP](http://www.ietf.org/rfc/rfc2326.txt) – marko

回答

2

這是一個通過UDP發送音頻的實現。 以下是客戶端和服務器代碼。基本上,客戶端代碼將捕獲的音頻發送到服務器,服務器在接收時播放它。客戶端也可以播放捕獲的音頻。

客戶端代碼:VUClient.java

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import javax.sound.sampled.*; 

public class VUClient extends JFrame { 

boolean stopaudioCapture = false; 
ByteArrayOutputStream byteOutputStream; 
AudioFormat adFormat; 
TargetDataLine targetDataLine; 
AudioInputStream InputStream; 
SourceDataLine sourceLine; 
Graphics g; 

public static void main(String args[]) { 
    new VUClient(); 
} 

public VUClient() { 
    final JButton capture = new JButton("Capture"); 
    final JButton stop = new JButton("Stop"); 
    final JButton play = new JButton("Playback"); 

    capture.setEnabled(true); 
    stop.setEnabled(false); 
    play.setEnabled(false); 

    capture.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      capture.setEnabled(false); 
      stop.setEnabled(true); 
      play.setEnabled(false); 
      captureAudio(); 
     } 
    }); 
    getContentPane().add(capture); 

    stop.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      capture.setEnabled(true); 
      stop.setEnabled(false); 
      play.setEnabled(true); 
      stopaudioCapture = true; 
      targetDataLine.close(); 
     } 
    }); 
    getContentPane().add(stop); 

    play.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      playAudio(); 
     } 
    }); 
    getContentPane().add(play); 

    getContentPane().setLayout(new FlowLayout()); 
    setTitle("Capture/Playback Demo"); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setSize(400, 100); 
    getContentPane().setBackground(Color.white); 
    setVisible(true); 

    g = (Graphics) this.getGraphics(); 
} 

private void captureAudio() { 
    try { 
     adFormat = getAudioFormat(); 
     DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, adFormat); 
     targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo); 
     targetDataLine.open(adFormat); 
     targetDataLine.start(); 

     Thread captureThread = new Thread(new CaptureThread()); 
     captureThread.start(); 
    } catch (Exception e) { 
     StackTraceElement stackEle[] = e.getStackTrace(); 
     for (StackTraceElement val : stackEle) { 
      System.out.println(val); 
     } 
     System.exit(0); 
    } 
} 

private void playAudio() { 
    try { 
     byte audioData[] = byteOutputStream.toByteArray(); 
     InputStream byteInputStream = new ByteArrayInputStream(audioData); 
     AudioFormat adFormat = getAudioFormat(); 
     InputStream = new AudioInputStream(byteInputStream, adFormat, audioData.length/adFormat.getFrameSize()); 
     DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, adFormat); 
     sourceLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); 
     sourceLine.open(adFormat); 
     sourceLine.start(); 
     Thread playThread = new Thread(new PlayThread()); 
     playThread.start(); 
    } catch (Exception e) { 
     System.out.println(e); 
     System.exit(0); 
    } 
} 

private AudioFormat getAudioFormat() { 
    float sampleRate = 16000.0F; 
    int sampleInbits = 16; 
    int channels = 1; 
    boolean signed = true; 
    boolean bigEndian = false; 
    return new AudioFormat(sampleRate, sampleInbits, channels, signed, bigEndian); 
} 

class CaptureThread extends Thread { 

    byte tempBuffer[] = new byte[10000]; 

    public void run() { 

     byteOutputStream = new ByteArrayOutputStream(); 
     stopaudioCapture = false; 
     try { 
      DatagramSocket clientSocket = new DatagramSocket(8786); 
      InetAddress IPAddress = InetAddress.getByName("127.0.0.1"); 
      while (!stopaudioCapture) { 
       int cnt = targetDataLine.read(tempBuffer, 0, tempBuffer.length); 
       if (cnt > 0) { 
        DatagramPacket sendPacket = new DatagramPacket(tempBuffer, tempBuffer.length, IPAddress, 9786); 
        clientSocket.send(sendPacket); 
        byteOutputStream.write(tempBuffer, 0, cnt); 
       } 
      } 
      byteOutputStream.close(); 
     } catch (Exception e) { 
      System.out.println("CaptureThread::run()" + e); 
      System.exit(0); 
     } 
    } 
} 

class PlayThread extends Thread { 

    byte tempBuffer[] = new byte[10000]; 

    public void run() { 
     try { 
      int cnt; 
      while ((cnt = InputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) { 
       if (cnt > 0) { 
        sourceLine.write(tempBuffer, 0, cnt); 
       } 
      } 
      //    sourceLine.drain(); 
      //    sourceLine.close(); 
     } catch (Exception e) { 
      System.out.println(e); 
      System.exit(0); 
     } 
    } 
} 
} 

Server代碼:VUServer.java

import java.io.*; 
import java.net.*; 
import javax.sound.sampled.*; 

public class VUServer { 

ByteArrayOutputStream byteOutputStream; 
AudioFormat adFormat; 
TargetDataLine targetDataLine; 
AudioInputStream InputStream; 
SourceDataLine sourceLine; 

private AudioFormat getAudioFormat() { 
    float sampleRate = 16000.0F; 
    int sampleInbits = 16; 
    int channels = 1; 
    boolean signed = true; 
    boolean bigEndian = false; 
    return new AudioFormat(sampleRate, sampleInbits, channels, signed, bigEndian); 
} 

public static void main(String args[]) { 
    new VUServer().runVOIP(); 
} 

public void runVOIP() { 
    try { 
     DatagramSocket serverSocket = new DatagramSocket(9786); 
     byte[] receiveData = new byte[10000]; 
     while (true) { 
      DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 
      serverSocket.receive(receivePacket); 
      System.out.println("RECEIVED: " + receivePacket.getAddress().getHostAddress() + " " + receivePacket.getPort()); 
      try { 
       byte audioData[] = receivePacket.getData(); 
       InputStream byteInputStream = new ByteArrayInputStream(audioData); 
       AudioFormat adFormat = getAudioFormat(); 
       InputStream = new AudioInputStream(byteInputStream, adFormat, audioData.length/adFormat.getFrameSize()); 
       DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, adFormat); 
       sourceLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); 
       sourceLine.open(adFormat); 
       sourceLine.start(); 
       Thread playThread = new Thread(new PlayThread()); 
       playThread.start(); 
      } catch (Exception e) { 
       System.out.println(e); 
       System.exit(0); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

class PlayThread extends Thread { 

    byte tempBuffer[] = new byte[10000]; 

    public void run() { 
     try { 
      int cnt; 
      while ((cnt = InputStream.read(tempBuffer, 0, tempBuffer.length)) != -1) { 
       if (cnt > 0) { 
        sourceLine.write(tempBuffer, 0, cnt); 
       } 
      } 
      // sourceLine.drain(); 
      // sourceLine.close(); 
     } catch (Exception e) { 
      System.out.println(e); 
      System.exit(0); 
     } 
    } 
} 
} 
+0

服務器崩潰由於tempBuffer限制5秒後,如何解決它? – Asim

+0

你能顯示輸出嗎?到目前爲止,我不會遇到任何問題。 –