Jak se dostat píseň trvání práce v JavaFx Hudební Přehrávač

0

Otázka

Jsem vytvořil hudební přehrávač pomocí JavaFX. Nicméně, já nejsem schopen pochopit, jak můžu vědět, trvání skladby, v současné době jsem hrál.

Edit: přidal jsem následující řádky, aby můj kód a teď píseň trvání je viditelné. Nicméně, když jsem hrát další píseň, píseň trvání není viditelné. Zde jsou linky, které jsem přidal do kódu:

mediaPlayer.currentTimeProperty().addListener(new TimeListener());  

TimeListener = new ChangeListener<Duration>() 
        {
              @Override public void changed(ObservableValue<? extends Duration> o, Duration oldVal, Duration newVal) 
              {
             //now newVal is of Duration class
              }
            };

    }
    
    public class TimeListener implements ChangeListener {
        public void changed(ObservableValue o, Object oldVal, Object newVal) {

        //Update time display with MediaPlayer's current time:
        playTime.setText(newVal.toString());
        }
    }

Tady je můj kód k vytvoření hudební přehrávač:

    public class MusicController implements Initializable 
{
    @FXML
    private ImageView trackLogo;
    @FXML
    private Button next, previous, pause, play, reset;
    @FXML
    private Slider VolumeSlider;    
    @FXML
    private AnchorPane Panel;   
    @FXML
    private Label playTime, appTitle, songTitle;    
    @FXML
    private ProgressBar songProgressBar;
    @FXML
    private Media media;
    private MediaPlayer mediaPlayer;
    private File directory;
    private File [] files;
    private ArrayList<File> songs;  
    private int songNumber; 
    private Timer timer;
    private TimerTask task;
    private boolean running;
    private ChangeListener<Duration> TimeListener;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) 
    {
        songs = new ArrayList<File>();      
        directory = new File("music");      
        files = directory.listFiles();      
        if(files!=null) 
        {
            for(File file : files)
            {
                songs.add(file);
                System.out.println(file);
            }
        }       
        media = new Media(songs.get(songNumber).toURI().toString());
        mediaPlayer = new MediaPlayer(media);
        mediaPlayer.currentTimeProperty().addListener(new TimeListener());      
        songTitle.setText(songs.get(songNumber).getName());
        VolumeSlider.valueProperty().addListener(new ChangeListener<Number>()
                {
                    public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) 
                    {       
                        mediaPlayer.setVolume(VolumeSlider.getValue() * 0.01);  
                    }
                });
        
        TimeListener = new ChangeListener<Duration>() 
        {
              @Override public void changed(ObservableValue<? extends Duration> o, Duration oldVal, Duration newVal) 
              {
             //now newVal is of Duration class
              }
            };

    }
    
    public class TimeListener implements ChangeListener {
        public void changed(ObservableValue o, Object oldVal, Object newVal) {

        //Update time display with MediaPlayer's current time:
        playTime.setText(newVal.toString());
        }
    }
    
    public void playMedia() 
    {   
            beginTimer();
            mediaPlayer.setVolume(VolumeSlider.getValue() * 0.01);
            mediaPlayer.play();
    }
    
    public void pauseMedia() 
    {   
            cancelTimer();
            mediaPlayer.pause();
    }

    public void resetMedia() 
    {   
            songProgressBar.setProgress(0);
            mediaPlayer.seek(Duration.seconds(0));
    }
    
    public void previousMedia() 
    {   
        if (songNumber > 0)
        {
            songNumber--;
            mediaPlayer.stop();
            
            if(running)
            {
                cancelTimer();
            }
            
            media = new Media(songs.get(songNumber).toURI().toString());
            mediaPlayer = new MediaPlayer(media);
            songTitle.setText(songs.get(songNumber).getName());
            playMedia();

        }
        else
        {
            songNumber = songs.size() - 1;
            mediaPlayer.stop();
            
            if(running)
            {
                cancelTimer();
            }
            
            
            media = new Media(songs.get(songNumber).toURI().toString());
            mediaPlayer = new MediaPlayer(media);
            songTitle.setText(songs.get(songNumber).getName());
            playMedia();
        }
    }
    
    public void nextMedia() 
    {   
        if (songNumber < songs.size() - 1)
        {
            songNumber++;
            mediaPlayer.stop();
            
            if(running)
            {
                cancelTimer();
            }
    
            media = new Media(songs.get(songNumber).toURI().toString());
            mediaPlayer = new MediaPlayer(media);
            songTitle.setText(songs.get(songNumber).getName());
            playMedia();

        }
        else
        {
            songNumber = 0;
            mediaPlayer.stop();
            
            if(running)
            {
                cancelTimer();
            }
            media = new Media(songs.get(songNumber).toURI().toString());
            mediaPlayer = new MediaPlayer(media);
            songTitle.setText(songs.get(songNumber).getName());
            playMedia();
        }
    }
    
    
    public void beginTimer() 
    {   
        timer = new Timer();
        task = new TimerTask()
                {   
                    public void run() 
                    {
                        running = true;
                        double current = mediaPlayer.getCurrentTime().toSeconds();
                        double end = media.getDuration().toSeconds();
                        System.out.println(current/end);
                        songProgressBar.setProgress(current/end);
                        
                        if (current/end ==1)
                        {
                            cancelTimer();
                        }
                        
                    }
                };
                timer.scheduleAtFixedRate(task, 0, 1000);
    }
    
    public void cancelTimer() 
    {   
            running = false;
            timer.cancel();
    }
    
}

