java.lang.ClassCastException:无法将DirectClip转换为javax.sound.sampled.源数据行

amrnrhlw  于 2022-12-02  发布在  Java
关注(0)|答案(1)|浏览(137)

所以,我现在正在为我的游戏开发新的声音引擎,因为旧的声音引擎不好。为此,我尝试使用SourceDataLine,但运行时它返回:

java.lang.ClassCastException: com.sun.media.sound.DirectAudioDevice$DirectClip cannot be cast to javax.sound.sampled.SourceDataLine
        at com.glowiak.aws.SoundLibrary.play(Main.java:1360)
        at com.glowiak.aws.UIButton.loop(Main.java:475)
        at com.glowiak.aws.Renderer.paintComponent(Main.java:174)
        at javax.swing.JComponent.paint(JComponent.java:1056)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:290)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
        at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
        at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
        at javax.swing.RepaintManager$4.run(RepaintManager.java:831)
        at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
        at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
        at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
        at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
        at java.awt.EventQueue.access$500(EventQueue.java:97)
        at java.awt.EventQueue$3.run(EventQueue.java:709)
        at java.awt.EventQueue$3.run(EventQueue.java:703)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

发动机代码为:

class SoundLibrary // the second option from https://www.baeldung.com/java-play-sound modified to fit my engine idea
{
    public static final int BUFFER_SIZE = 4096;
    
    public ArrayList<String> urls;
    
    public void registerSound(String fp)
    {
        urls.add(fp);
    }
    public boolean play(int i)
    {
        try {
            InputStream is = getClass().getResourceAsStream(urls.get(urls.size() - 1));
            AudioInputStream ais = AudioSystem.getAudioInputStream(is);
            SourceDataLine.Info dli = new DataLine.Info(Clip.class, ais.getFormat());
            SourceDataLine sdl = (SourceDataLine)AudioSystem.getLine(dli);
            sdl.open(ais.getFormat());
            
            sdl.start();
        
            byte[] buffer = new byte[BUFFER_SIZE];
            int rb = -1;
            while ((rb = ais.read(buffer)) != -1)
            {
                sdl.write(buffer, 0, rb);
            }
            sdl.drain();
            sdl.close();
            ais.close();
            
            return true;
        } catch (Exception e)
        {
            e.printStackTrace();
            
            return false;
        }
    }
    public static void cleanup()
    {
    }
    public SoundLibrary()
    {
        this.urls = new ArrayList<String>();
        
        this.registerSound("/resources/sound/bow.wav");
        this.registerSound("NULL");
        this.registerSound("/resources/sound/buttonpress.wav");
    }
}

就在上面。
在这里我写的东西,没有人关心只是StackOverflowException告诉我,我必须在这里写的东西,否则它不会允许我张贴,只是忽略这两行。
有人能解释一下我做错了什么吗?

bq3bfh9z

bq3bfh9z1#

下面的方法对你有效吗?改变你获取URL的方式来适应你的情况。

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;

public class SoundDemo {

    public static void main(String[] args) {
        SoundDemo sound = new SoundDemo();
        for (URL url : sound.urls) {
            try {
                CountDownLatch outerLatch = new CountDownLatch(1);
                sound.play(url, outerLatch);
                outerLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    List<URL> urls;

    public SoundDemo() {
        // You'll change the following to suit your situation.
        String path = "...";
        urls = Stream.of(new File(path).listFiles())
            .filter(file -> !file.isDirectory() && file.getName().endsWith("wav"))
            .map(this::getUrl)
            .collect(Collectors.toList());

        System.out.println(urls);
    }

    public void play(URL url, CountDownLatch outerLatch) {
        CountDownLatch syncLatch = new CountDownLatch(1);
        System.out.println("playing " + url.getFile());
        
        // Use try-with-resources to ensure the stream and clip are closed.
        try (AudioInputStream ais = AudioSystem.getAudioInputStream(url);
            Clip clip = AudioSystem.getClip();) {

            clip.addLineListener(e -> {
                if (e.getType() == LineEvent.Type.STOP) {
                    syncLatch.countDown();
                }
            });
            
            clip.open(ais);
            clip.start();
            syncLatch.await();
            while (clip.getFramePosition() < clip.getFrameLength()) {
                Thread.yield();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        outerLatch.countDown();

    }

    private URL getUrl(final File file) {
        try {
            return file.toURI().toURL();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }

}

相关问题