如何正确设置媒体播放器javafx

时间:2016-10-26 10:50:56

标签: java javafx media-player scrollpane pause

我创建的媒体播放器方法是javafx,在启动时调用(下面是媒体播放器)。我的问题是,每当我通过拖动或缩放播放器暂停并且不再重新开始与滚动窗格进行交互时,这会暂停。为什么会出现这种情况,如何解决这个问题(包括完整的应用程序,如果你想尝试的话)。

方法(实时代码)

    private static void MusicPlayer() {
    if(musicList.peek() == null)
    {
        return;
    }
    MediaPlayer mediaPlayer = new MediaPlayer(new Media(new File(musicList.poll()).toURI().toString()));
    mediaPlayer.setOnReady(() -> {
        mediaPlayer.play();
        mediaPlayer.setOnEndOfMedia(() -> {
            mediaPlayer.dispose();
            MusicPlayer();
        });
    });
}

最小

package minimalist;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class Minimal extends Application{

    private static Queue<String> musicList = new LinkedList<String>();

    public static void main(String[] args) throws IOException {
        List<String> result = Files.find(Paths.get(".\\music"), 100,
                (p, a) -> p.toString().toLowerCase().endsWith(".mp3"))
                .map(path -> path.toString())
                .collect(Collectors.toList());
        for(int a = 0; a < result.size(); a++)
        {
            musicList.add(result.get(a));
        }
        MusicPlayer();
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        ScrollPane scrollpane = new ScrollPane();
        Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/7/70/Kusatma_Zonaro.jpg");
        ImageView imageView = new ImageView(image);
        scrollpane.setContent(imageView);
        scrollpane.setPannable(true);
        Scene scene = new Scene(new StackPane(scrollpane));
        primaryStage.setScene(scene);
        primaryStage.setFullScreen(true);
        primaryStage.show();
    }

    private static void MusicPlayer() {
        if(musicList.peek() == null)
        {
            return;
        }
        MediaPlayer mediaPlayer = new MediaPlayer(new Media(new File(musicList.poll()).toURI().toString()));
        mediaPlayer.setOnReady(() -> {
            mediaPlayer.play();
            mediaPlayer.setOnEndOfMedia(() -> {
                mediaPlayer.dispose();
                MusicPlayer();
            });
        });
    }
}

1 个答案:

答案 0 :(得分:2)

这一切似乎都表现得很脆弱。

我不建议使用main方法启动媒体播放器。文档对于MediaPlayer的线程策略有点缺乏,但是由于您要启动常规JavaFX应用程序,遵循通常的规则并且只从JavaFX应用程序线程调用它的方法似乎是明智的。在我的系统上,我无法按照你设置的方式播放任何音乐。

我也有零星的问题让它在改变后开始播放;我猜想也许我退出后会让系统资源出现问题,所以我修改了代码以确保在应用程序结束时处理了播放器。在这两次更改之后,它的行为与预期一致。在任何时候我都没有任何与用户输入相关的问题;我的猜测是,这些是由主线程而不是FX应用程序线程启动媒体播放器引起的,并且可能与系统有关。

这是适合我的代码。我还清理了代码中的一些冗余(迭代Path以将它们转换为String,然后将其转换回File,以便转换为字符串表示形式一个URL似乎有点迂回;你还在该过程中创建一个完全不必要的列表,等等)并重命名事物,使其遵守适当的naming conventations):

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.Queue;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;

public class Minimal extends Application{

    private Queue<Path> musicList = new LinkedList<>();

    private MediaPlayer mediaPlayer ;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        // Everyone should have this album. Edit the path if your musical taste is poor.
        Files.find(Paths.get(System.getProperty("user.home"),"Music/iTunes/iTunes Media/Music/Thievery Corporation/Saudade/"), 100,
                (p, a) -> p.toString().toLowerCase().endsWith(".m4a"))
                .forEach(musicList::add);

        playMusic();

        ScrollPane scrollpane = new ScrollPane();
        Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/7/70/Kusatma_Zonaro.jpg");
        ImageView imageView = new ImageView(image);
        scrollpane.setContent(imageView);
        scrollpane.setPannable(true);
        Scene scene = new Scene(new StackPane(scrollpane));
        primaryStage.setScene(scene);
        primaryStage.setFullScreen(true);
        primaryStage.show();

    }

    @Override
    public void stop() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.dispose();
        }
    }

    private void playMusic() {
        if(musicList.peek() == null)
        {
            return;
        }
        mediaPlayer = new MediaPlayer(new Media(musicList.poll().toUri().toString()));
        mediaPlayer.setOnReady(() -> {
            mediaPlayer.play();
            mediaPlayer.setOnEndOfMedia(() -> {
                mediaPlayer.dispose();
                playMusic();
            });
        });

    }
}