0

我在这里很困惑。我编写了一个非常基本的程序来测试我们一直在一个单独的 Eclipse 项目中处理的 MP3 抽象。MP3 类有 3 个依赖项,我将它们移至主项目,我们也复制了该类。但是,当尝试在新项目上播放歌曲时,代码突然停止工作。修复?移除 SWT 罐子。我不知道它为什么会起作用,但是删除 SWT 会使 MP3 播放,然后重新添加它会再次破坏它。swt.jar 中包含的唯一内容是org.eclipse.swt代码,通过 JD-GUI 反编译确认。问题是没有任何音频代码从 org.eclipse.swt 导入任何内容。知道如何添加 SWT 文件可以完全破坏 MP3 代码吗?

我的测试文件:

MP3 mp3 = new MP3(new File("four-chord-song.mp3"));

mp3.play(60);

Scanner in = new Scanner(System.in);
long lastTime = System.currentTimeMillis();
while (true) {
    in.nextLine();
    System.out.println(System.currentTimeMillis() - lastTime);
    lastTime = System.currentTimeMillis();
}

还有 MP3 文件(有点乱,注意到挂在 SWT 的那一行):

package com.partyrock.music;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.*;

public class MP3 extends Sound {

private File file;
private boolean isPaused;
private boolean isPlaying;
private AudioFileFormat fileFormat;
private Thread MP3Thread;
private SourceDataLine line;
private AudioInputStream din;
private MP3Player myMP3Player;
private double startTime = 0;

/**
 * Constructs an MP3 from a given file.
 * @param file The file
 */
public MP3(File file) {
    super();
    this.file = file;
    isPaused = false;

    if (!file.exists()) {
        System.err.println("MP3 constructed for non-existent file");
        return;
    }

    try {
        fileFormat = AudioSystem.getAudioFileFormat(file);
    } catch (UnsupportedAudioFileException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public class MP3Player implements Runnable {

    private double startTime;
    boolean paused;

    public MP3Player(double var) {
        this.startTime = var;
        paused = false;
    }

    public void run() {
        din = null;
        try {
            AudioInputStream in = AudioSystem.getAudioInputStream(file);
            AudioFormat baseFormat = in.getFormat();
            AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
            din = AudioSystem.getAudioInputStream(decodedFormat, in);

            DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);
// ****** This is the line that breaks when SWT is included
            line = (SourceDataLine) javax.sound.sampled.AudioSystem.getLine(info);

            if (line != null) {
                line.open(decodedFormat);
                byte[] data = new byte[4096];

                // Start
                line.start();
                isPlaying = true;

                // Skip first startTime seconds
                int bytesToSkip = (int) (startTime
                        * (Integer) fileFormat.properties().get("mp3.bitrate.nominal.bps") / 8);
                din.skip(bytesToSkip);

                int nBytesRead;
                while ((data != null) && (din != null) && (nBytesRead = din.read(data, 0, data.length)) != -1
                        && isPlaying) {
                    // Skip first startTime seconds
                    if (isPaused == true) {
                        while (isPaused) {
                            Thread.sleep(100);
                        }
                    }
                    line.write(data, 0, nBytesRead);
                    // System.out.println(line.getMicrosecondPosition());
                }

                isPlaying = false;
                // Stop
                if (line != null && din != null) {
                    line.drain();
                    line.stop();
                    line.close();
                    din.close();
                }
            }

        } catch (Exception e) {
            System.out.println("Error!");
            e.printStackTrace();
        } finally {
            if (din != null) {
                try {
                    din.close();
                } catch (IOException e) {
                }
            }
        }
    }
}

@Override
public void play(double startTime) {
    this.startTime = startTime;
    myMP3Player = new MP3Player(startTime);
    MP3Thread = new Thread(myMP3Player);
    MP3Thread.start();

}

public void playthread(double startTime) {

}

@Override
public double getDuration() {
    // TODO Auto-generated method stub
    Long microseconds = (Long) fileFormat.properties().get("duration");
    double milliseconds = (int) (microseconds / 1000);
    double seconds = (milliseconds / 1000);
    return seconds;
}

@Override
public void pause() {
    // TODO Auto-generated method stub
    isPaused = true;
    // MP3Thread.suspend();
    myMP3Player.paused = true;
}

public void unpause() {
    // TODO Auto-generated method stub
    isPaused = false;
    myMP3Player.paused = false;
    // MP3Thread.resume();
}

@Override
public double getCurrentTime() {
    // TODO Auto-generated method stub
    System.out.println(line.getMicrosecondPosition());
    return startTime + (line.getMicrosecondPosition() / 1000);
}

/**
 * Returns the file associated with this MP3
 * @return The mp3 file
 */
public File getFile() {
    return file;
}

public void stop() {
    isPlaying = false;

    pause();
    MP3Thread = null;
    myMP3Player = null;

    isPaused = false;
    isPlaying = false;
    // fileFormat = null;
    MP3Thread = null;
    line = null;
    din = null;
    myMP3Player = null;
    startTime = 0;

    // Stop
    // line.drain();
    // line.stop();
    // line.close();
}

}
4

1 回答 1

0

我对如何操作感到很困惑,但是我重新下载了最新的 SWT,并且它起作用了,尽管我必须-XstartOnFirstThread在启动时添加参数或出现***WARNING: Display must be created on main thread due to Cocoa restrictions.错误。

于 2013-01-04T06:29:47.460 回答