JAVA音频研究5:音频播放器(javax.sound学习指南,javax.sound学习实战)

本代码将调用javax.sound库,讲解如何播放音频
得到能够使用的简易音频的播放器
本文可作为javax.sound学习指南,javax.sound学习实战等进行参考
相关内容请看下方代码与注释

注:代码中 SoundFileFormat、SoundInputStream、SoundSourceDataLine、MixerInformation 几个类都是前面几篇文章中讲解的内容,将其中代码依次创立为对应的类,并调用即可
SoundFileFormat中代码对应文章:JAVA音频研究1
SoundInputStream中代码对应文章:JAVA音频研究2
SoundSourceDataLine中代码对应文章:JAVA音频研究3
MixerInformation中代码对应文章:JAVA音频研究4
如:在这里插入图片描述
后续使用请看下片文章:JAVA音频研究6

import java.io.File;
//import java.time.Instant;

public class SoundPlayer {
    private static String soundFilePath = null;//保存为字符串类型的绝对地址,例:"C:\\Users\\17512\\Desktop\\bgm.wav";
    private static File soundFile = null;//保存音频文件
    //========================================================

    private volatile boolean running = false;  //记录音频是否播放
    private static boolean isLoop = false; //记录是否循环播放
    private static Thread mainThread = null;   //播放音频的任务主线程(音频数据读取输出)
    private static Thread secondThread = null;   //播放音频的任务次线程(控制主线程暂停、继续)
    private static byte tempBuffer[] = null;//缓冲区
    private static int count;//保存得到的采样数
    //private static Instant startTime = null; 待后续开发
    //private static Instant endTime = null;待后续开发

    //清空所有内容,释放内存
    protected static void clearAll(){
        soundFile = null;
        mainThread = null;
        secondThread = null;
        tempBuffer = null;
        //startTime = null;待后续开发
        //endTime = null;待后续开发
    }
    //设置音频文件绝对路径
    public void setSoundFilePath(String absolutePath){
        soundFilePath = absolutePath;
    }

    private void playMusic(){
        try{
            synchronized(this){
                running = true;
            }
            //通过数据行读取音频数据流,发送到混音器;
            //数据流传输过程:AudioInputStream -> SourceDataLine;
            if(soundFilePath == null){
                System.out.println("未设置声音文件绝对路径");
                return;
            }

            soundFile = new File(soundFilePath);

            //MixerInformation.getMixerInformation();
            //MixerInformation.showMixerInformation();
            SoundFileFormat.getSoundFileFormat(soundFile);
            //SoundFileFormat.showSoundFileFormat();

            SoundInputStream.getSoundInputStream(soundFile);
            //SoundInputStream.showSoundInputStream();

            SoundSourceDataLine.loadSourceDataLine();

            System.out.println("播放开始");
            tempBuffer = new byte[1024];
            //音频输入流读取指定最大大小(tempBuff.length)数据并传输到源数据线,off为传输数据在字节数组(tempBuffer)开始保存数据的位置,最终读取大小保存进count
            while((count = SoundInputStream.soundInputStream.read(tempBuffer,0,tempBuffer.length)) != -1){
                //System.out.println("音频输入流读取了" + count + "个字节");
                synchronized(this){
                    while(!running)
                        wait();
                }
                //源数据线进行一次数据输出,将从字节数组中位置off开始将读取到的数据输出到缓冲区(输出大小为count)(混音器从混音器读取数据播放)
                SoundSourceDataLine.sourceDataLine.write(tempBuffer,0,count);
            }

            stopMusic();
        }catch(Exception ex){
            ex.printStackTrace();
        }

    }

    private void playMusic(boolean isLoop)throws Exception {
        try{
            if(isLoop){
                while(isLoop){
                    playMusic();
                }
            }else{
                playMusic();
            }

        }catch(Exception ex){
            ex.printStackTrace();
        }

    }


    //暂停播放音频
    private void pauseMusic(){ synchronized(this){ running = false; notifyAll(); } }
    //继续播放音乐
    private void continueMusic(){ synchronized(this){ running = true; notifyAll(); } }
    //停止播放音频
    private void stopMusic() throws Exception {
        synchronized(this){
        running = false;
        isLoop = false;
        System.out.println("播放结束");
        //清空数据行并关闭
        SoundSourceDataLine.sourceDataLine.drain();
        SoundSourceDataLine.sourceDataLine.close();
        SoundInputStream.soundInputStream.close();
        SoundFileFormat.clearAll();
        SoundSourceDataLine.clearAll();
        SoundInputStream.clearAll();
        clearAll();
        }
    }

    //外部调用控制方法:生成音频主线程;
    public void start(boolean loop)throws Exception{
        if(SoundInputStream.soundInputStream != null || SoundSourceDataLine.sourceDataLine != null){
            System.out.println("切换歌曲");
            stopMusic();
        }
        isLoop = loop;
        mainThread = new Thread(new Runnable(){
            public void run(){ try { playMusic(isLoop); } catch (Exception e) { e.printStackTrace(); } }
        });
        mainThread.start();
    }

    //外部调用控制方法:暂停音频线程
    public void pause(){
        secondThread = new Thread(new Runnable(){
            public void run(){
                System.out.println("调用暂停");
                pauseMusic();
            }
        });
        secondThread.start();
    }
    //外部调用控制方法:继续音频线程
    public void continues(){
        secondThread = new Thread(new Runnable(){
            public void run(){
                System.out.println("调用继续");
                continueMusic();
            } });
        secondThread.start();
    }
    //外部调用控制方法:结束音频线程
    public void stop(){
        secondThread = new Thread(new Runnable(){
            public void run(){
                System.out.println("调用停止");
                try {stopMusic();}
                catch (Exception e) {e.printStackTrace();}
            } });
        secondThread.start();
    }
}
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倚肆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值