http://www.xuebuyuan.com/1749979.html

最近做的一个小项目中,师兄安排的任务,要实现录音然后保存文件,实现网络传输,然后我用初学的java实现了一个录音机的功能(见前面的博客),但是windows录音默认保存的格式是WAVE,后缀是WAV,经过大量测试,录制一分钟要1M大小,这样不便于网络的传输,于是下面的任务就是实现音频压缩了,搜了几天,找到了一个不错的软件Monkey Audio(实现说明,我们的项目得全是代码实现的),这个软件的开源的,但是在官网下载的源代码经过我们一个下午的测试,竟然跟最新软件的压缩差的很远,于是我们便尝试走其他的路,比如:音频格式转换也可以达到音频压缩的目的,于是便搜类似的东西,于是便找到了Lame解码器。

百度百科普及:

LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择。LAME本身是DOS下的文件,需要加外壳程序才比较容易使用,也可以在别的软件(比如EAC)中间调用。是一款出色的MP3压缩程序,它使用了独创的人体听音心理学模型和声学模型,改变了人们对MP3高音发哑、低音发破的音质的印象。

然后我就通过代码在程序调用这个解码器,实现了最后的音频格式转换,当然也达到的压缩的目地,并且经过大量的测试,效果非常不错,并没有损坏音频,同时压缩比很高。

事先说明:Lame.exe文件必须得有,并且在程序调用的时候,如果没在java的src同一个文件夹下的话,必须在程序中使用绝对路径,否则报错。

贴出完整的录音代码(这次与上次博文中代码添加了音频格式转换的代码)

