简体   繁体   中英

JavaFX high CPU usage on long audio played by a MediaPlayer

I'm a JavaFX 8 beginner and I already did some little correct app, but now I wanna optimize it as much.

A short description of my app : It takes long audio band (minimum half an hour) and let you switch them whenever you want. On switching, the switched audio is played at the last played time of the precedent one. My audios are .m4a files locally stored.

My problem : All of this is working greatly, but it takes HUGE CPU usage (in my guess), I got an i7 4720HQ and when I do some audio switching (or even when I only launch one), it grows to 20 then 30 and even 40% of usage. I feel this is too much, plus I tested this with only 3 audio and there can be 6 at max on my app. However it drops to standard usage when I let one audio play more than 30 seconds.

What I have done : A simple use of Oracle basic usage of MediaPlayer. The switching system works as it : It pause all audio that are not playing on click of a button, and play the clicked one related to that button.

Here my code : AudioButtons class, that link an audio to a button for playing on click

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, that controls all the audio inputs

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 + "]";
    }

}

Already tried the following two helps which didn't give better results

CPU Usage JavaFX

JavaFX 8 QuantumRenderer high CPU usage

Maybe it's the use of .pause & .play with multiples mediaPlayer that cause this, or I may badly use their concept.

Thanx for future helps !

What I would think would be for you to use a separate thread for audio playback. That way you can kill an audio thread before you open a new one, allowing the rest of your program to use only what it needs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM