91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何用Java播放聲音

科技綠洲 ? 來(lái)源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-09 10:56 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在本篇文章中,我們將學(xué)習(xí)如何用Java播放音樂(lè),Java 聲音 API 的設(shè)計(jì)是為了流暢和連續(xù)地播放聲音,甚至是很長(zhǎng)的聲音。我們將使用 Java 提供的 ClipSourceDataLine 聲音API播放一個(gè)音頻文件。

播放聲音的Java APIs

一般來(lái)說(shuō),javax.sound 包中的Java Sound APIs提供了兩種播放音頻的方法。在這兩種方法之間,在如何指定聲音文件數(shù)據(jù)方面有區(qū)別。Java Sound APIs可以以流式、緩沖方式和內(nèi)存、非緩沖方式處理音頻傳輸。Java的兩個(gè)最著名的聲音API是 ClipSourceDataLine。

Clip API

Clip API是Java的一個(gè)非緩沖或內(nèi)存聲音API。Clip類(lèi)是javax.sound.sampled包的一部分,它在讀取和播放短的聲音文件時(shí)有用。在播放之前,整個(gè)音頻文件被加載到內(nèi)存中,用戶(hù)可以完全控制播放。除了循環(huán)播放聲音外,它還允許用戶(hù)在一個(gè)隨機(jī)的位置開(kāi)始播放。

讓我們首先創(chuàng)建一個(gè)示例類(lèi),SoundPlayerWithClip,它實(shí)現(xiàn)了LineListener接口,以便接收播放的線事件(OPEN、CLOSESTARTSTOP)。我們將從LineListener實(shí)現(xiàn)update()方法來(lái)檢查播放狀態(tài)。

public class SoundPlayerUsingClip implements LineListener {

    boolean isPlaybackCompleted;
    
    @Override
    public void update(LineEvent event) {
        if (LineEvent.Type.START == event.getType()) {
            System.out.println("Playback started.");
        } else if (LineEvent.Type.STOP == event.getType()) {
            isPlaybackCompleted = true;
            System.out.println("Playback completed.");
        }
    }
}

其次,讓我們從我們項(xiàng)目的資源文件夾中讀取音頻文件。我們的資源文件夾包含三個(gè)不同格式的音頻文件--即WAV、MP3和MPEG。

InputStream inputStream = getClass().getClassLoader().getResourceAsStream(audioFilePath);

第三,從文件流中,我們將創(chuàng)建一個(gè)AudioInputStream。

AudioInputStream audioStream = AudioSystem.getAudioInputStream(inputStream);

現(xiàn)在,我們將創(chuàng)建一個(gè)DataLine.Info對(duì)象。

AudioFormat audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);

讓我們從這個(gè)DataLine.Info創(chuàng)建一個(gè)Clip對(duì)象,并打開(kāi)流,然后調(diào)用start來(lái)開(kāi)始播放音頻。

Clip audioClip = (Clip) AudioSystem.getLine(info);
audioClip.addLineListener(this);
audioClip.open(audioStream);
audioClip.start();

最后,我們需要關(guān)閉任何開(kāi)放的資源。

audioClip.close();
audioStream.close();

一旦代碼運(yùn)行,音頻文件就會(huì)播放。

由于音頻被預(yù)裝在內(nèi)存中,我們有許多其他有用的API,我們可以從中受益。

我們可以使用Clip.loop方法來(lái)連續(xù)循環(huán)播放音頻片段。

例如,我們可以把它設(shè)置為播放五次音頻。

audioClip.loop(4);

或者,我們可以設(shè)置它無(wú)限期地播放音頻(或直到中斷)。

audioClip.loop(Clip.LOOP_CONTINUUSLY);

Clip.setMicrosecondPosition設(shè)置媒體位置。當(dāng)剪輯下次開(kāi)始播放時(shí),它將從這個(gè)位置開(kāi)始。例如,要從第30秒開(kāi)始,我們可以這樣設(shè)置。

audioClip.setMicrosecondPosition(30_000_000);

SourceDataLine API

SourceDataLine API是java的一個(gè)緩沖或流式聲音API。SourceDataLine類(lèi)是javax.sound.sampled包的一部分,它可以播放無(wú)法預(yù)裝到內(nèi)存中的長(zhǎng)聲音文件。

當(dāng)我們希望優(yōu)化大的音頻文件的內(nèi)存時(shí),或者在流傳實(shí)時(shí)音頻數(shù)據(jù)時(shí),使用SourceDataLine更有效。如果我們事先不知道聲音有多長(zhǎng),何時(shí)結(jié)束,它也很有用。

讓我們首先創(chuàng)建一個(gè)示例類(lèi),從我們項(xiàng)目的資源文件夾中讀取音頻文件。我們的資源文件夾包含三個(gè)不同格式的音頻文件--即WAV、MP3和MPEG。

InputStream inputStream = getClass().getClassLoader().getResourceAsStream(audioFilePath);

第二,從文件輸入流中,我們將創(chuàng)建一個(gè)AudioInputStream

