我正在试着播放一种声音,它完美地循环在你看不出它什么时候开始的地方.我知道我可以用setCycleCount方法让AudioClip或MediaPlayer无限循环,这很管用.然而,音频并不是完全连续的;有非常短的一秒钟没有播放,所以当它重新开始时,它是非常明显的.我知道这不是音频文件本身的问题,因为当我在音频播放器上循环播放它时,它会完美地循环.我试过AudioClip和MediaPlayer,我试着用setOnEndOfMedia让它循环,但它们都有同样的问题.下面是一个例子:

import java.io.File;
import java.net.*;
import java.util.Scanner;
import javafx.scene.media.*;

public class AudioTest {
    public static void main(String[] args) {
        URI audioURI = new File("filePath").toURI();
        
        AudioClip audio = new AudioClip(audioURI.toString());
        audio.setCycleCount(AudioClip.INDEFINITE);
        audio.play();
        
        /*
        setOnEndOfMedia version
        
        MediaPlayer audio = new MediaPlayer(new Media(audioURI.toString()));
        audio.setOnEndOfMedia(new Runnable() {
            @Override
            public void run() {
                audio.seek(Duration.ZERO);
                audio.play();
            }
        });
        */
        
        new Scanner(System.in).next(); // to prevent the program from closing immediately
    }
}

以及指向示例音频文件的链接: https://drive.google.com/file/d/1NzlqY-K7m__qXE6iKJw3H26KZ8Ql4U2n/view?usp=sharing

我的操作系统是Windows 11,使用的是Java 17和Java FX 17.我的CPU是第11代英特尔(R)酷睿(TM)i5-1135G7. 我有什么办法可以解决这个问题吗?

推荐答案

下面是一个包含javax.sound的示例,它循环一个wav文件(您在问题中链接的名为tone.wav的正弦波文件).

我将声音循环五次,但您可以想循环多少次就循环多少次.

要从JavaFX应用程序中使用它,可以在JavaFX任务中使用javax.sound包装声音播放,并为其提供接口(注意并发应用程序的线程编码).

import javax.sound.sampled.*;
import java.io.IOException;
import java.util.Objects;
import java.util.Scanner;

public class SoundTest {
    public static void main(String[] args) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        AudioInputStream stream = AudioSystem.getAudioInputStream(
                Objects.requireNonNull(
                        SoundTest.class.getResource(
                                "tone.wav"
                        )
                )
        );
        AudioFormat format = stream.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        Clip clip = (Clip) AudioSystem.getLine(info);
        clip.open(stream);
        clip.loop(5);
//        clip.start();

        new Scanner(System.in).next(); // to prevent the program from closing immediately
    }
}

对我来说,我得到了一个连续的,无缝的音频循环与javax.sound回放.

但是使用Java MediaPlayer或AudioClip,使用您的样例代码,我可以在循环之间中断,正如您在问题中提到的.我不知道这是为什么,是否受限于您正在播放的声音的某些属性,或者某些特定或所有平台上当前对JavaFX音频播放的限制.你可能想问openjfx-dev mailing list人更多的信息.

使用的测试系统是OS X 14.1.2 Mac上的JavaFX 21.0.1和OpenJDK 21.

A note on 100 usage.

javax.sound是JavaFX媒体的替代声音播放接口.javax.sound包是java.desktop模块的一部分,而java.desktop模块(从JavaFX 21开始)是任何JavaFX安装所必需的(即使javax.sound系统与JavaFX无关).

javax.sound系统可能不符合您的要求,因为它可能不会播放您想要的声音格式,但对于某些声音格式,它可能是一个可行的替代方案.

如果需要,Oracle提供tutorial for the javax.soundAPI.

Java相关问答推荐

将具有多个未知字段的SON映射到Java POJO

在Java中测试DAO方法:假实现与内存数据库

在AnyLogic中增加变量计数

@ IdClass with @ Inheritance(策略= InheritanceType. SINGLE_TABLE)

无法处理批处理侦听器中的反序列化异常

关于泛型的覆盖规则

将关键字与正文中的_Allowed匹配,但带有__Signing可选后缀

Chunk(Int)已弃用并标记为要删除

Java流传输一个列表并创建单个对象

在Java中如何从Executors.newFixedThreadPool(MAX_THREAD_COUNT())迁移到虚拟线程

Java-动态绑定-问题-了解

将Spring Boot 3.2.0升级到3.2.1后查询执行错误

Java连接池无法正常工作

为什么有两种实现来检索数组类的组件类型?

EXCEL中的公式单元格显示#NAME?

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

如何设计包含已知和未知键值对映射的Java类?

如何使JOOQ渐变脚本不重新创建表未更改的类?

为什么我得到默认方法的值而不是被覆盖的方法的值?

Hibernate 命名策略导致 Java Spring Boot 应用程序中出现未知列错误