<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了java實現錄音播放的具體程式碼,供大家參考,具體內容如下
需求:
1.實現可以從麥克風進行錄音
2.可以停止錄音
3.實現播放錄音內容
4.並將所錄的mp3檔案全部存到F:/語音資料夾,語音的檔名以當前時間命名(java中是換算成秒),其中資料夾程式自己建立,不用擔心出錯
程式如下:
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.io.*; import javax.sound.sampled.*; 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; //定義所需要的元件 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(); }else if (e.getActionCommand().equals("stopBtn")) { //點選停止錄音按鈕的動作 captureBtn.setEnabled(true); stopBtn.setEnabled(false); playBtn.setEnabled(true); saveBtn.setEnabled(true); //呼叫停止錄音的方法 stop(); }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/O td.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(); } file = new File(filePath.getPath()+"/"+System.currentTimeMillis()+".mp3"); AudioSystem.write(ais, AudioFileFormat.Type.WAVE, file); } 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 { System.out.println("ok3"); 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(); } } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45