AudioInputStream audioStream = AudioSystem.getAudioInputStream(inputStream);

現(xiàn)在,我們將創(chuàng)建一個(gè)DataLine.Info對(duì)象。

AudioFormat audioFormat = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);

讓我們從這個(gè)DataLine.Info創(chuàng)建一個(gè)SourceDataLine對(duì)象,打開(kāi)流,并調(diào)用start來(lái)開(kāi)始播放音頻。

SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(audioFormat);
sourceDataLine.start();

現(xiàn)在,在SourceDataLine的情況下,的音頻數(shù)據(jù)是分塊加載的,我們需要提供緩沖區(qū)的大小。

private static final int BUFFER_SIZE = 4096;

現(xiàn)在,讓我們從AudioInputStream讀取音頻數(shù)據(jù),并將其發(fā)送到SourceDataLine的播放緩沖區(qū),直到它到達(dá)流的末端。

byte[] bufferBytes = new byte[BUFFER_SIZE];
int readBytes = -1;
while ((readBytes = audioStream.read(bufferBytes)) != -1) {
    sourceDataLine.write(bufferBytes, 0, readBytes);
}

最后,讓我們關(guān)閉任何開(kāi)放的資源。

sourceDataLine.drain();
sourceDataLine.close();
audioStream.close();

一旦代碼運(yùn)行,音頻文件就會(huì)播放。在這里,我們不需要實(shí)現(xiàn)任何LineListener接口。

ClipSourceDataLine之間的比較

讓我們來(lái)討論一下兩者的優(yōu)點(diǎn)和缺點(diǎn)。

ClipSourceDataLine
支持從音頻的任何位置播放。參見(jiàn)setMicrosecondPosition(long)setFramePosition(int).不能從聲音中的任意位置開(kāi)始播放。
支持在循環(huán)中播放(全部或部分的聲音)。 參見(jiàn)setLoopPoints(int, int)loop(int).不能播放(循環(huán))全部或部分聲音。
可以在播放前知道聲音的持續(xù)時(shí)間。參見(jiàn)getFrameLength()getMicrosecondLength().在播放前不能知道聲音的持續(xù)時(shí)間。
可以在當(dāng)前位置停止播放,稍后繼續(xù)播放。請(qǐng)看stop()start()不能在中間停止和恢復(fù)播放。
不適合播放大的音頻文件,也沒(méi)有效率,因?yàn)樗窃趦?nèi)存中的。適合播放長(zhǎng)的聲音文件或?qū)崟r(shí)的聲音流。
Clip的start()方法確實(shí)在播放聲音,但它不會(huì)阻塞當(dāng)前線程(它立即返回),所以它需要實(shí)現(xiàn)LineListener接口來(lái)了解播放狀態(tài)。與Clip不同,我們不需要實(shí)現(xiàn)LineListener接口來(lái)知道什么時(shí)候播放完成。
不可能控制什么聲音數(shù)據(jù)被寫(xiě)入音頻線的播放緩沖區(qū)。可以控制哪些聲音數(shù)據(jù)要被寫(xiě)入音頻線的播放緩沖區(qū)。

Java API對(duì)MP3格式的支持

目前,ClipSourceDataLine都可以播放AIFC、AIFF、AU、SND和WAV格式的音頻文件。

我們可以使用AudioSystem檢查支持的音頻格式。

Type[] list = AudioSystem.getAudioFileTypes();
    StringBuilder supportedFormat = new StringBuilder("Supported formats:");
    for (Type type : list) {
        supportedFormat.append(", " + type.toString());
    }
    System.out.println(supportedFormat.toString());

