Java SourceDataLine 播放音频

Java SourceDataLine 播放音频

  • 1 依赖
  • 2 接口
  • 3 实现
  • 4 测试

项目Value
音频格式 添加依赖
*.wav(JDK 原生支持)
*.pcm(JDK 原生支持)
*.au(JDK 原生支持)
*.aiff(JDK 原生支持)
*.mp3mp3spi.jar
*.flacjflac-codec.jar

1 依赖

<dependency><groupId>com.googlecode.soundlibs</groupId><artifactId>mp3spi</artifactId><version>1.9.5.4</version>
</dependency><!-- 如果需要解码播放flac文件则引入这个jar包 -->
<dependency><groupId>org.jflac</groupId><artifactId>jflac-codec</artifactId><version>1.5.2</version>
</dependency>

2 接口

package com.xu.music.player.player;import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioFormat.Encoding;
import javax.sound.sampled.AudioInputStream;import java.io.File;
import java.net.URL;/*** Java 音频播放** @author hyacinth* @date 2019年10月31日19:06:39*/
public interface Player {/*** Java Music 加载音频** @param url 音频文件url* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(URL url) throws Exception;/*** Java Music 加载音频** @param file 音频文件* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(File file) throws Exception;/*** Java Music 加载音频** @param path 文件路径* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(String path) throws Exception;/*** Java Music 加载音频** @param stream 音频文件输入流* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(AudioInputStream stream) throws Exception;/*** Java Music 加载音频** @param encoding Encoding* @param stream   AudioInputStream* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(Encoding encoding, AudioInputStream stream) throws Exception;/*** Java Music 加载音频** @param format AudioFormat* @param stream AudioInputStream* @throws Exception 异常* @date 2019年10月31日19:06:39*/void load(AudioFormat format, AudioInputStream stream) throws Exception;/*** Java Music 暂停播放** @date 2019年10月31日19:06:39*/void pause();/*** Java Music 继续播放** @date 2019年10月31日19:06:39*/void resume();/*** Java Music 开始播放** @throws Exception 异常* @date 2019年10月31日19:06:39*/void play() throws Exception;/*** Java Music 结束播放** @description: Java Music 结束播放* @date 2019年10月31日19:06:39*/void stop();}

3 实现

