【Java】打开窗体后自动播放背景音乐代码实现

简介: 【Java】打开窗体后自动播放背景音乐代码实现

简易音乐播放器

窗体类

音乐类

实现效果


新建一个窗体后程序自动播放音乐,可以选择自己喜欢的歌曲播放,可用于平时的窗体练习或者游戏界面的背景音乐,拿走不谢。

首先,该播放器需要两个类,一个用来构建窗体,一个用来设置音乐。
话不多说,直接上代码


窗体类


package 音乐播放窗体;
import java.awt.Color;
import java.awt.Container;
import java.awt.Frame;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import 音乐播放窗体.MusicFrame;
import 音乐播放窗体.Sound;
public class MusicFrame extends JFrame{
  public static void main(String[] args) throws InterruptedException {
    //1.创建音乐窗体
    JFrame f = new JFrame("自制音乐播放器");
    //2.设置容器
    Container con=f.getContentPane();
    //3.设置窗口的背景色
        con.setBackground(Color.pink) ; 
    //4.设置大小
    f.setSize(400, 400);
    //5.设置位置居中显示
    f.setLocationRelativeTo(null);
    //6.设置可见
    f.setVisible(true);
    //7.设置关闭窗体时关闭窗体
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //8.创建音乐播放器
    Sound player = new Sound("E:/kkkkk/博客斐日常练习/src/稻香.wav");   
    //循环播放
        player.start(true);
        TimeUnit.SECONDS.sleep(4);
        //继续开始播放音频
        player.continues();
        /**
         * 第二,三步可以省略,此处为了美观,设置窗体颜色。
         */
  }
}

音乐类


