【问题标题】:How do I play an audio in a loop in Java?如何在 Java 中循环播放音频?
【发布时间】:2022-01-18 15:13:59
【问题描述】:

每次完成后,我只想循环播放一段音频。我不得不说这只是背景音乐,它在一个线程中运行。代码如下:

package Generator;

import javazoom.jl.player.Player;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javazoom.jl.decoder.JavaLayerException;

public class Reproductor {
       
    Player reproductor;
        
    public void reproducir() throws FileNotFoundException, JavaLayerException {
        reproductor = new Player(new FileInputStream("C:\\Users\\Leonardo\\Desktop\\config generator\\Recursos\\Triage at dawn.mp3"));    
        new Thread  () {
           @Override
           public void run() {
               try {   
                    reproductor.play();        //This just play the audio for the first time.
               } catch (JavaLayerException ex) {
                   
               }
           } 
        }.start();
    }    
        
    public void parar() {
        if(reproductor != null) {
            reproductor.close();
        }
    }

【问题讨论】:

  • 您是否尝试过使用while (true) 循环来包围对 play() 的调用?
  • 我试过了,但是如果我放 while(mainwindow.isAtctive()) 它一次只会播放很多次音频。

标签: java loops class oop audio


【解决方案1】:

我找到了源代码:https://github.com/umjammer/jlayer/tree/master/src/main/java/javazoom/jl/player/advanced

您应该使用AdvancedPlayer 而不是Player。它允许您注册一个PlaybackListener,当音乐停止时,它会收到一个PlaybackEvent

这段代码应该可以解决问题:

package Generator;

import javazoom.jl.player.Player;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javazoom.jl.decoder.JavaLayerException;

public class Reproductor {
       
    Player reproductor;
        
    public void reproducir() throws FileNotFoundException, JavaLayerException {
        reproductor = new Player(new FileInputStream("C:\\Users\\Leonardo\\Desktop\\config generator\\Recursos\\Triage at dawn.mp3"));    

       PlaybackListener myListener = new PlaybackListener() {
        public void playbackStarted(PlaybackEvent evt){
            // Do nothing
        }
        public void playbackFinished(PlaybackEvent evt){
            // Restart
            reproductor.play(); 
        }
        };
        reproductor.setPlayBackListener( myListener  );
        new Thread  () {
           @Override
           public void run() {
               try {
                    reproductor.play();        //This just play the audio for the first time.
               } catch (JavaLayerException ex) {
                   
               }
           } 
        }.start();
    }    
        
    public void parar() {
        if(reproductor != null) {
            reproductor.close();
        }
    }

【讨论】:

  • 谢谢,您的回答非常有用,但是我不得不对代码进行一些更改。我不得不在playbackFinished 方法中重新定义reproductor 变量。我遇到了一个异常,我认为这是因为一旦声音完成了再现,一个名为 position 的变量被设置为null,所以调用reproductor 是在调用一个新的内容。
【解决方案2】:

我有一个解决方案给你。 创建一个新的 java 文件并将其命名为任何名称。然后执行此代码:


class Main{
 public static void main(String[] args)
 {
    int length = 10000000000, numberOfTimes = 5;
    Reproducer reproducer = new Reproducer();
    for(int j =0;j < numberOfTimes;i++){
    reproducer.reproducir();
    for(int i =0;i < length;i++){}
    }
 }
}

【讨论】:

  • 我刚做了,但这会使程序一次播放声音多次。
【解决方案3】:

我看到您正在使用 Javazoom。

查看我在 github 上找到的该库的文档,有一个类应该可以更好地工作:AdvancedPlayerPlaybackListener 结合使用。

如果这与 Java 中的大多数侦听器类似,则可以将其设置为感知音频何时结束,并在该事件上调用另一个播放。不过,我已经很久没有使用这个库了,我所做的只是用它来将 ogg/vorbis 文件转换为 PCM,所以我无法帮助您提供所需的特定代码。

如果可以使用 wav 文件,使用 Java 的 Clip 类和 loop() 方法会容易得多。 mp3 文件到 wav 的转换可以使用诸如 Audacity 之类的工具来完成,前提是您的应用程序可以预先准备好资产。

如果您确切知道要播放的代码,另一种可能性是确定某些标头信息中可能存在的长度,或者再次在 Audacity 中打开它,然后存储项目中的持续时间信息。然后,对于播放代码,在循环前添加一个Thread.sleep()。这可能不太可靠。

【讨论】:

    【解决方案4】:

    当我试图解决一些问题时,我发现了一种更简单的方法。检查此链接以获取solution。我的代码是这样结束的:

    
    package Generator;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import javazoom.jl.decoder.JavaLayerException;
    import javazoom.jl.player.Player;
    
    public class Reproductor extends Thread{
           
        private String ruta;
        private boolean bucle;
        private Player reproductor;
            
        public Reproductor(String ruta, boolean bucle) {
            this.ruta = ruta;
            this.bucle = bucle;
        }    
            
        public void run() {
            try {
                do{
                    FileInputStream buff = new FileInputStream(ruta);
                        reproductor = new Player(buff);
                        reproductor.play();
                    try {
                        reproductor.play();
                    } catch (JavaLayerException ex) {}
                }while(bucle);
            }   catch(FileNotFoundException | JavaLayerException ioe) {}  
        }
                
        public void parar() {
            bucle = false;
            reproductor.close();
            this.interrupt();
        }  
        
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多