然而,我們不能用Java Sound APIs ClipSourceDataLine 播放流行的音頻格式MP3/MPEG。`我們需要尋找一些能播放MP3格式的第三方庫(kù)。

如果我們向 ClipSourceDataLine API提供MP3格式的文件,我們會(huì)得到UnsupportedAudioFileException 。

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file
        at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1189)

總結(jié)

在這篇文章中,我們學(xué)習(xí)了如何用Java播放聲音。我們還了解了兩個(gè)不同的Java聲音API - ClipSourceDataLine。我們了解了 ClipSourceDataLine API之間的區(qū)別。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 音頻
    +關(guān)注

    關(guān)注

    31

    文章

    3186

    瀏覽量

    85523
  • 緩沖
    +關(guān)注

    關(guān)注

    0

    文章

    53

    瀏覽量

    18231
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    9

    文章

    3209

    瀏覽量

    76352
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    3001

    瀏覽量

    116411
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    2365

    瀏覽量

    66745
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    ESP32-C5怎么播放聲音?

    我看了ESP32-C5的介紹,沒(méi)發(fā)現(xiàn)它有I2C和I2S,那怎么播放聲音?看到來(lái)ADF和它無(wú)關(guān)。
    發(fā)表于 06-28 08:29

    Tas5825pevm無(wú)法通過(guò)usb播放聲音怎么辦

    無(wú)法通過(guò)usb播放聲音 ppc顯示需要ID地址為0x98 但evm板ID為0x97 我該怎么修?
    發(fā)表于 10-09 07:11

    wince系統(tǒng)playsound單獨(dú)播放聲音正常,進(jìn)去地圖里面播放就有雜音的原因?

    地圖也是用playsound播放聲音,同樣的音頻文件,只是進(jìn)去地圖播放有雜音。在地圖播放聲音過(guò)程中cpu和內(nèi)存實(shí)用率都沒(méi)有超過(guò)50%。音頻芯片tlv320aic3106。
    發(fā)表于 10-29 06:05

    TPA3110無(wú)法播放聲音的原因?怎么解決?

    立刻重新制作了一塊新的板子,最后還是無(wú)法播放聲音。 在接下來(lái)的查找錯(cuò)誤原因中,我們發(fā)現(xiàn)以下幾種有價(jià)值的情況: 1,首先,如果先在輸入端輸入音頻信號(hào),再接通電源,板子可以短暫的播放一會(huì)音樂(lè)。但如果暫?;?/div>
    發(fā)表于 11-05 07:39

    C#中如何播放聲音

    C#中沒(méi)有聲音類(lèi)。播放聲音請(qǐng)參閱API!比如:  [DllImport("Winmm.dll")]  
    發(fā)表于 02-20 10:22

    WinForm中如何播放聲音與Flash動(dòng)畫(huà)

    WinForm中如何播放聲音與Flash動(dòng)畫(huà)前面幾天有一位MM在論壇中問(wèn)我,怎么在VC#設(shè)計(jì)中如何播放聲音和Flash動(dòng)畫(huà)。當(dāng)時(shí)我正急著找工作,沒(méi)有機(jī)會(huì)去想想怎么做,只能遺憾對(duì)那個(gè)MM說(shuō),我?guī)筒涣四?/div>
    發(fā)表于 03-04 17:00

    VC播放聲音函數(shù)PlaySound和sndPlaySound的用法

    VC播放聲音函數(shù)PlaySound和sndPlaySound的用法一、PlaySound函數(shù)的聲明為:BOOL PlaySound(LPCSTR pszSound,HMODULE hmod
    發(fā)表于 10-02 01:51

    播放聲音

    自己編程的播放聲音文件的程序,分享相互學(xué)習(xí)。
    發(fā)表于 01-11 18:55

    LabVIEW播放聲音文件選擇設(shè)備ID無(wú)效?

    電腦有兩個(gè)聲卡,使用LabVIEW播放聲音文件的VI,無(wú)論設(shè)備ID設(shè)置0或1,都通過(guò)默認(rèn)的聲卡輸出聲音。即無(wú)法實(shí)現(xiàn)選擇輸出設(shè)備。而如果讀取波形文件控制播放時(shí),則可以按照設(shè)備ID的選擇,通過(guò)不同的聲卡播出。但是
    發(fā)表于 09-13 15:01

    播放聲音直接從PSoC和發(fā)送同時(shí)有聲音失真

    我的英語(yǔ)道歉,不講起我用“谷歌翻譯”。試圖做一個(gè)樂(lè)器,必須傳送到計(jì)算機(jī),這種風(fēng)格的“吉他英雄”的游戲,我的問(wèn)題是,當(dāng)我嘗試播放聲音直接從PSoC和發(fā)送同時(shí)有聲音失真,思考這quice使用“操作系統(tǒng)
    發(fā)表于 01-17 12:53

    請(qǐng)問(wèn)用edma方式播放聲音如何讓循環(huán)播放聲音停下來(lái)?

    想問(wèn)兩個(gè)問(wèn)題:1、AUDIO LINE OUT 例程中,用edma方式播放聲音,如何讓循環(huán)播放聲音停下來(lái)。做交互時(shí)很困擾,聲音一旦播放就停
    發(fā)表于 09-06 08:29

    求助大神自己設(shè)計(jì)咪頭聲音很大,錄音播放聲音很小

    自己在做一個(gè)基于ISD4004語(yǔ)音芯片的一個(gè)語(yǔ)音錄放裝置,不知道是哪里除了問(wèn)題,在放音是總是很大雜音而錄音的播放聲音很小,請(qǐng)教一下各位大神們我的電路有什么問(wèn)題嗎?
    發(fā)表于 07-16 08:30

    如何強(qiáng)制使用默認(rèn)聲卡播放聲音?

    如何強(qiáng)制使用默認(rèn)聲卡播放聲音?
    發(fā)表于 03-03 06:49

    java小應(yīng)用,java小應(yīng)用程序下載

    Java小應(yīng)用: 2.1 所有小應(yīng)用程序的根源 2.2 小試身手 2.3 圖形操作 2.4 URL類(lèi) 2.5 載入現(xiàn)有圖像文件 2.6 動(dòng)畫(huà)效果 2.7  播放聲音 2.8 小 
    發(fā)表于 04-28 14:20 ?0次下載

    JAVA教程之聲音播放程序

    JAVA教程之聲音播放程序,很好的JAVA的資料,快來(lái)學(xué)習(xí)吧
    發(fā)表于 04-11 17:14 ?5次下載