首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重用AudioInputStream

重用AudioInputStream
EN

Stack Overflow用户
提问于 2021-09-14 20:59:07
回答 1查看 21关注 0票数 0

我有一个程序,我为一个朋友做了一段时间,我有一个计时器和闹钟的功能。它会在您启动计时器时播放一个声音并显示一个图像,并在计时器结束时播放另一个声音和图像。它一直运行良好(或多或少),但我的朋友最近切换到Linux,并有一些更具交互性的声音控制器,这导致我们发现了该程序的一个问题:每次播放声音时,它都会创建一个全新的输入流,该输入流不会被重用,直到程序完全关闭时才会消失。这不仅是我的这个糟糕的设计,我想要学习如何修复,而且当我的朋友试图多次使用计时器而没有关闭程序时,它也会导致问题。我相信修复方法是让所有声音都通过一个输入流播放(如果有人对Java和Linux的交互有更多了解,请指正我)。我尝试简单地将AudioInputStream设置为全局变量,并在每次使用之前重新设置它,但这会导致图像和声音完全停止工作,我不知道为什么。下面是我当前和有缺陷的代码中的actionPerformed on按钮按下。下面是有效但无效的代码。

代码语言:javascript
复制
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        
        boolean needNewThread = false;
        if (imgWindow.getIcon() == null) {
            needNewThread = true;
        }
        timeUpLabel.setText(" ");
        BufferedImage buffImg = null;
        try{
            globalAudioIn.reset();
            URL url = this.getClass().getResource("/EvilManiMani.wav");
            globalAudioIn = AudioSystem.getAudioInputStream(url);
            Clip clip = AudioSystem.getClip();
            clip.open(globalAudioIn);
            clip.start();
            buffImg = ImageIO.read(getClass().getResource("/images/cloudWait.png"));
            imgWindow.setIcon(new ImageIcon(buffImg));
            System.out.println(buffImg.toString());
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
        Integer inputTime = Integer.parseInt(timeTextField.getText());
        timerLabel.setText(inputTime + ":00");
        if(needNewThread) {
            t = new Timer(1000, new ActionListener (){
                @Override
                public void actionPerformed(ActionEvent ae){
                    String[] minsAndSeconds = timerLabel.getText().split(":");
                    boolean timesUp = false;
                    if(minsAndSeconds[0].startsWith("-")) {
                        timesUp = true;
                        String temp = minsAndSeconds[0].substring(1);
                        minsAndSeconds[0] = temp;
                    }
                    Integer minutes = Integer.parseInt(minsAndSeconds[0]);
                    Integer seconds = Integer.parseInt(minsAndSeconds[1]);
                    seconds += (minutes*60);
                    if(seconds > 0 && !timesUp){
                        minutes = --seconds/60;
                        seconds %= 60;
                        if(seconds >= 10) {
                            timerLabel.setText(minutes + ":" + seconds);
                        }else {
                            timerLabel.setText(minutes + ":0" + seconds);
                        }
                    }else if(seconds > 0 && timesUp) {
                        minutes = ++seconds/60;
                        seconds %= 60;
                        if(seconds >= 10) {
                            timerLabel.setText("-" + minutes + ":" + seconds);
                        }else {
                            timerLabel.setText("-" + minutes + ":0" + seconds);
                        }
                    }else if (seconds == 0){
                        timerLabel.setText("-0:01");
                        BufferedImage bufferedImg = null;
                        try {
                            globalAudioIn.reset();
                            URL url = this.getClass().getResource("/YouWin!.wav");
                            globalAudioIn = AudioSystem.getAudioInputStream(url);
                            Clip clip = AudioSystem.getClip();
                            clip.open(globalAudioIn);
                            clip.start();
                            bufferedImg = ImageIO.read(getClass().getResource("/images/drinkyMattPog.png"));
                            imgWindow.setIcon(new ImageIcon(bufferedImg));
                            timeUpLabel.setText("Time's up");
                        } catch (Exception e) {
                            System.out.println(e.getMessage());
                        }
                    }
                }
            });
            t.setRepeats(true);
            t.start();
        }
    }