/** 实现录音机的功能*/
package com.liuyun.MyRecord1;import java.awt.*;import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import javax.sound.sampled.*;
import java.lang.*;public class MyRecord extends JFrame implements ActionListener{//定义录音格式AudioFormat af = null;//定义目标数据行,可以从中读取音频数据,该 TargetDataLine 接口提供从目标数据行的缓冲区读取所捕获数据的方法。TargetDataLine td = null;//定义源数据行,源数据行是可以写入数据的数据行。它充当其混频器的源。应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。SourceDataLine sd = null;//定义字节数组输入输出流ByteArrayInputStream bais = null;ByteArrayOutputStream baos = null;//定义音频输入流AudioInputStream ais = null;//定义停止录音的标志,来控制录音线程的运行Boolean stopflag = false;//记录开始录音的时间long startPlay;//定义所需要的组件JPanel jp1,jp2,jp3;JLabel jl1=null;JButton captureBtn,stopBtn,playBtn,saveBtn;public static void main(String[] args) {//创造一个实例MyRecord mr = new MyRecord();}//构造函数public MyRecord(){//组件初始化jp1 = new JPanel();jp2 = new JPanel();jp3 = new JPanel();//定义字体Font myFont = new Font("华文新魏",Font.BOLD,30);jl1 = new JLabel("录音机功能的实现");jl1.setFont(myFont);jp1.add(jl1);captureBtn = new JButton("开始录音");//对开始录音按钮进行注册监听captureBtn.addActionListener(this);captureBtn.setActionCommand("captureBtn");//对停止录音进行注册监听stopBtn = new JButton("停止录音");stopBtn.addActionListener(this);stopBtn.setActionCommand("stopBtn");//对播放录音进行注册监听playBtn = new JButton("播放录音");playBtn.addActionListener(this);playBtn.setActionCommand("playBtn");//对保存录音进行注册监听saveBtn = new JButton("保存录音");saveBtn.addActionListener(this);saveBtn.setActionCommand("saveBtn");this.add(jp1,BorderLayout.NORTH);this.add(jp2,BorderLayout.CENTER);this.add(jp3,BorderLayout.SOUTH);jp3.setLayout(null);jp3.setLayout(new GridLayout(1, 4,10,10));jp3.add(captureBtn);jp3.add(stopBtn);jp3.add(playBtn);jp3.add(saveBtn);//设置按钮的属性captureBtn.setEnabled(true);stopBtn.setEnabled(false);playBtn.setEnabled(false);saveBtn.setEnabled(false);//设置窗口的属性this.setSize(400,300);this.setTitle("录音机");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setLocationRelativeTo(null);this.setVisible(true);}public void actionPerformed(ActionEvent e) {if(e.getActionCommand().equals("captureBtn")){//点击开始录音按钮后的动作//停止按钮可以启动captureBtn.setEnabled(false);stopBtn.setEnabled(true);playBtn.setEnabled(false);saveBtn.setEnabled(false);//调用录音的方法capture();//记录开始录音的时间startPlay = System.currentTimeMillis();}else if (e.getActionCommand().equals("stopBtn")) {//点击停止录音按钮的动作captureBtn.setEnabled(true);stopBtn.setEnabled(false);playBtn.setEnabled(true);saveBtn.setEnabled(true);//调用停止录音的方法     stop();//记录停止录音的时间long stopPlay = System.currentTimeMillis();//输出录音的时间System.out.println("Play continues " + (stopPlay-startPlay));}else if(e.getActionCommand().equals("playBtn")){//调用播放录音的方法play();}else if(e.getActionCommand().equals("saveBtn")){//调用保存录音的方法save();}}//开始录音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();//创建播放录音的线程Record record = new Record();Thread t1 = new Thread(record);t1.start();} catch (LineUnavailableException ex) {ex.printStackTrace();return;}}//停止录音public void stop(){stopflag = true;           }//播放录音public void play(){//将baos中的数据转换为字节数据byte audioData[] = baos.toByteArray();//转换为输入流bais = new ByteArrayInputStream(audioData);af = getAudioFormat();ais = new AudioInputStream(bais, af, audioData.length/af.getFrameSize());try {DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, af);sd = (SourceDataLine) AudioSystem.getLine(dataLineInfo);sd.open(af);sd.start();//创建播放进程Play py = new Play();Thread t2 = new Thread(py);t2.start();           } catch (Exception e) {e.printStackTrace();}finally{try {//关闭流if(ais != null){ais.close();}if(bais != null){bais.close();}if(baos != null){baos.close();}} catch (Exception e) {      e.printStackTrace();}}}//保存录音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("F:/语音文件");if(!filePath.exists()){//如果文件不存在,则创建该目录filePath.mkdir();}long time = System.currentTimeMillis();file = new File(filePath+"/"+time+".wav");      AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file);//将录音产生的wav文件转换为容量较小的mp3格式//定义产生后文件名String tarFileName = time+".mp3";Runtime run = null;try {run = Runtime.getRuntime();long start=System.currentTimeMillis();//调用解码器来将wav文件转换为mp3文件<strong><span style="color:#ff0000;">Process p=run.exec(filePath+"/"+"lame -b 16 "+filePath+"/"+file.getName()+" "+filePath+"/"+tarFileName); //16为码率,可自行修改</span></strong>//释放进程p.getOutputStream().close();p.getInputStream().close();p.getErrorStream().close();p.waitFor();long end=System.currentTimeMillis();System.out.println("convert need costs:"+(end-start)+"ms");//删除无用的wav文件if(file.exists()){file.delete();}} 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();}       }}//设置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);}}} catch (Exception e) {e.printStackTrace();}finally{try {//关闭打开的字节数组流if(baos != null){baos.close();}  } catch (IOException e) {e.printStackTrace();}finally{td.drain();td.close();}}}}//播放类,同样也做成内部类class Play implements Runnable{//播放baos中的数据即可public void run() {byte bts[] = new byte[10000];try {int cnt;//读取数据到缓存数据while ((cnt = ais.read(bts, 0, bts.length)) != -1) {if (cnt > 0) {//写入缓存数据//将音频数据写入到混频器sd.write(bts, 0, cnt);}}} catch (Exception e) {e.printStackTrace();}finally{sd.drain();sd.close();}}        }
}

