Soundprobleme

Mugiii

Mitglied
Erstmal hallo an alle bin neu hier :)

Ich programmiere seit ein paar Tagen ein R-Type ähnliches Spiel mit Java2D.
Bisher lief alles wunderbar. Nur habe ich einige kleine Probleme mit den Sounds.

1. Wenn Ich das Spiel in Eclipse ausführe, funktionieren die Sounds wunderbar, kommen und gehen.
Nachdem ich aber das Project als jar file (oder runnable jar file) exportiert habe, kommen die Sounds nicht mehr, sind aber im Jar file enthalten.

2. Wenn ich beim spielen (in eclipse) GameOver gehe, kommt der GameOver sound, aber der screen freezd ungefähr 4 Sekunden lang, bevor der GameOver screen kommt. (Nur wenn der Sound eingefügt ist). Im jar File freezd er ganz und muss forceclosed werden. Wäre es möglich für den Sound ein Thread zu erstellen(kenne mich nicht so aus mit Threads), oder gibt es auch andere möglichkeiten?
 

Developer_X

Top Contributor
Hi Muggii,

1. Wenn du die sounds in eclipse dabei hast ist ja alles wunderbar, aber wenn du es extrahierst, hast du probleme, das kenne ich, lege die dateien und ordner einfach zu deiner jar, dann klappt das auch,

2. Zeig mal wie du Sounds abspielen lässt, wenn du ihn nicht in einem Thread spielst, dann blockiert er alles, ist klar. Ich zeige dir mal wie ich sounds abspiele :
Java:
		try
		{
			InputStream in = new FileInputStream("Dev_X.wav");
			AudioStream audioStream = new AudioStream(in);         
			AudioPlayer.player.start(audioStream);
		}
		catch(Exception e)
		{
		}

So zum Beispiel.

Und zu Punkt 1 noch einmal :
-
Wenn du jetzt in deiner Packet Hierarchie in Eclipse, da hast du ja
folgende sachen :
- einmal die src-Folder mit den Packeten für das Programm,
- dann noch einmal JRE System Library
- und dann deine sounds, so wie die sounds da drin liegen, muss du sie zur jar bei geben, wenn du die sounds beispielsweise in einen Ordner (rechtsklick->new->folder) steckst, kopier diesen ordner zu deiner Jar, dann klappt das.
-

Ich hoffe ich konnte dir helfen,
M.f.G. Developer-X
 

Mugiii

Mitglied
Danke für die Antwort. :)

Zum abspielen:
Ich habe eine Beispielklasse (gegoogelt) genommen, und implementiert.
Die sieht so aus:
Java:
import java.io.*;
import javax.sound.sampled.*;

/**
    The SimpleSoundPlayer encapsulates a sound that can be opened
    from the file system and later played.
*/
public class SimpleSoundPlayer  {

    public static void main(String[] args) {
        // load a sound
        SimpleSoundPlayer sound =
            new SimpleSoundPlayer("../sounds/voice.wav");

        // create the stream to play
        InputStream stream =
            new ByteArrayInputStream(sound.getSamples());

        // play the sound
        sound.play(stream);

        // exit
        System.exit(0);
    }

    private AudioFormat format;
    private byte[] samples;