Snažil jsem se číst Oracle dokument (https://docs.oracle.com/javase/8/javafx/media-tutorial/playercontrol.htm) a toto video na youtube (https://www.youtube.com/watch?v=-D2OIekCKes) chcete-li vytvořit hudební přehrávač.

A byl bych vděčný za jakoukoliv pomoc. Díky předem!

java javafx scenebuilder
2021-11-23 06:16:25
1

Nejlepší odpověď

1

Neměli byste používat Timernebo závity obecně platí, že pro něco takového. Vlastnosti MediaPlayer jsou pozorovatelné, a tak byste měli buď přidat posluchače, aby jim, nebo vázat uživatelské ROZHRANÍ vlastnosti pro ně. Zde je příklad vázání ProgressBarpokrok majetku přehrávač:

progressBar.progressProperty().bind(
    Bindings.createDoubleBinding(() -> {
      Duration current = mediaPlayer.getCurrentTime();
      Duration total = mediaPlayer.getCycleDuration();
      return current.toMilli() / total.toMillis();
    },
    mediaPlayer.currentTimeProperty(),
    mediaPlayer.cycleDurationProperty())
);

Výše uvedené je použití Vazby#createDoubleBinding(Callable,Pozorovatelné...) a lambda výrazy.

Budete muset udělat výše uvedené, pokaždé, když nový MediaPlayer je vytvořen, ale jinak, že zvládne udržet progress bar up-to-date. A vy můžete udělat něco podobného pro popisky zobrazení, například aktuální čas a celkový čas v lidském čitelném formátu.

Také, místo toho, přidání posluchače, aby váš volumeSlider můžete to udělat:

mediaPlayer.volumeProperty().bind(volumeSlider.valueProperty());

Vidět Pomocí JavaFX Vlastnosti a Závazné pro více informací.


Jako stranou, nejen, že by jsi neměl používat Timer tady, ale jak to používáte, je nesprávné. V JavaFX, tam je speciální vlákno s názvem JavaFX Aplikace Závitu. Jen to, že závit by měl komunikovat s UI, přímo nebo nepřímo. Použití jakékoliv jiné vlákno k interakci s UI je poškozený kód, a může vést k nedefinované chování—JavaFX není závit bezpečné.

Můžete naplánovat akce na FX nit pomocí Platform#runLater(Runnable).

2021-11-23 08:20:29

Děkuji moc za vaši pomoc. Budu se snažit realizovat vaše rady, ve svém programu.
Devanshu Mahapatra

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................