前几次博客中也是用java实现录音机的各种功能,这次是比先前有了一点优化,将录音的功能单独提取出来,这个程序的实现用到了编码器LAME.exe这个的作用是将录音得到的wav文件编码成MP3文件,这样的结果是容量大大减少,因为LAME编码器经测试在编码过程中路径中带有空格问题未能解决,所以只能找了一个笨的方法,为了将其放到指定的文件夹下(这个文件夹路径是带有空格的),所以只能先存放到D盘,然后利用文件操作将其复制到指定的路径下,然后再删除,程序中还用到了图片,修改了java的图标,所以在运行时可将其注释掉,写的很烂,相互学习哈!

/** 实现录音机的功能* 1.在原来的基础上界面更加精简,字体变大使用户更加方便* 2.在停止录音后便直接保存为.mp3文件* 3.对停止录音进行改进,将录音按钮设计成类似微信的形式,按下时进行录音,松开即停止录音并保存即可* 4.在录音的时候在面板上显示音频波,表示正在录音*/
package com.liuyun.MyRecord6;import java.awt.*;import javax.swing.*;
import java.awt.event.*;
import java.io.*;import javax.sound.sampled.*;import java.lang.*;public class MyRecord6 extends JFrame implements MouseListener{//定义录音格式AudioFormat af = null;//定义目标数据行,可以从中读取音频数据,该 TargetDataLine 接口提供从目标数据行的缓冲区读取所捕获数据的方法。TargetDataLine td = null;//定义源数据行,源数据行是可以写入数据的数据行。它充当其混频器的源。应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。SourceDataLine sd = null;//定义字节数组输入输出流ByteArrayInputStream bais = null;ByteArrayOutputStream baos = null;//定义音频输入流AudioInputStream ais = null;//定义停止录音的标志,来控制录音线程的运行Boolean stopflag = false;//记录开始录音的时间long startPlay;//设置一个播放的标志Boolean playflag;//每次保存的最后的文件名File tarFile = null;//定义音频波形每次显示的字节数int intBytes = 0;//定义每次录音的时候每次提取字节来画音频波byte audioDataBuffer[] = null;//定义所需要的组件JPanel jp1,jp2,jp3;JLabel jl1=null;JButton captureBtn;//设置画波形线程的终止的标志boolean flag = true;//定义播放录音时的一个计数值int cnt;//定义播放录音时一个缓冲数组byte btsPlay[] = null;int gridx, gridy, gridwidth, gridheight, anchor, fill, ipadx, ipady;double weightx, weighty;Insets inset;GridBagConstraints c;public static void main(String[] args) {//创造一个实例MyRecord6 mr = new MyRecord6();}//构造函数public MyRecord6(){//组件初始化jp1 = new JPanel();jp2 = new JPanel();jp3 = new JPanel();//定义jp1的字体Font jpFont = new Font("华文新魏",Font.BOLD,40);jl1 = new JLabel("请留下您想说的话");jl1.setFont(jpFont);jl1.setForeground(Color.red);jp1.add(jl1);//定义按钮上面的字体Font btFont = new Font("华文新魏",Font.BOLD,40);captureBtn = new JButton("按住 说话");//setForeground可以设置按钮上面字体的颜色captureBtn.setForeground(Color.RED);captureBtn.setFont(btFont);//对开始录音按钮进行鼠标监听captureBtn.addMouseListener(this);this.add(jp1,BorderLayout.NORTH);this.add(jp2,BorderLayout.CENTER);this.add(jp3,BorderLayout.SOUTH);GridBagLayout gridbag = null;jp3.setLayout(gridbag = new GridBagLayout());gridx=1;gridy=2;gridwidth=1;gridheight=1;weightx=1;weighty=1;anchor=GridBagConstraints.CENTER;fill=GridBagConstraints.HORIZONTAL;inset=new Insets(1,1,1,1);ipadx=0;ipady=30;c = new GridBagConstraints(gridx, gridy, gridwidth, gridheight,weightx, weighty, anchor, fill, inset, ipadx, ipady);gridbag.setConstraints(captureBtn, c);jp3.add(captureBtn);//设置窗口的属性this.setSize(800,500);this.setTitle("录音机");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口居中this.setLocationRelativeTo(null);//将窗口的边框去掉this.setUndecorated(true);this.setVisible(true);//设置窗口上的图标Image img = this.getToolkit().getImage(getClass().getResource("/image/Recorder.jpg"));this.setIconImage(img);//设置窗口在最前端显示this.setAlwaysOnTop(true);}public void mouseClicked(MouseEvent e) {}public void mousePressed(MouseEvent e) {//当开始录音按钮被按下时就开始录音if(e.getSource().equals(captureBtn)){//改变按钮上面的字的内容captureBtn.setText("松开 结束");//调用录音的方法capture();//记录开始录音的时间startPlay = System.currentTimeMillis();}}public void mouseReleased(MouseEvent e) {//当松开录音按钮时停止录音并保存录音的文件if(e.getSource().equals(captureBtn)){//调用停止录音的方法stop();//当松开按钮后对显示波形的面板进行清空jp2.repaint();//改变按钮上面的字的内容captureBtn.setText("按住 说话");//调用保存录音的方法save();//将其放到指定的路径下//定义最终要存放的文件路径String destPath = "D:/Program Files/apache-tomcat-6.0.35/webapps/XWZ/tempFile/";copyFile("D:/"+tarFile.getName(), destPath);System.exit(0);}}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}//开始录音public void capture(){try {//af为AudioFormat也就是音频格式af = getAudioFormat();DataLine.Info info = new DataLine.Info(TargetDataLine.class,af);td = (TargetDataLine)(AudioSystem.getLine(info));//打开具有指定格式的行,这样可使行获得所有所需的系统资源并变得可操作。td.open(af);//允许某一数据行执行数据 I/Otd.start();//启动显示波形的进程RecordWave aw = new RecordWave();Thread t2 = new Thread(aw);t2.start();//把显示波形的进程标志设为trueflag = true;Record record = new Record();Thread t1 = new Thread(record);t1.start();} catch (Exception ex) {ex.printStackTrace();return;}}//停止录音public void stop(){stopflag = true;//将画波形的进程终止flag = false;}//保存录音public void save(){af = getAudioFormat();byte audioData[] = baos.toByteArray();bais = new ByteArrayInputStream(audioData);ais = new AudioInputStream(bais,af, audioData.length / af.getFrameSize());//定义最终保存的文件名File file = null;//写入文件try {   //以当前的时间命名录音的名字//将录音的文件存放到F盘下语音文件夹下File filePath = new File("D:/AudioFile");String tarPath = "D:/";if(!filePath.exists()){//如果文件不存在,则创建该目录filePath.mkdirs();}long time = System.currentTimeMillis();file = new File(filePath+"/"+time+".wav");      AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file);//将录音产生的wav文件转换为容量较小的mp3格式//定义产生后文件名tarFile = new File(tarPath+time+".mp3"); Runtime run = null;//测试当前的路径try {run = Runtime.getRuntime();//调用编码器来将wav文件转换为mp3文件//把编码得到的mp3文件先存放到D盘下,然后利用文件拷贝函数将它放到指定的文件夹下同时将D盘下的文件删除Process p=run.exec(filePath+"/"+"lame -b 16 "+filePath+"/"+file.getName()+" "+tarPath+tarFile.getName()); //16为码率,可自行修改//释放进程p.getOutputStream().close();p.getInputStream().close();p.getErrorStream().close();//等待p.waitFor();//               //删除之前保存的的wav文件
//              if(file.exists())
//              {
//                  file.delete();
//              }//             //定义最终要存放的文件路径
//              String destPath = "D:/Program Files/apache-tomcat-6.0.35/webapps/XWZ/tempFile/";
//              copyFile(tarPath+tarFile.getName(), destPath);} catch (Exception e) {e.printStackTrace();}finally{//最后都要执行的语句//run调用lame解码器最后释放内存run.freeMemory();}} catch (Exception e) {e.printStackTrace();}finally{//关闭流try {if(bais != null){bais.close();} if(ais != null){ais.close();        }} catch (Exception e) {e.printStackTrace();}       }}//文件拷贝方法public void copyFile(String srcPath , String destPath){File srcFile = new File(srcPath);//如果目的文件夹没有则创建目的文件夹(new File(destPath)).mkdirs();//在目的文件夹下创建要复制的文件File destFile = new File(destPath+"/"+srcFile.getName());if(srcFile.isFile() && srcFile.exists()){InputStream in = null;OutputStream out = null;try {in = new FileInputStream(srcFile);out = new FileOutputStream(destFile);//设置缓冲数组byte[] buff = new byte[1024*5];   int len = 0;   while ((len = in.read(buff)) != -1) {   out.write(buff, 0, len);   }
//              //测试该函数是否执行
//              System.out.println("ok1");} catch(Exception e) {e.printStackTrace();}finally{//关闭流,先开的后关闭try {if(out != null){out.close(); }if(in != null){in.close();}} catch (Exception e) {e.printStackTrace();}}}//复制过后删除源文件夹中的的文件if(srcFile.exists()){srcFile.delete();}}//设置AudioFormat的参数public AudioFormat getAudioFormat() {//下面注释部分是另外一种音频格式,两者都可以AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED ;float rate = 8000f;int sampleSize = 16;String signedString = "signed";boolean bigEndian = true;int channels = 1;return new AudioFormat(encoding, rate, sampleSize, channels,(sampleSize / 8) * channels, rate, bigEndian);
//      //采样率是每秒播放和录制的样本数
//      float sampleRate = 16000.0F;
//      // 采样率8000,11025,16000,22050,44100
//      //sampleSizeInBits表示每个具有此格式的声音样本中的位数
//      int sampleSizeInBits = 16;
//      // 8,16
//      int channels = 1;
//      // 单声道为1,立体声为2
//      boolean signed = true;
//      // true,false
//      boolean bigEndian = true;
//      // true,false
//      return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,bigEndian);}//录音类,因为要用到MyRecord类中的变量,所以将其做成内部类class Record implements Runnable{//定义存放录音的字节数组,作为缓冲区byte bts[] = new byte[10000];//将字节数组包装到流里,最终存入到baos中//重写run函数public void run() {  baos = new ByteArrayOutputStream();        try {stopflag = false;while(stopflag != true){//当停止录音没按下时,该线程一直执行  //从数据行的输入缓冲区读取音频数据。//要读取bts.length长度的字节,cnt 是实际读取的字节数int cnt = td.read(bts, 0, bts.length);if(cnt > 0){baos.write(bts, 0, cnt);}//开始从音频流中读取字节数byte copyBts[] = bts;bais = new ByteArrayInputStream(copyBts);ais = new AudioInputStream(bais, af, copyBts.length/af.getFrameSize());try{DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, af);sd = (SourceDataLine) AudioSystem.getLine(dataLineInfo);sd.open(af);sd.start();//从音频流中读取int Buffer_Size = 10000;audioDataBuffer = new byte[Buffer_Size];int outBytes;intBytes = ais.read(audioDataBuffer, 0,audioDataBuffer.length);//                      不写到混频器中这样就不会播放
//                      if (intBytes >= 0) {
//                          outBytes = sd.write(audioDataBuffer, 0,audioDataBuffer.length);
//                      }   }catch (Exception e) {e.printStackTrace();}}} catch (Exception e) {e.printStackTrace();}finally{try {//intBytes = -1;//关闭打开的字节数组流if(baos != null){baos.close();}  } catch (Exception e) {e.printStackTrace();}finally{//下面这句td.drain()不能要,这样如果不播放数据就阻塞再次录音会出现其他程序访问错误//td.drain();td.close();//刷新显示波形的面板jp2.repaint();}}}}//画波形的类//因为要使用一些主函数中的数据,所以做成内部类class RecordWave extends JPanel implements Runnable{//用画笔画出波形public void paint(Graphics g){super.paint(g);g.fillRect(jp2.getX(),jp2.getY() , 800, 380);if( audioDataBuffer != null){g.drawLine(jp2.getWidth() / 256, 700, jp2.getWidth() / 256, 700);for(int i=0; i<audioDataBuffer.length-1; ++i){g.setColor(Color.RED);g.drawLine(i * jp2.getWidth() / 256, (int)audioDataBuffer[i]+200 , (i + 1)* jp2.getWidth() / 256, (int)audioDataBuffer[i+1]+200);}}}public void run() {//刷新波形while(true){//System.out.println("ok");try {synchronized (this) {//隔多长时间获取Thread.sleep(300);}} catch (Exception e) {e.printStackTrace();}this.paint(jp2.getGraphics());//终止线程if(flag == false){break;}}}  }}

java实现录音功能相关推荐

  1. android java 录音放大_Android实现录音功能实现实例(MediaRecorder)

    本文介绍了Android实现录音的实例代码(MediaRecorder),分享给大家,具体如下: Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord, ...

  2. uni-app小程序实现录音功能,uniapp实现录音功能并上传java,uniapp简单实现录音功能

    前言 [简单的录音例子,复制过去就可用] 使用了uni组件和uView组件: uniapp小程序授权录音并录制后保存到java后端. 效果图 uniapp实现 直接复制过去粘贴到.vue文件即可测试: ...

  3. java 录音_用JAVA实现不限时录音功能

    在网上找了个录音软件,而且这个软件是根据手机里剩余内存的大小,可以进行不限时录音,所以特地拿上来和大家分享! 这个JAVA软件我发到了"玩转手机"里.解压缩后,大家可以用MIDwa ...

  4. java h5在线音频_[语音技术]java+H5的录音类实例(1)

    看了某位仁兄的分享的关于C#的window平台的录音分装,有兴趣同学请访问楼下地址 https://ai.baidu.com/forum/topic/show/492634 于是,我也整理了自己项目中 ...

  5. java audiorecord_Android 录音实现(AudioRecord)

    上一篇文章介绍了使用 MediaRecorder 实现录音功能 Android录音实现(MediaRecorder) ,下面我们继续看看使用 AudioRecord 实现录音功能. AudioReco ...

  6. [高通SDM450][Android9.0]CTA认证--去掉录音功能

    文章目录 开发平台基本信息 问题描述 解决方法 开发平台基本信息 芯片: SDM450 版本: Android 9.0 kernel: msm-4.9 问题描述 设备在进行入网认证的时候,公司为了尽快 ...

  7. php录音功能,关于录音功能的详细介绍

    微信jssdk录音功能开发记录标签(空格分隔): 前端0.需求描述在微信浏览器内打开的页面,制作一个按钮,用户按住按钮后开始录音,松手后停止录音并将录音上传并长期保存.1.开发流程如果开发的是普通的展 ...

  8. 安卓仿微信录音功能实现

    WeixinRecord 简介 仿安卓微信客户端录音与播放功能.其中录音功能以工具类形式封装,可以直接调用.播放功能以example形式提供解决思路,可以自己定制需要的特定功能. 功能 录音功能: 长 ...

  9. android 仿微信录音,Android 模仿微信长按录音功能

    Android 模仿微信长按录音功能 布局就两个button这里不多介绍了. 下面是activity内的代码 package com.example.forevercloud.myapplicatio ...

最新文章

  1. c#获取对象的唯一标识_Articy Importer Guide - 01 基本对象处理
  2. Asp.Net Core 中的“虚拟目录”
  3. vue watch 第一次不执行_Vue 实现前进刷新,后退不刷新的效果
  4. 百度一口气亮出NLP十年积累:完整技术布局全面披露,面向业界砸下11项七夕大礼
  5. Python | 使用__del __()和__init __()实现析构函数和构造函数的示例
  6. SQL注入漏洞入门(操作实现)
  7. android 关于view的onTouch和onClick同时触发解决方案
  8. [转] 关于闰年的判断方法
  9. java中级项目案例_60个Java练手项目案例,看了让你茅塞顿开~
  10. python更改pip源地址
  11. java中System类详解
  12. VC++,6.0 MFC设计--- 图形界面
  13. NRF52832 WDT
  14. mysql临时表索引_数据库查询优化——给临时表建索引
  15. matplotlib - 自定义散点形状marker的3种方法
  16. idea常用快捷键图文_如何在Word中的自动图文集词条中添加快捷键
  17. MTK 平台获取IMSI号码 以及如何截获系统中的各种消息
  18. 【每日新闻】2017年亚马逊研发投入排世界第一,超过华为、BAT 总和 | 数人云宣布与UMCloud合并...
  19. 天才富豪鲁宾:长于资产变废为宝
  20. 笔谈OpenGL ES(三)

热门文章

  1. 用于著作权申报的代码导出功能
  2. 计算机毕业设计Python+Django的旅游信息网站系统(源码+系统+mysql数据库+Lw文档)
  3. 转载:基于C语言中野指针的深入解析
  4. CentOS 7配置静态IP
  5. android系统佳明app,佳明garmin手表
  6. 【BZOJ 1115】【POI 2009】石子游戏Kam
  7. TS入门详解(typescript)
  8. ANSYS NGEN命令
  9. Sql Server 2008日志满的解决办法
  10. 亚商投资顾问 早餐FM/0607华虹公开发行股票注册