⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 captureplaybackclient.java

📁 java语言编写的语音聊天室程序
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
          for (int i = 0; i < audioBytes.length; i++) {
            audioData[i] = audioBytes[i] - 128;
          }
        }
      }

      int frames_per_pixel = audioBytes.length / format.getFrameSize() / w;
      byte my_byte = 0;
      double y_last = 0;
      int numChannels = format.getChannels();
      for (double x = 0; x < w && audioData != null; x++) {
        int idx = (int) (frames_per_pixel * numChannels * x);
        if (format.getSampleSizeInBits() == 8) {
          my_byte = (byte) audioData[idx];
        }
        else {
          my_byte = (byte) (128 * audioData[idx] / 32768);
        }
        double y_new = (double) (h * (128 - my_byte) / 256);
        //增加点!
        lines.add(new Line2D.Double(x, y_last, x, y_new));
        y_last = y_new;
      }

      //repaint();//???
    }

//使用线程画波形图!hlf
    public void paint(Graphics g) {
      // 组件JPanel的大小;Returns the size of this component in the form of a <code>Dimension</code> object
      Dimension d = getSize();
      int w = d.width;
      int h = d.height;
      int INFOPAD = 15;
      // 精确控制几何图形 Graphics2D——sophisticated control over geometry
      // 在JPanel上画画!
      Graphics2D g2 = (Graphics2D) g;
      g2.setBackground(getBackground());
      g2.clearRect(0, 0, w, h); //???300,60
      g2.setColor(Color.white);
      g2.fillRect(0, h - INFOPAD, w, INFOPAD);
      //捕获出错的情况1
      if (errStr != null) {
        g2.setColor(jfcBlue);
        g2.setFont(new Font("serif", Font.BOLD, 18));
        g2.drawString("ERROR", 5, 20);
        AttributedString as = new AttributedString(errStr);
        as.addAttribute(TextAttribute.FONT, font12, 0, errStr.length());
        AttributedCharacterIterator aci = as.getIterator();
        FontRenderContext frc = g2.getFontRenderContext();
        LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
        float x = 5, y = 25;
        lbm.setPosition(0);
        while (lbm.getPosition() < errStr.length()) {
          TextLayout tl = lbm.nextLayout(w - x - 5);
          if (!tl.isLeftToRight()) {
            x = w - tl.getAdvance();
          }
          tl.draw(g2, x, y += tl.getAscent());
          y += tl.getDescent() + tl.getLeading();
        }
      }
      //正捕获中的情况2
      else if (capture.thread != null) {
        g2.setColor(Color.black);
        g2.setFont(font12);
        g2.drawString("Length: " + String.valueOf(seconds), 3, h - 4);
      }
      //捕获结束的情况3
      else {
        g2.setColor(Color.black);
        g2.setFont(font12);
        g2.drawString("文件名: " + fileName + "  长度: " +
                      String.valueOf(duration) + "  当前位置(秒): " +
                      String.valueOf(seconds), 3, h - 4);

        if (audioInputStream != null) {
          // 画声音波形图.. render sampling graph ..
          g2.setColor(jfcBlue);
          for (int i = 1; i < lines.size(); i++) {
            g2.draw( (Line2D) lines.get(i));
          }

          // 画当前位置图.. draw current position ..
          if (seconds != 0) {
            double loc = seconds / duration * w;
            g2.setColor(pink);
            g2.setStroke(new BasicStroke(3));
            g2.draw(new Line2D.Double(loc, 0, loc, h - INFOPAD - 2));
          }
        }
      }
    }

    public void start() {
      thread = new Thread(this);
      thread.setName("SamplingGraph");
      thread.start();
      seconds = 0;
    }

    public void stop() {
      if (thread != null) {
        thread.interrupt();
      }
      thread = null;
    }

    public void run() {
      seconds = 0;
      while (thread != null) {
        if ( (playback.line != null) && (playback.line.isOpen())) {

          long milliseconds = (long) (playback.line.getMicrosecondPosition() /
                                      1000);
          seconds = milliseconds / 1000.0;
        }
        else if ( (capture.line != null) && (capture.line.isActive())) {

          long milliseconds = (long) (capture.line.getMicrosecondPosition() /
                                      1000);
          seconds = milliseconds / 1000.0;
        }

        try {
          thread.sleep(100);
        }
        catch (Exception e) {
          break;
        }

        repaint();

        while ( (capture.line != null && !capture.line.isActive()) ||
               (playback.line != null && !playback.line.isOpen())) {
          try {
            thread.sleep(10);
          }
          catch (Exception e) {
            break;
          }
        }
      }
      seconds = 0;
      repaint();
    }
  } // End class SamplingGraph

  public static void main(String s[]) {
    CapturePlaybackClient CapturePlaybackClient = new CapturePlaybackClient();
    CapturePlaybackClient.open();
    JFrame f = new JFrame("欢迎使用客户端语音系统");
    f.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    f.getContentPane().add("Center", CapturePlaybackClient);
    f.pack();
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int w = 400;//720;
    int h = 340;
    //使frame居中
    f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h / 2);
    f.setSize(w, h);
    f.show();
  }
  class ConnSocket
        implements Runnable { //extend Thead;
      Socket socket;
      boolean runing = true;
      //输出流:BufferedOutputStream
       BufferedOutputStream bos;
       OutputStream os;

      //声音流
       AudioInputStream audioInputStream = null;
      Thread thread;

      public void start() {
        thread = new Thread(this);
        thread.setName("Client");
        startup();
        thread.start();
      }

      public void stop() {
        try {
          socket.close();
          socket = null;
        }
        catch (IOException ex) {
        }
        thread = null;
      }

      public void startup(){
        if (socket==null)
          try {
            socket = new Socket("localhost", 1983);
          }
          catch (UnknownHostException ex) {
            System.out.println("意外错误");
          }
          catch (IOException ex) {
            System.out.println("IO错误");
          }
      }
      public void run() {
        /**
         * 声明soundAPI里的 AudioFormat格式对象
         */
        AudioFormat DEFAULT_AUDIO_FORMAT = new AudioFormat(
            //Encoding
            AudioFormat.Encoding.PCM_SIGNED,
            //Sample rate
            22050f, //Sample size in bytes
            16, //Number of channels
            2, //Frame size
            4, //Frame rate
            22050f, //Big endian
            false
            );
        //interface TargetDataLine (Autoformat,bufsize)
        TargetDataLine line;
        FormatControls formatControls=new FormatControls();
        AudioFormat format = formatControls.getFormat();
//      AudioFormat format = DEFAULT_AUDIO_FORMAT;
        boolean recording = false;

        try {
          //懒汉模式
          os = socket.getOutputStream();
          bos = new BufferedOutputStream(socket.getOutputStream());
          System.out.println("连接成功");
          /**
           *
           */
          DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
          //转化为TargetDataLine接口类型,以使用open(format, line.getBufferSize())函数!
          line = (TargetDataLine) AudioSystem.getLine(info);
          System.out.println(line.getBufferSize());
          line.open(format, line.getBufferSize());

          //返回每帧的大小
          int frameSizeInBytes = format.getFrameSize();

          //返回buf里的(8字节)帧数The number of frames = the size of the buffer
          int bufferLengthInFrames = line.getBufferSize() / 8;

          //buf总大小Number of frames * frame size = total bytes
          int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;

          //新建的buf大小的字节数组Make a new byte[] the size of the AudioBuffer
          byte[] buf = new byte[bufferLengthInBytes];
          System.out.println("bufferLengthInBytes:" + bufferLengthInBytes);
          //ByteArrayOutputStream 见78行的ByteArrayInputStream
          ByteArrayOutputStream out = new ByteArrayOutputStream();

          int numBytesRead; //缓存Cache the number of bytes we have read

          line.start();

          while (runing) {
            System.out.println(runing);

            if ( (numBytesRead = line.read(buf, 0, bufferLengthInBytes)) == -1) {

              break;
            }
            //out.write(buf, 0, numBytesRead);
            //byte audioBytes[] = out.toByteArray();字节数组流
            //(buf)是 新建的buf大小的字节数组
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
                buf);

            /**ByteArrayInputStream--->AudioInputStream
             * AudioInputStream(buf大小的字节数组,声音格式,帧数)
             */
            audioInputStream = new AudioInputStream(byteArrayInputStream, format,
                                                    buf.length / frameSizeInBytes);

            System.out.println("audioInputStream.available:" +
                               audioInputStream.available() + "buf.length " +
                               buf.length + " frameSizeInBytes" +
                               frameSizeInBytes);
            /**
             * Writes a stream of bytes representing an audio file of the specified file type
             * to the output stream provided.  Some file types require that
             * the length be written into the file header; such files cannot be written from
             * start to finish unless the length is known in advance.  An attempt
             * to write a file of such a type will fail with an IOException if the length in
             * the audio file type is <code>AudioSystem.NOT_SPECIFIED</code>.
             *
             * @param stream the audio input stream containing audio data to be
             * written to the file
             * @param fileType the kind of audio file to write
             * @param out the stream to which the file data should be written
             * @return the number of bytes written to the output stream
             * @throws IOException if an input/output exception occurs
             * @throws IllegalArgumentException if the file type is not supported by
             * the system
             * @see #isFileTypeSupported
             * @see	#getAudioFileTypes
             */
            //将输入流写入输出字节buf流  bos==BufferedOutputStream
            //AudioFileFormat(Type type, int byteLength, AudioFormat format, int frameLength)
            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, bos); //bos-->os
            //API说明:write(AudioInputStream stream, AudioFileFormat.Type fileType,OutputStream out)
            /**关于socket:
             *将字符串转化成为out输出流,out.println && 从流中得到字符串: in.readLine()
             * PrintWriter =out类型 out.println(string s);      BufferedReader=in类型 in.readline();
             */
          }
          System.out.println("完成...");
          System.exit(0);
        }
        catch (Exception err) {
          System.out.println("youProblem");
          err.printStackTrace();
          connB.setText("连接");
          this.stop();
        }
      }
      /*
      public void runBare()throws Throwable {
        try{
          AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, bos);
        }
        catch (Exception err) {
          System.out.println("Problem");
          err.printStackTrace();
          throw err;
        }
      }
    */
  }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -