JavaFX 在 MediaPlayer 播放的长音频上使用率高 CPU

JavaFX high CPU usage on long audio played by a MediaPlayer

我是 JavaFX 8 初学者,我已经做了一些正确的应用程序,但现在我想尽可能多地优化它。

我的应用程序的简短描述: 它需要很长的音频带(至少半小时),让您随时切换它们。 切换时,切换后的音频在前一个音频的最后播放时间播放。我的音频是本地存储的.m4a文件。

我的问题: 所有这些都非常有效,但它需要大量 CPU 的使用(我猜),我有一个 i7 4720HQ,当我进行一些音频切换时(或者甚至当我只启动一个时),它会增长到 20 然后30% 甚至 40% 的使用率。我觉得这太多了,而且我只用 3 个音频测试了这个,我的应用程序最多可以有 6 个。 然而,当我让一个音频播放超过 30 秒时,它会下降到标准用法。

我所做的: Oracle MediaPlayer的基本用法的简单使用。切换系统的工作原理是:它会暂停所有未在单击按钮时播放的音频,并播放与该按钮相关的已单击音频。

这是我的代码: AudioButtons class,link 一个按钮的音频,用于点击播放

package application;

import java.util.ArrayList;
import java.util.List;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar;
import javafx.util.Duration;

public class AudioButtons {

        List<AudioPlayer> audioPlayer = new ArrayList<AudioPlayer>();
        Duration lastPlayedTime = null;
        Duration launchDelay;
        ButtonBar buttonBar;

        public void computeDelay(long delay) {
            launchDelay = new Duration(delay);
        }

        public AudioButtons(ButtonBar buttonBar) {
            this.buttonBar = buttonBar;
        }

        public void setAudio() {
            for(Node buttonNode : buttonBar.getButtons()) {

                Button button = (Button) buttonNode;
                String buttonName = button.getText();

                AudioPlayer audioPlayerAdding = new AudioPlayer("C:/JFXTest/"+buttonName+".m4a");
                audioPlayerAdding.setMediaId(Integer.parseInt(buttonName));
                audioPlayer.add(audioPlayerAdding);

                button.setOnMousePressed((event) -> {
                    int buttonIndex = Integer.parseInt(buttonName) - 1;
                    for(AudioPlayer oneAudioPlayer : audioPlayer) {
                        System.out.println("Time of media id "+oneAudioPlayer.getMediaId()+" "+oneAudioPlayer.audioPlayer.getCurrentTime());
                        if(oneAudioPlayer.isLaunched()) {
                            lastPlayedTime = oneAudioPlayer.audioPlayer.getCurrentTime();

                            oneAudioPlayer.pauseAudio();
                        }
                    } 

                    if(audioPlayer.get(buttonIndex).isPaused()) {
                        audioPlayer.get(buttonIndex).audioPlayer.seek(lastPlayedTime);
                        audioPlayer.get(buttonIndex).resumeAudio();
                    } else {
                        if(lastPlayedTime==null)
                            lastPlayedTime = launchDelay;
                        audioPlayer.get(buttonIndex).launch(lastPlayedTime);
                    }
                });
            }

        }
}

AudioPlayer class,控制所有音频输入

package application;

import java.io.File;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;

public class AudioPlayer {

    MediaView mediaView;
    MediaPlayer audioPlayer;
    int mediaId;
    Duration currentTime = null;
    boolean launched = false;
    boolean paused = false;

    public AudioPlayer(String playerSoundPath) {
        String path = new File(playerSoundPath).toURI().toString();
        Media audioMedia = new Media(path);
        audioPlayer = new MediaPlayer(audioMedia);
        System.out.println("Playing of "+path);
    }

    public void setMediaId(int id) {
        mediaId = id;
    }

    public int getMediaId() {
        return mediaId;
    }

    public void launch() {
        audioPlayer.setAutoPlay(true);
        mediaView = new MediaView(audioPlayer);
        launched = true;
        currentTime = mediaView.getMediaPlayer().getCurrentTime();
    }

    public void launch(Duration startTime) {
        audioPlayer.setStartTime(startTime);
        audioPlayer.setAutoPlay(true);
        mediaView = new MediaView(audioPlayer);
        launched = true;
        currentTime = mediaView.getMediaPlayer().getCurrentTime();
    }

    public MediaView getViewStack() {
        return mediaView;
    }

    public Duration getCurrentTime() {
        return currentTime;
    }

    public boolean isLaunched() {
        return launched;
    }

    public boolean isPaused() {
        return paused;
    }

    public void pauseAudio() {
        mediaView.getMediaPlayer().pause();
        paused = true;
        launched = false;
        currentTime = mediaView.getMediaPlayer().getCurrentTime();
    }

    public void resumeAudio() {
        mediaView.getMediaPlayer().play();
        paused = false;
        launched = true;
        currentTime = mediaView.getMediaPlayer().getCurrentTime();
    }

    public void mute() {
        mediaView.getMediaPlayer().setMute(true);
    }

    public boolean isMute() {
        return mediaView.getMediaPlayer().isMute();
    }

    public void unMute() {
        mediaView.getMediaPlayer().setMute(false);
    }

    @Override
    public String toString() {
        return "ViewStack [mediaId=" + mediaId + ", launched=" + launched + ", paused=" + paused + "]";
    }

}

已经尝试了以下两个帮助,但没有得到更好的结果

CPU Usage JavaFX

JavaFX 8 QuantumRenderer high CPU usage

可能是将 .pause 和 .play 与多个 mediaPlayer 一起使用导致了这种情况,或者我可能错误地使用了他们的概念。

感谢未来的帮助!

我认为您可以使用单独的线程来播放音频。这样你就可以在打开一个新的线程之前杀死一个音频线程,让你的程序的其余部分只使用它需要的东西