package 音乐播放窗体;
/**
* Description: 简易音频播放器(只支持AU,RA,WAV)
*          在不使用JMF的情况下快速实现音频播放
*/
import javax.sound.sampled.*;
import java.io.*;
import java.util.concurrent.TimeUnit;
public class Sound {
  private String musicPath; //音频文件
  private volatile boolean run = true;  //记录音频是否播放
  private Thread mainThread;   //播放音频的任务线程
  private AudioInputStream audioStream;
  private AudioFormat audioFormat;
  private SourceDataLine sourceDataLine;
  public Sound(String musicPath) {
    this.musicPath = musicPath;
    prefetch();
  }
  //数据准备
  private void prefetch(){
    try{
    //获取音频输入流
      audioStream = AudioSystem.getAudioInputStream(new File(musicPath));
    //获取音频的编码对象
    audioFormat = audioStream.getFormat();
    //包装音频信息
    DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,
        audioFormat,AudioSystem.NOT_SPECIFIED);
    //使用包装音频信息后的Info类创建源数据行,充当混频器的源
    sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);
    sourceDataLine.open(audioFormat);
    sourceDataLine.start();
    }catch(UnsupportedAudioFileException ex){
      ex.printStackTrace();
    }catch(LineUnavailableException ex){
      ex.printStackTrace();
    }catch(IOException ex){
      ex.printStackTrace();
    }
  }
  //析构函数:关闭音频读取流和数据行
  protected void finalize() throws Throwable{
    super.finalize();
    sourceDataLine.drain();
    sourceDataLine.close();
    audioStream.close();
  }
  //播放音频:通过loop参数设置是否循环播放
  private void playMusic(boolean loop)throws InterruptedException {
    try{
        if(loop){
          while(true){
            playMusic();
          }
        }else{
          playMusic();
          //清空数据行并关闭
          sourceDataLine.drain();
          sourceDataLine.close();
          audioStream.close();
        }
    }catch(IOException ex){
      ex.printStackTrace();
    }
  }
  private void playMusic(){
    try{
      synchronized(this){
        run = true;
      }
      //通过数据行读取音频数据流,发送到混音器;
      //数据流传输过程:AudioInputStream -> SourceDataLine;
      audioStream = AudioSystem.getAudioInputStream(new File(musicPath));
      int count;
      byte tempBuff[] = new byte[1024];
        while((count = audioStream.read(tempBuff,0,tempBuff.length)) != -1){
          synchronized(this){
          while(!run)
            wait();
          }
          sourceDataLine.write(tempBuff,0,count);
      }
    }catch(UnsupportedAudioFileException ex){
      ex.printStackTrace();
    }catch(IOException ex){
      ex.printStackTrace();
    }catch(InterruptedException ex){
      ex.printStackTrace();
    }
  }
  //暂停播放音频
  private void stopMusic(){
    synchronized(this){
      run = false;
      notifyAll();
    }
  }
  //继续播放音乐
  private void continueMusic(){
    synchronized(this){
       run = true;
       notifyAll();
    }
  }
  //外部调用控制方法:生成音频主线程;
  public void start(boolean loop){
    mainThread = new Thread(new Runnable(){
      public void run(){
        try {
          playMusic(loop);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });
    mainThread.start();
  }
  //外部调用控制方法:暂停音频线程
  public void stop(){
    new Thread(new Runnable(){
      public void run(){
        stopMusic();
      }
    }).start();
  }
  //外部调用控制方法:继续音频线程
  public void continues(){
    new Thread(new Runnable(){
      public void run(){
        continueMusic();
      }
    }).start();
  }  
 }

实现效果


目录
相关文章
|
15天前
|
Java 测试技术 应用服务中间件
常见 Java 代码缺陷及规避方式(下)
常见 Java 代码缺陷及规避方式(下)
43 0
|
17天前
|
Java
Java中ReentrantLock释放锁代码解析
Java中ReentrantLock释放锁代码解析
25 8
|
20天前
|
前端开发 小程序 Java
uniapp上传图片 前端以及java后端代码实现
uniapp上传图片 前端以及java后端代码实现
34 0
|
22天前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
35 4
|
22天前
|
设计模式 Java 中间件
23种设计模式,适配器模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】适配器模式(Adapter Pattern)是一种结构型设计模式,它的主要目标是让原本由于接口不匹配而不能一起工作的类可以一起工作。适配器模式主要有两种形式:类适配器和对象适配器。类适配器模式通过继承来实现适配,而对象适配器模式则通过组合来实现
31 4
|
23天前
|
存储 缓存 算法
优化 Java 后台代码的关键要点
【4月更文挑战第5天】本文探讨了优化 Java 后台代码的关键点,包括选用合适的数据结构与算法、减少不必要的对象创建、利用 Java 8 新特性、并发与多线程处理、数据库和缓存优化、代码分析与性能调优、避免阻塞调用、JVM 调优以及精简第三方库。通过这些方法,开发者可以提高系统性能、降低资源消耗,提升用户体验并减少运营成本。
|
24天前
|
Java 开发工具 流计算
flink最新master代码编译出现Java Runtime Environment 问题
在尝试编译Flink源码时遇到Java运行时环境致命错误:EXCEPTION_ACCESS_VIOLATION。问题出现在JVM.dll+0x88212。使用的是Java 11.0.28和Java HotSpot(TM) 64-Bit Server VM。系统为Windows客户端,没有生成核心dump文件。错误日志保存在hs_err_pid39364.log和replay_pid39364.log。要解决这个问题,建议检查JDK版本兼容性,更新JDK或参照错误报告文件提交Bug至http://bugreport.java.com/bugreport/crash.jsp。
|
25天前
|
Java
使用Java代码打印log日志
使用Java代码打印log日志
82 1
|
26天前
|
设计模式 Java 数据库
Java设计模式精讲:让代码更优雅、更可维护
【4月更文挑战第2天】**设计模式是解决软件设计问题的成熟方案,分为创建型、结构型和行为型。Java中的单例模式确保类仅有一个实例,工厂方法模式让子类决定实例化哪个类。适配器模式则协调不兼容接口间的合作。观察者模式实现了一对多依赖,状态变化时自动通知相关对象。学习和适当应用设计模式能提升代码质量和可维护性,但需避免过度使用。设计模式的掌握源于实践与不断学习。**
Java设计模式精讲:让代码更优雅、更可维护
|
26天前
|
SQL 设计模式 安全
Java单例模式几种写法以及代码案例拿来直接使用
Java单例模式几种写法以及代码案例拿来直接使用
32 0