package com.xu.music.player.player;import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.CharSequenceUtil;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Deque;
import java.util.LinkedList;import com.xu.music.player.system.Constant;/*** Java 音频播放** @author hyacinth* @date 2019年10月31日19:06:39*/
public class XPlayer implements Player {private static SourceDataLine data = null;private static AudioInputStream audio = null;public static final Deque<Double> deque = new LinkedList<>();public void put(Double v) {synchronized (deque) {deque.add(v);if (deque.size() > Constant.SPECTRUM_TOTAL_NUMBER) {deque.removeFirst();}}}private XPlayer (){}public static XPlayer createPlayer() {return XPlayer.SingletonHolder.player;}private static class SingletonHolder {private static final XPlayer player = new XPlayer();}@Overridepublic void load(URL url) throws Exception {load(AudioSystem.getAudioInputStream(url));}@Overridepublic void load(File file) throws Exception {String name = file.getName();if (CharSequenceUtil.endWithIgnoreCase(name, ".mp3")) {AudioInputStream stream = new MpegAudioFileReader().getAudioInputStream(file);AudioFormat format = stream.getFormat();format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(),format.getChannels() * 2, format.getSampleRate(), false);stream = AudioSystem.getAudioInputStream(format, stream);load(stream);} else if (CharSequenceUtil.endWithIgnoreCase(name, ".flac")) {AudioInputStream stream = AudioSystem.getAudioInputStream(file);AudioFormat format = stream.getFormat();format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(),format.getChannels() * 2, format.getSampleRate(), false);stream = AudioSystem.getAudioInputStream(format, stream);load(stream);} else {load(AudioSystem.getAudioInputStream(file));}}@Overridepublic void load(String path) throws Exception {load(new File(path));}@Overridepublic void load(AudioInputStream stream) throws Exception {DataLine.Info info = new DataLine.Info(SourceDataLine.class, stream.getFormat(), AudioSystem.NOT_SPECIFIED);data = (SourceDataLine) AudioSystem.getLine(info);data.open(stream.getFormat());audio = stream;}@Overridepublic void load(AudioFormat.Encoding encoding, AudioInputStream stream) throws Exception {load(AudioSystem.getAudioInputStream(encoding, stream));}@Overridepublic void load(AudioFormat format, AudioInputStream stream) throws Exception {load(AudioSystem.getAudioInputStream(format, stream));}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic void play() throws IOException {if (null == audio || null == data) {return;}data.start();byte[] buf = new byte[4];int channels = audio.getFormat().getChannels();float rate = audio.getFormat().getSampleRate();while (audio.read(buf) != -1) {if (channels == 2) {//立体声if (rate == 16) {put((double) ((buf[1] << 8) | buf[0]));//左声道//put((double) ((buf[3] << 8) | buf[2]));//右声道} else {put((double) buf[1]);//左声道put((double) buf[3]);//左声道//put((double) buf[2]);//右声道//put((double) buf[4]);//右声道}} else {//单声道if (rate == 16) {put((double) ((buf[1] << 8) | buf[0]));put((double) ((buf[3] << 8) | buf[2]));} else {put((double) buf[0]);put((double) buf[1]);put((double) buf[2]);put((double) buf[3]);}}data.write(buf, 0, 4);}}@Overridepublic void stop() {if (null == audio || null == data) {return;}IoUtil.close(audio);data.stop();IoUtil.close(data);}}

4 测试

package com.xu.music.player.player;import java.io.File;/*** Java 音频播放** @author hyacinth* @date 2019年10月31日19:06:39*/
public class Test {public static void main(String[] args) throws Exception {Player player = XPlayer.createPlayer();player.load(new File("D:\\Kugou\\梦涵 - 加减乘除.mp3"));player.play();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

⭐北邮复试刷题LCR 052. 递增顺序搜索树__DFS (力扣119经典题变种挑战)

LCR 052. 递增顺序搜索树 给你一棵二叉搜索树&#xff0c;请 按中序遍历 将其重新排列为一棵递增顺序搜索树&#xff0c;使树中最左边的节点成为树的根节点&#xff0c;并且每个节点没有左子节点&#xff0c;只有一个右子节点。 示例 1&#xff1a; 输入&#xff1a;root [5,…

DataX - 全量数据同步工具

前言 今天是2024-2-21&#xff0c;农历正月十二&#xff0c;相信今天开始是新的阶段&#xff0c;尽管它不是新的周一、某月一日、某年第一天&#xff0c;尽管我是一个很讲究仪式感的人。新年刚过去 12 天&#xff0c;再过 3 天就开学咯&#xff0c;开学之后我的大学时光就进入了…

TypeScript01:安装TypeScript

一、TypeScript 官方网站&#xff1a;https://www.tslang.cn/docs/index.html 练习场&#xff1a;https://www.typescriptlang.org/zh/play 好处&#xff1a; 强类型语言&#xff0c;对JS弱类型的一个良好补充&#xff1b;TS利于大型项目团队合作&#xff0c;可以一定程度…

这五个软件测试工具,测试工程师必备

在软件开发过程中&#xff0c;软件测试是确保软件质量和稳定性的关键环节。为了帮助开发人员和测试团队更好地完成这一任务&#xff0c;市面上涌现出众多软件测试工具。本文将盘点五个备受推崇的软件测试工具&#xff0c;它们各具特色&#xff0c;适用于不同的测试场景。 Test…

ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整

文章目录 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整获取音频长度pydub获取音频长度获取时长精确到秒格式设定 mutagen获取音频长度 调整音量视频音量调整注意事项 ChatGPT实战100例 - (17) 用ChatGPT实现音频长度测量和音量调整 老王媳妇说上次那个pip挺好…

深度学习的学习笔记帖子2

人脸数据集的介绍&#xff1a; https://zhuanlan.zhihu.com/p/362356480 https://blog.csdn.net/bjbz_cxy/article/details/122210641 CASIAWebFace人脸数据集等的github&#xff1a; https://github.com/deepinsight/insightface/blob/master/recognition/datasets/README.md…

蓝桥杯基础知识点9 stack、queue、priority_queue

蓝桥杯基础知识点9 stack、queue、priority_queue 01 stack的定义和结构 stack是一种后进先出&#xff08;LIFO&#xff09;的数据结构&#xff0c;头文件<stcak>。 template <class T, class Container deque<T>> class stack; T&#xff1a;存储在stack…

《VitePress 简易速速上手小册》第7章 高级功能与动态内容(2024 最新版)

文章目录 7.1 动态路由与 API 集成7.1.1 基础知识点解析7.1.2 重点案例&#xff1a;技术博客7.1.3 拓展案例 1&#xff1a;电商网站7.1.4 拓展案例 2&#xff1a;事件管理网站 7.2 状态管理与 Vuex 使用7.2.1 基础知识点解析7.2.2 重点案例&#xff1a;用户认证系统7.2.3 拓展案…

力扣精选算法100道——Z字形变换(模拟专题)

目录 &#x1f388;了解题意 &#x1f388;算法原理 &#x1f6a9;先处理第一行和最后一行 &#x1f6a9;再处理中间行 &#x1f388;实现代码 &#x1f388;了解题意 大家看到这个题目的时候肯定是很迷茫的&#xff0c;包括我自己也是搞不清楚题目什么意思&#xff0c;我…

memcpy和strcat的区别

memcpy 函数&#xff1a; memcpy 函数用于在内存之间复制一定数量的字节。memcpy 是按字节进行复制的&#xff0c;可以用于复制任意类型的数据&#xff0c;不仅限于字符串。memcpy 不会自动添加字符串结束符号 \0&#xff0c;因此在复制字符串时&#xff0c;需要确保复制的字节…

喝点小酒-胡诌“编程语言学习”

今天&#xff0c; 与一个小哥们儿&#xff08;学习计算机科学与技术专业的&#xff0c;我儿子&#xff0c;这是真的&#xff09;一块儿吃饭&#xff08;这顿饭&#xff0c;在家里吃的&#xff0c;吹个牛哈&#xff0c;我做的&#xff0c;三个荤菜、一个素材、一个汤、主食米饭 …

约瑟夫经典问题C++,STL容器queue解法

题目&#xff1a; Description n 个人围成一圈&#xff0c;从第一个人开始报数,数到 m 的人出列&#xff0c;再由下一个人重新从 1 开始报数&#xff0c;数到m 的人再出圈&#xff0c;依次类推&#xff0c;直到所有的人都出圈&#xff0c;请输出依次出圈人的编号。 注意&…

[linux]进程间通信(IPC)———共享内存(shm)(什么是共享内存,共享内存的原理图,共享内存的接口,使用演示)

一、什么是共享内存 共享内存区是最快的&#xff08;进程间通信&#xff09;IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核&#xff0c;换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。注意&#xff1a;…

Three.js初学(2)

Three.js初学&#xff08;2&#xff09; 三维坐标系的认识1. 辅助坐标系 光源的影响1. 光材质的影响2. 光源介绍点光源环境光平行光 3. 光源衰减/位置 相机控件1. 引入扩展库2. 使用方法 三维坐标系的认识 这一章节的主要作用是加强自我对三维坐标空间的认识。 1. 辅助坐标系…

猫头虎分享已解决Bug || TypeError: Cannot set property ‘innerHTML‘ of null

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

华为配置直连三层组网隧道转发示例

配置直连三层组网隧道转发示例 组网图形 图1 配置直连三层组网隧道转发示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件扩展阅读 业务需求 企业用户接入WLAN网络&#xff0c;以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff0c;不…

Linux 系统编程:文件编程

本篇涉及文件的创建、打开、读和关闭。 文件为操作系统服务和设备提供了一个简单而一致的 接口 。“接口”指的是一种约定或标准&#xff0c;通过提供一个一致的接口&#xff0c;可以为上层隐藏底层硬件和服务的复杂性&#xff0c;上层无需关注它们的具体实现细节。 比如操作系…

Kafka进阶

文章目录 概要应用场景消息队列两种模式kafka的基础架构分区常见问题小结 概要 kafka的传统定义&#xff1a;kafka是一个分布式的基于发布\订阅模式的消息队列&#xff0c;主要用于大数据实时处理领域。 kafka的最新概念&#xff1a;kafka是一个开源的分布式事件流平台&#x…

随机森林模型、模型模拟技术和决策树模型简介

随机森林模型、模型模拟技术和决策树模型简介 随机森林模型 随机森林模型是一种比较新的机器学习模型&#xff0c;它是通过集成学习的方法将多个决策树模型组合起来&#xff0c;形成一个更加强大和稳定的模型。随机森林模型的基本原理是“数据随机”和“特征随机”&#xff0…

10种常见的光伏发电量计算方法

光伏发电是一种将太阳能转化为电能的清洁能源技术。随着环境保护意识的日益增强和能源结构的转型&#xff0c;光伏发电得到了广泛的应用。对于光伏系统来说&#xff0c;发电量的准确计算是评估系统性能、预测长期收益和优化系统运行的关键。以下是常见的光伏发电量计算方法&…