java實現(xiàn)錄音播放功能
更新時間:2022年08月08日 13:03:56 作者:jsjliuyun
這篇文章主要為大家詳細介紹了java實現(xiàn)錄音播放功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了java實現(xiàn)錄音播放的具體代碼,供大家參考,具體內容如下
需求:
1.實現(xiàn)可以從麥克風進行錄音
2.可以停止錄音
3.實現(xiàn)播放錄音內容
4.并將所錄的mp3文件全部存到F:/語音文件夾,語音的文件名以當前時間命名(java中是換算成秒),其中文件夾程序自己創(chuàng)建,不用擔心出錯
程序如下:
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 接口提供從目標數據行的緩沖區(qū)讀取所捕獲數據的方法。 ?? ?TargetDataLine td = null; ?? ?//定義源數據行,源數據行是可以寫入數據的數據行。它充當其混頻器的源。應用程序將音頻字節(jié)寫入源數據行,這樣可處理字節(jié)緩沖并將它們傳遞給混頻器。 ?? ?SourceDataLine sd = null; ?? ?//定義字節(jié)數組輸入輸出流 ?? ?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) { ?? ??? ? ?? ??? ?//創(chuàng)造一個實例 ?? ??? ?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("錄音機功能的實現(xiàn)"); ?? ??? ?jl1.setFont(myFont); ?? ??? ?jp1.add(jl1); ?? ??? ? ?? ??? ?captureBtn = new JButton("開始錄音"); ?? ??? ?//對開始錄音按鈕進行注冊監(jiān)聽 ?? ??? ?captureBtn.addActionListener(this); ?? ??? ?captureBtn.setActionCommand("captureBtn"); ?? ??? ?//對停止錄音進行注冊監(jiān)聽 ?? ??? ?stopBtn = new JButton("停止錄音"); ?? ??? ?stopBtn.addActionListener(this); ?? ??? ?stopBtn.setActionCommand("stopBtn"); ?? ??? ?//對播放錄音進行注冊監(jiān)聽 ?? ??? ?playBtn = new JButton("播放錄音"); ?? ??? ?playBtn.addActionListener(this); ?? ??? ?playBtn.setActionCommand("playBtn"); ?? ??? ?//對保存錄音進行注冊監(jiān)聽 ?? ??? ?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)); ?? ??? ??? ?//打開具有指定格式的行,這樣可使行獲得所有所需的系統(tǒng)資源并變得可操作。 ?? ??? ??? ?td.open(af); ?? ??? ??? ?//允許某一數據行執(zhí)行數據 I/O ?? ??? ??? ?td.start(); ?? ??? ??? ? ?? ??? ??? ?//創(chuàng)建播放錄音的線程 ?? ??? ??? ?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中的數據轉換為字節(jié)數據 ?? ??? ?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(); ? ? ? ? ? ? //創(chuàng)建播放進程 ? ? ? ? ? ? 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()) ? ? ? ? ?? ?{//如果文件不存在,則創(chuàng)建該目錄 ? ? ? ? ?? ??? ?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 ?? ?{ ?? ??? ?//定義存放錄音的字節(jié)數組,作為緩沖區(qū) ?? ??? ?byte bts[] = new byte[10000]; ?? ??? ?//將字節(jié)數組包裝到流里,最終存入到baos中 ?? ??? ?//重寫run函數 ?? ??? ?public void run() {?? ? ?? ??? ??? ?baos = new ByteArrayOutputStream();?? ??? ? ?? ??? ??? ?try { ?? ??? ??? ??? ?System.out.println("ok3"); ?? ??? ??? ??? ?stopflag = false; ?? ??? ??? ??? ?while(stopflag != true) ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?//當停止錄音沒按下時,該線程一直執(zhí)行?? ? ?? ??? ??? ??? ??? ?//從數據行的輸入緩沖區(qū)讀取音頻數據。 ?? ??? ??? ??? ??? ?//要讀取bts.length長度的字節(jié),cnt 是實際讀取的字節(jié)數 ?? ??? ??? ??? ??? ?int cnt = td.read(bts, 0, bts.length); ?? ??? ??? ??? ??? ?if(cnt > 0) ?? ??? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ??? ?baos.write(bts, 0, cnt); ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} catch (Exception e) { ?? ??? ??? ??? ?e.printStackTrace(); ?? ??? ??? ?}finally{ ?? ??? ??? ??? ?try { ?? ??? ??? ??? ??? ?//關閉打開的字節(jié)數組流 ?? ??? ??? ??? ??? ?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技術實現(xiàn)上傳下載文件到FTP服務器(完整)
這篇文章主要介紹了JAVA技術實現(xiàn)上傳下載文件到FTP服務器(完整),本文使用 Apache Jakarta Commons Net(commons-net-3.3.jar) 基于FileZilla Server服務器實現(xiàn)FTP服務器上文件的上傳/下載/刪除等操作,需要的朋友可以參考下2015-07-07