JavaFx学习问题2--音频、视频播放失败情况

文章目录

  • 一、路径注意事项:
    • [① 用相对路径的时候别忘了前面的斜杠](#① 用相对路径的时候别忘了前面的斜杠)
    • [② uri问题](#② uri问题)
  • 二、播放不了的问题
    • [① 获取的媒体文件路径本身就是不对的](#① 获取的媒体文件路径本身就是不对的)
    • [② 必须是uri](#② 必须是uri)
    • [③ 特殊情况](#③ 特殊情况)
  • 额外收获:

一、路径注意事项:

完整代码如下:

java 复制代码
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Main extends Application {


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


        primaryStage.setTitle("BA怪叫器雏形版");

        // 创建上下两个部分的布局
        BorderPane borderPane = new BorderPane();

        // 上部分用于展示图片的ImageView,放置在一个StackPane中

        ImageView imageView = new ImageView();
        imageView.setFitWidth(300); // 宽度占30%
        imageView.setFitHeight(300); // 高度占80%

        borderPane.setCenter(imageView);

        // 下部分用于放置按钮的GridPane
        GridPane gridPane = new GridPane();
        gridPane.setAlignment(Pos.CENTER);
        gridPane.setHgap(15);
        gridPane.setVgap(20);

        // 创建9个带图片的按钮,并指定不同的图片和音频
        for (int i = 0; i < 15; i++) {
            Button button = createImageButton(i,imageView);
            int row = i / 5;
            int col = i % 5;
            gridPane.add(button, col, row);
        }
        borderPane.setBottom(gridPane);

        // 创建场景并显示
        Scene scene = new Scene(borderPane, 600, 700);
        primaryStage.setScene(scene);
        primaryStage.getIcons().add(new Image("/img/cover.jpg"));
        primaryStage.show();
    }

    // 创建带图片的按钮,并添加事件处理程序
    private Button createImageButton(int index,ImageView mainImage) {
        String[] imagePaths = {
                "/img/fox.jpg", "/img/xiaotao1.png", "/img/xingye.jpg","/img/fox.jpg",
                "/img/fox.jpg", "/img/fox.jpg", "/img/fox.jpg","/img/fox.jpg",
                "/img/fox.jpg", "/img/fox.jpg", "/img/fox.jpg","/img/fox.jpg",
                "/img/fox.jpg", "/img/fox.jpg", "/img/fox.jpg","/img/fox.jpg"
        };

        Image image = new Image(imagePaths[index]);
        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(50);
        imageView.setFitHeight(50);

        Button button = new Button("", imageView);
        button.setOnAction(event -> {
            String folderPath="";
            if (index==0) {
                folderPath="/audio/fox1";
            }else if (index==1){
                folderPath= "/audio/xiaotao";
            }else if (index==2){
                folderPath= "/audio/xingye";
            }
            List<String> filePaths=new ArrayList<>();

            //这里用于调试
            String uri=getClass().getResource(folderPath).toString();

            try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(Paths.get(getClass().getResource(folderPath).toString().substring(6)))) {
                for (Path path : directoryStream) {
                    if (Files.isRegularFile(path)) {
                        filePaths.add(path.toString());
                        System.out.println("文件路径: " + path.toString());
                    }
                }
            }  catch (NoSuchFileException e) {
                System.out.println("指定的文件夹不存在:" + e.getMessage());
            } catch (IOException e) {
                System.out.println("无法读取文件夹: " + e.getMessage());
            }
            // 当按钮点击时,更新上部ImageView的图片
            mainImage.setImage(image);

            Random random=new Random();
            int audioIndex=random.nextInt(filePaths.size());

            // 播放MP3音频
            String audioFilePath = filePaths.get(audioIndex);
            audioFilePath = audioFilePath.replace("\\", "/");
            try {
                URI audioUri = Paths.get(audioFilePath).toUri();
                Media media = new Media(audioUri.toString());
                MediaPlayer mediaPlayer = new MediaPlayer(media);
                //添加一个setOnReady()事件监听器来确保音频文件在准备好之后再进行播放
                mediaPlayer.setOnReady(() -> {
                    mediaPlayer.play();
                });
            } catch (Exception e) {
                e.printStackTrace();
            }


        });

        return button;
    }



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

① 用相对路径的时候别忘了前面的斜杠

并不是什么大问题,只是说这个细节可能会被遗漏

② uri问题

当时搞这个费了老劲了,搞不懂为啥是非法路径,使用getResource获取编译出来的文件夹路径会前面会出现file:/,必须把这个file:/去掉才能进行下一步文件夹下的文件读取

二、播放不了的问题

① 获取的媒体文件路径本身就是不对的

c 复制代码
D:\javaFX1\out\production\java\audio\fox1\audio0.wav

从directoryStream(忽略这个,只是一个特殊指代词)得到的文件路径,要注意路径里面的是斜杠还是反斜杠,合法的路径应该是/才对,要把"\"(反斜杠)换成"/"(斜杠)

加以下这行代码就可以了audioFilePath = audioFilePath.replace("\\", "/");这里源的位置两个斜杠分别代表斜杠和转义符

② 必须是uri

转换完反斜杠,播放媒体,那你大概率会遇到下面这个错误

java 复制代码
java.lang.UnsupportedOperationException: Unsupported protocol "xxx"

这个错误是由于尝试使用不支持的协议导致的。在JavaFX的Media类中,它接受的是一个合法的URI(Uniform Resource Identifier),而不是简单的文件路径。需要将文件路径转换为正确的URI格式,然后再传递给Media类

③ 特殊情况

我遇到一种奇怪的现象,打断点看路径没有问题,文件在项目里也有,但老是报not found的情况,最后发现是编译结果那里没把我项目里的文件编译出来,重新编译也没用。

碰到这种情况,直接把整个out删掉,然后再给它一锤子(编译),看它还发不发癫

额外收获:

URI和URL区别的通俗理解

借用一句话就是: 去村子找个具体的人就是URI(这个人),如果用地址:某村多少号房子第几间房的主人 就是URL,如果用身份证号+名字 去找就是URN了

相关推荐
yaoxtao2 分钟前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
liliangcsdn1 小时前
Leiden社区发现算法的学习和示例
学习·数据分析·知识图谱
Swift社区1 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT2 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy2 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss4 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续4 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0444 小时前
ReAct模式解读
java·ai
轮到我狗叫了5 小时前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法