有效但无效:

代码语言:javascript
复制
   private void buttonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        
        boolean needNewThread = false;
        if (imgWindow.getIcon() == null) {
            needNewThread = true;
        }
        timeUpLabel.setText(" ");
        BufferedImage buffImg = null;
        try{
            URL url = this.getClass().getResource("/EvilManiMani.wav");
            AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
            Clip clip = AudioSystem.getClip();
            clip.open(audioIn);
            clip.start();
            buffImg = ImageIO.read(getClass().getResource("/images/cloudWait.png"));
            imgWindow.setIcon(new ImageIcon(buffImg));
            System.out.println(buffImg.toString());
        } catch (Exception e){
            System.out.println(e.getMessage());
        }
        Integer inputTime = Integer.parseInt(timeTextField.getText());
        timerLabel.setText(inputTime + ":00");
        if(needNewThread) {
            t = new Timer(1000, new ActionListener (){
                @Override
                public void actionPerformed(ActionEvent ae){
                    String[] minsAndSeconds = timerLabel.getText().split(":");
                    boolean timesUp = false;
                    if(minsAndSeconds[0].startsWith("-")) {
                        timesUp = true;
                        String temp = minsAndSeconds[0].substring(1);
                        minsAndSeconds[0] = temp;
                    }
                    Integer minutes = Integer.parseInt(minsAndSeconds[0]);
                    Integer seconds = Integer.parseInt(minsAndSeconds[1]);
                    seconds += (minutes*60);
                    if(seconds > 0 && !timesUp){
                        minutes = --seconds/60;
                        seconds %= 60;
                        if(seconds >= 10) {
                            timerLabel.setText(minutes + ":" + seconds);
                        }else {
                            timerLabel.setText(minutes + ":0" + seconds);
                        }
                    }else if(seconds > 0 && timesUp) {
                        minutes = ++seconds/60;
                        seconds %= 60;
                        if(seconds >= 10) {
                            timerLabel.setText("-" + minutes + ":" + seconds);
                        }else {
                            timerLabel.setText("-" + minutes + ":0" + seconds);
                        }
                    }else if (seconds == 0){
                        timerLabel.setText("-0:01");
                        BufferedImage bufferedImg = null;
                        try {
                            URL url = this.getClass().getResource("/YouWin!.wav");
                            AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
                            Clip clip = AudioSystem.getClip();
                            clip.open(audioIn);
                            clip.start();
                            bufferedImg = ImageIO.read(getClass().getResource("/images/drinkyMattPog.png"));
                            imgWindow.setIcon(new ImageIcon(bufferedImg));
                            timeUpLabel.setText("Time's up");
                        } catch (Exception e) {
                            System.out.println(e.getMessage());
                        }
                    }
                }
            });
            t.setRepeats(true);
            t.start();
        }
    }                         

谢谢!此外,欢迎对代码提出任何建设性的批评,无论它是否与问题相关。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-15 01:09:41

在调用clip.start()之前,添加一个侦听器以关闭剪辑和AudioInputStream:

代码语言:javascript
复制
clip.open(audioIn);
clip.addLineListener(e -> {
    if (e.getType().equals(LineEvent.Type.STOP)) {
        clip.close();
        try {
            audioIn.close();
        } catch (IOException e) {
            System.err.println(e);
        }
    }
});
clip.start();

既然你已经要求了建设性的批评:永远不要写catch (Exception)。您不希望捕获RuntimeException或它的子类,因为它们通常指示需要暴露和修复的程序员错误,而不是掩饰。在您的例子中,您应该使用catch (LineUnavailableException | IOException e)

catch块不应打印e.getMessage()。相反,使用e.printStackTrace(),因此如果发生异常,您将确切地知道发生了什么以及发生在哪里。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69184459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档