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.pswp.cn/news/696085.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696085.shtml
英文地址,請注明出處:http://en.pswp.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;發電量的準確計算是評估系統性能、預測長期收益和優化系統運行的關鍵。以下是常見的光伏發電量計算方法&…