    /**
        Opens a sound from a file.
    */
    public SimpleSoundPlayer(String filename) {
        try {
            // open the audio input stream
            AudioInputStream stream =
                AudioSystem.getAudioInputStream(
                new File(filename));

            format = stream.getFormat();

            // get the audio samples
            samples = getSamples(stream);
        }
        catch (UnsupportedAudioFileException ex) {
            ex.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
    }


    /**
        Gets the samples of this sound as a byte array.
    */
    public byte[] getSamples() {
        return samples;
    }


    /**
        Gets the samples from an AudioInputStream as an array
        of bytes.
    */
    private byte[] getSamples(AudioInputStream audioStream) {
        // get the number of bytes to read
        int length = (int)(audioStream.getFrameLength() *
            format.getFrameSize());

        // read the entire stream
        byte[] samples = new byte[length];
        DataInputStream is = new DataInputStream(audioStream);
        try {
            is.readFully(samples);
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        // return the samples
        return samples;
    }


    /**
        Plays a stream. This method blocks (doesn't return) until
        the sound is finished playing.
    */
    public void play(InputStream source) {

        // use a short, 100ms (1/10th sec) buffer for real-time
        // change to the sound stream
        int bufferSize = format.getFrameSize() *
            Math.round(format.getSampleRate() / 10);
        byte[] buffer = new byte[bufferSize];

        // create a line to play to
        SourceDataLine line;
        try {
            DataLine.Info info =
                new DataLine.Info(SourceDataLine.class, format);
            line = (SourceDataLine)AudioSystem.getLine(info);
            line.open(format, bufferSize);
        }
        catch (LineUnavailableException ex) {
            ex.printStackTrace();
            return;
        }

        // start the line
        line.start();

        // copy data to the line
        try {
            int numBytesRead = 0;
            while (numBytesRead != -1) {
                numBytesRead =
                    source.read(buffer, 0, buffer.length);
                if (numBytesRead != -1) {
                   line.write(buffer, 0, numBytesRead);
                }
            }
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }

        // wait until all data is played, then close the line
        line.drain();
        line.close();

    }

}
Die Mainmethode habe ich hier gelöscht und in meine Mainklasse eingefügt.

Zum zweiten:
Im project Ordner habe ich die einzelnen packages mit den Klassen drin, den JRE, und einen Audio Ordner mit einem Unterordner Vocals, worin dann die Sounds sind.
Im Jar File ist diese Struktur geblieben, habe dann den Audio Ordner beikoppiert und hat wunderbar geklappt, danke ;).
Ist es nicht möglich den Ornder im Jar File zu integrieren, so dass man nur das JAR file braucht, um das Spiel zu spielen?
 

Developer_X

Top Contributor
schon, dann musst du aber mit dem Hässlichen FileInputStream arbeiten, dann getCodeBase dings dings, weiß ich jetzt auch nicht genau, ich finde dass ist aber sehr hässlich, deshalb empfehle ich dir :
Kopier die dateien einfach zur jar, dann hast du nicht zu viel arbeit, und benutzt, wenn du willst,, absofort, meinen Weg sounds abzuspielen, denn du musst zu geben, mein weg ist viel, viel kürzer oder?

M.f.G. Developer_X

PS:
Weißt du was es auch noch witziges gibt, es ist eigentlich mehr nebensächlich aber trotzdem interessant, du musst mal das java.awt.Toolkit benutzen, und die Methode beep ausführen.

Quasi so:
Java:
import java.awt.*;

public class Test
{
public static void main(String[]args)
{
Toolkit tk = Toolkit.getDefaultToolkit();
tk.beep();
}
}
 

Mugiii

Mitglied
Mit deiner Methode sind es schon einige Zeilen weniger.
Konnte ich aber nicht implementieren. Er kennt den AudioStream und AudioPlayer nicht. Die imports sind import sun.audio.AudioPlayer; import sun.audio.AudioStream; Die werden aber auch als Fehler markiert. Kannst du mir mal einen ganzen Beispielprogrammcoder zeigen?

Was den beep angeht, konnte ich irgendwie nie zum beepen bringen :confused:
 

Developer_X

Top Contributor
ok, nach beep, scheib einfach noch das hinein :
Java:
try{Thread.sleep(1000);}catch(Exception e){}

Zu deinem anderen Problem :
Java:
package soundPlayer;

import java.io.*;
import sun.audio.*;

public class SoundPlayer 
{
	public static void main(String[]args)
	{
		try
		{
			InputStream in = new FileInputStream("sources/sounds/"+text+".wav");
			AudioStream audioStream = new AudioStream(in);         
			AudioPlayer.player.start(audioStream);
			Thread.sleep(1000);
		}
		catch(Exception e)
		{
		}
	}
}
 

truesoul

Top Contributor
Ich würde
Java:
java.applet.AudioClip
verwenden und getClass().getResource("gameover.wav") benutzen.
Beispiel:
Java:
URL sound_url = getClass().getResource(path);
AudioClip audio = (AudioClip)Applet.newAudioClip(sound_url);

...

audio.play();
audio.stop();
audio.loop();
Die Audiodateien im Verzeichnis von src reinkopieren, und dann müsste es klappen.
Die Audio File beim Programmstart laden bzw beim Initializeren.
 

Mugiii

Mitglied
Danke nochmal für die Antworten

zur Developer_X' Methode.
Irgendwie kennt er AudioStream und AudioPlayer nicht, keine Ahnung wieso.
Details:
Multiple markers at this line
- Access restriction: The type AudioPlayer is not accessible due to restriction on required library /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar
- Access restriction: The method start(InputStream) from the type AudioPlayer is not accessible due to restriction on required library /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar
- Access restriction: The field player from the type AudioPlayer is not accessible due to restriction on required library /usr/lib/jvm/java-6-openjdk/jre/lib/rt.jar

Muss ich da noch was in die Systemlibrary reinkopieren?

Zur zweiten Methode: Dann müsste meine Klasse aber extends Applet sein, ist aber JPanel. Hab es mit einer neuen Klasse versucht mit Instanz versucht, gibt dann aber beim Ausführen einen NullPointer... ???:L
 

truesoul

Top Contributor
Hier ein kleines beispiel:

Java:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class Beispiel extends JPanel {

    private List<AudioClip> audioliste = new ArrayList<AudioClip>();
    
    public Beispiel() {

        JFrame frame = new JFrame("Musik");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setPreferredSize(new Dimension(80, 40));
        this.add(getJButton());
        frame.add(this);
        frame.pack();
        frame.setVisible(true);

        initAudio();
    }

    private JButton getJButton()
    {
        JButton button = new JButton("Drück Mich!");
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                audioliste.get(0).play();
            }
        });
        return button;
    }



    private void initAudio()
    {
        URL sound_url = getClass().getResource("Explosion.wav");
        AudioClip audio = (AudioClip)Applet.newAudioClip(sound_url);
        audioliste.add(audio);
    }



    public static void main(String[] args) {
        new Beispiel();

    }
}
 

Mugiii

Mitglied
Wow, gute Methode (hatte Nullpointer weil Pfad falsch angegeben).
Es freezd nicht mehr und nach dem Export sind die Sounds auch enthalten, danke euch habt super geholfen :)
 

Neue Themen


Oben