第二步:编辑文件首先在src下创建一个test包并在test包下新建一个类MyRecord具体步骤代码如下所示:

package test;

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

import java.io.*;

import javax.sound.sampled.*;

public class MyRecord extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;

// 定义录音格式

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);

}

// 录音类,因为要用到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();

}

}

}

}

python实现录音小程序 界面_小程序如何实现录音 播放功能相关推荐

  1. 微信小程序界面设计小程序中的WXSS(css)选择器课程-伪类-:focus 伪类

    小程序中的WXSS(css)选择器课程-伪类-:focus 伪类 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/hua ...

  2. 微信小程序界面设计小程序中的WXSS(css)选择器课程-伪类-:checked 伪类(不支持)

    小程序中的WXSS(css)选择器课程-伪类-:checked 伪类(不支持) 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/to ...

  3. 微信小程序界面设计小程序中的WXSS(css)选择器课程-::before伪元素

    小程序中的WXSS(css)选择器课程-::before伪元素 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/huan ...

  4. 微信小程序界面设计小程序中的WXSS(css)选择器课程-伪类-:nth-child() 伪类

    小程序中的WXSS(css)选择器课程-伪类-:nth-child() 伪类 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/top ...

  5. 微信小程序界面设计小程序中的WXSS(css)选择器课程-伪类-:nth-last-child伪类

    小程序中的WXSS(css)选择器课程-伪类-:nth-last-child伪类 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/t ...

  6. 微信小程序界面设计小程序中CSS3样式精通课程-渐变Gradients-线性渐变Linear Gradients

    线性渐变Linear Gradients 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/huangjuhua 通用语法 ...

  7. 微信小程序界面设计小程序中CSS3样式精通课程-渐变Gradients-使用透明度(transparent)

    渐变Gradients-使用透明度(transparent) 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/huang ...

  8. 微信小程序界面设计小程序中的WXSS(css)选择器课程-子元素选择器

    小程序中的WXSS(css)选择器课程-子元素选择器 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/huangjuhu ...

  9. 微信小程序界面设计小程序中CSS3样式精通课程-边框-box-shadow 盒阴影

    边框-box-shadow 盒阴影 微信小程序交流群:111733917 | 微信小程序从0基础到就业的课程:https://edu.csdn.net/topic/huangjuhua 通用语法 浏览 ...

最新文章

  1. 2021-01-24过去十年十大AI研究热点,分别为深度神经网络、特征抽取、图像分类、目标检测、语义分割、表示学习、生成对抗网络、语义网络、协同过滤和机器翻译。
  2. Lua基础之字符串(string)
  3. python中怎么比较两个列表-python中如何比较两个列表
  4. 血栓清道夫机器人_血栓“清道夫”找到了!洋葱排最后,排在第一很多人并不知道...
  5. 如何在Cloud for Customer overview UI上扩展新的按钮
  6. git 命令总结(转)
  7. Mahout聚类分析
  8. [附源码]Java计算机毕业设计SSM餐厅订餐系统
  9. mac 上查看字体文件的路径
  10. 农业农村部:发现生猪、野猪异常死亡应立即报告
  11. 注册一个域名需要多少钱_注册一个新的域名需要多少钱 注册域名费用明细
  12. 猜大小游戏(条件判断)
  13. 【线程池封装】实现简单回射服务器
  14. Compilation error :org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException
  15. 王阳明心学主要讲了什么
  16. 服务器推送小程序,小程序之主动推送消息(订阅消息)
  17. xps是什么文件?xps文件怎么打开?
  18. 【模拟IC】运算放大器设计指标简析之直流特性
  19. 心跳丢失造成RAC节点驱逐
  20. 如何让PDF不可编辑?

热门文章

  1. (需求实战_进阶_07)SSM集成RabbitMQ 订阅模式 关键代码讲解、开发、测试
  2. redis 公网 安全_redis漏洞复现
  3. 定义快捷代码_nodepad++代码编辑器替代工具整理
  4. datagrid如何获取一行数据中的某个字段值_SQL中常见的面试题
  5. qt种实现搜索栏功能
  6. C语言代码注释 - C语言零基础入门教程
  7. int类型数字特别大
  8. BugkuCTF-WEB题file_get_contents
  9. linux下进程监听端口,linux下查看监听端口对应的进程
  10. centos6.5 mysql主从_CentosMysql主从备份