Java实现音频格式转换 WAV—mp3,可使音频压缩相关推荐

  1. Java实现音频格式转换 WAV---mp3,可使音频压缩

    最近做的一个小项目中,师兄安排的任务,要实现录音然后保存文件,实现网络传输,然后我用初学的java实现了一个录音机的功能(见前面的博客),但是windows录音默认保存的格式是WAVE,后缀是WAV, ...

  2. 音频如何转换成mp3格式?详细步骤解析

    音频如何转换成mp3格式?我以为对音频转mp3这个小小的技巧,大家肯定都有方法自己转换的,就是没想到最近几天接连不断的有人咨询我音频怎么转mp3格式, 因为这样的东西对我而言真的信手拈来,所以在我的思 ...

  3. 声音的变奏:深入理解ffmpeg音频格式转换的奥秘与应用

    声音的变奏:深入理解音频格式转换的奥秘与应用 1. 音频数据的本质:声音与数字 (The Nature of Audio Data: Sound and Numbers) 1.1 音频的物理与数学基础 ...

  4. java aud 转mp3_音频格式转换:微信语音aud格式转成wav格式

    近期遇到音频格式问题,下面就来记录一下,我暂时还没有找到直接从音频格式aud转换成wav的工具或者代码,所以我这里的转换是先把aud转换成mp3格式,然后再从mp3格式转换成aud格式.我是在linu ...

  5. Matlab 音频格式转换(wav,ogg,flac,au,aiff,aif,aifc,mp3,m4a,mp4 互转)

    欢迎转载,但请一定要给出原文链接,标注出处,支持原创! 谢谢~ https://blog.csdn.net/qq_29225913/article/details/105445028 目录 1.目标及 ...

  6. 让我来推荐几个WAV音频格式转换软件

    大家是否跟我一样对音频文件格式接触的比较多的是MP3和FLAC,然而某一天我在传输歌曲时发现了一首歌是WAV格式.了解后才发现原来WAV是微软开放的一种标准数字音频文件,这个格式能记录单声道或者立体声 ...

  7. 苹果mp3软件_音频格式转换软件

    Music Converter Pro Mac免激活版是Mac平台上的一款非常不错的音频格式转换软件,Music Converter Pro Mac中文版能够免费支持多种格式的转换,只需要点击拖放即可 ...

  8. 苹果mp3软件_一款非常不错的音频格式转换软件

    Music Converter Pro Mac免激活版是Mac平台上的一款非常不错的音频格式转换软件,Music Converter Pro Mac中文版能够免费支持多种格式的转换,只需要点击拖放即可 ...

  9. 格式工厂 wav 比特率_DRmare Audio Converter——音频格式转换工具

    DRmare Audio Converter Mac是一款音频格式转换.drmare audio converter mac适合将Apple Music,iTunes歌曲转换为其他格式,突破歌曲本身D ...

  10. 格式工厂 wav 比特率_想拥有一款音频格式转换工具吗?TunesKit Audio Converter

    想拥有一款音频格式转换工具吗?TunesKit Audio Converter Mac版是一款Mac上的音频格式转换工具,可以将所有类型的DRM和无DRM音频文件转换为多种格式,十分强大!可以根据你的 ...

最新文章

  1. Spark:group by和聚合函数使用
  2. 基于Shodan Python库的批量攻击实践 撒旦网
  3. mysql centos 源码安装_CentOS5下MySQL源码安装方式
  4. 访问vue实例中的数据
  5. 全球及中国塑料薄膜行业产销现状及投资竞争力分析报告2021版
  6. linux系统下载经验,linux系统的学习经验首篇
  7. 启动Kafka失败Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c0000000, 107
  8. 通信协议—HTTP、TCP、UDP
  9. USB共享网络:android手机通过USB与Ubuntu进行socket网络通信
  10. 订阅mysql的二进制日志_MySQL二进制日志
  11. 今天起,我们喝的百年牛奶要变了!
  12. Oracle 索引相关
  13. 钩子教程 - 原理(一)
  14. Flask-MDict搭建在线Mdict词典服务
  15. oracle清理磁盘空间
  16. 云炬随笔集(2016.7~2022.1)
  17. 如何判断企业微信是否在线?
  18. win10内置ubuntu, 启动时提示“指定的网络名不再可用”无法启动解决办法
  19. Spring Boot优点和缺点
  20. 强化学习环境学习-gym[atari]-paper中的相关设置

热门文章

  1. 软件测试基础之功能性测试
  2. 百度网盘linux微博登录,百度网盘,微博登录
  3. Java接入第三方微博登陆
  4. SQL项目实战练习:淘宝用户行为数据分析实战
  5. Skype 8.34 Windows7-64bit Ubuntu 16.04安装试验
  6. 计算机及数码产品营销课后题,职业教育课程改革创新系列教材:计算机及数码产品营销...
  7. IT大学生应该经常浏览的十大网站
  8. ORACLE表空间碎片整理
  9. steam无法连接至计算机,详解无法连接至steam网络怎么办
  10. 中国移动互联网半年大报告解析