# MP3-Player mit Grundfunktionen



## multiholle (29. Dez 2008)

Ich versuche mit Hilfe der JLayer-Library einen Mp3 Player mit den Grundfunktionen Play|Pause|Resume|Stop zu schreiben. Play und Stop funktionieren soweit. Ich weiß nur nicht, wie ich den Player anhalte und dann an der gleichen Position fortsetze. Anbei der Code:


```
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;
import javazoom.jl.player.FactoryRegistry;
import javazoom.jl.player.advanced.AdvancedPlayer;
import javazoom.jl.player.advanced.PlaybackEvent;
import javazoom.jl.player.advanced.PlaybackListener;


public class Mp3Player extends JFrame implements ActionListener{
	public Mp3Player() {
		state = "STOP";
		
		setTitle("Mp3Player");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		btnPlay.setActionCommand("PLAY");
		btnPlay.addActionListener(this);
		btnPause.setActionCommand("PAUSE");
		btnPause.addActionListener(this);
		btnStop.setActionCommand("STOP");
		btnStop.addActionListener(this);
		
		pnlButtons.add(btnPlay);
		pnlButtons.add(btnPause);
		pnlButtons.add(btnStop);
		
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(pnlInfo, BorderLayout.CENTER);
		getContentPane().add(pnlButtons, BorderLayout.SOUTH);
		
		pack();
		setVisible(true);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		String actionCommand = e.getActionCommand();
		if (actionCommand.equals("PLAY")) {
			if (state.equals("STOP"))
				play();
			else if (state.equals("PAUSE"))
				resume();
		} else if (actionCommand.equals("PAUSE")) {
			if (state.equals("PLAY"))
				pause();
		} else if (actionCommand.equals("STOP")) {
			if (state.equals("PLAY") || (state.equals("PAUSE")))
				stop();
		}		
	}
	

	
	private void play() {
		state = "PLAY";
		
		try {
			FileInputStream fileInputStream = new FileInputStream("t:/test.mp3");
			InputStream inputStream = new BufferedInputStream(fileInputStream);
			
			FactoryRegistry factoryRegistry = FactoryRegistry.systemRegistry();
			audioDevice = factoryRegistry.createAudioDevice();
			
			player = new AdvancedPlayer(inputStream, audioDevice);
			player.setPlayBackListener(new PlaybackListener() {
				@Override
				public void playbackStarted(PlaybackEvent arg0) {
					System.out.println(">> Playback started.");
				}
				@Override
				public void playbackFinished(PlaybackEvent arg0) {
					System.out.println("<< Playback finished.");
				}
			});
			
			playerThread = new PlayerThread();
			playerThread.start();
			timeThread = new TimeThread();
			timeThread.start();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JavaLayerException e) {
			e.printStackTrace();
		}
	}
	
	public void pause() {
		state = "PAUSE";
		
		position = audioDevice.getPosition();
		System.out.println("|| Pause (" + position + ")");
		
		// player pausieren
		// timer pausieren
	}
	
	public void resume() {
		state = "PLAY";
		
		// player fortsetzen
		// timer fortsetzen
	}
	
	public void stop() {
		state = "STOP";
		
		player.stop();
		timeThread.interrupt();
	}
	
	private class PlayerThread extends Thread {
		@Override
		public void run() {
			try {
				player.play();
			} catch (JavaLayerException e) {
				e.printStackTrace();
			}

		}
	}
	
	private class TimeThread extends Thread {
		@Override
		public void run() {
			while (true) {
				if (isInterrupted()) {
					break;
				}
				System.out.println("... playing (" + audioDevice.getPosition() + ")");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					interrupt();
				}
			}
		}
	}
	
	public static void main(String[] args) {
		new Mp3Player();
	}

	private JButton btnPlay = new JButton("Play");
	private JButton btnPause = new JButton("Pause");
	private JButton btnStop = new JButton("Stop");
	
	private JPanel pnlInfo = new JPanel(new BorderLayout());
	private JPanel pnlButtons = new JPanel(new FlowLayout());
	
	private AudioDevice audioDevice;
	private AdvancedPlayer player;
	private int position = 0;
	
	private PlayerThread playerThread = null;
	private TimeThread timeThread = null;
	
	private String state;
}
```


----------



## homer65 (30. Dez 2008)

Hallo,
komisch ich habe erst vor kurzem so was ähnliches auch mit JLayer programmiert. ) Klappt bei mir auch ganz gut.
Aber zu deiner Frage habe ich auch keine befriedigende Antwort. Ich glaube eher, das dies mit den einfachen Player gar nicht geht. Aber es gibt im Packet javazoom.jl.player.advanced die Klasse AdvancedPlayer, vielleicht geht es damit. Habe aber letztendlich auch keine Ahnung.
Könnte aber mit der Methode play(int start, int end) gehen.
Gruß Christian


----------



## The_S (30. Dez 2008)

Evtl. ist das hier interessant für dich:

http://www.java-forum.org/de/viewtopic.php?t=36827&highlight=mp3


----------



## Spacerat (30. Dez 2008)

Ich meine, das hatten wir schonmal... (Suche blieb jedoch erfolglos, hmmm)
Was soll's... Hier nochmal meine Lösung mit 2 Status-Flags...

```
...
  private boolean running = false, pause = false;

  public void run()
  {
    try {
      while(running) {
        if(!pause) {
          // Thread ausführen...
        }
      }
    } catch(InterruptedException e) {
      interrupt();
    }
  }

  public synchronized void start()
  {
    pause = false;
    if(!running) {
        running = true;
        super.start();
    }
  }

  public void stop()
  {
    running = false;
    super.interrupt();
  }

  public void pause()
  {
    pause = !pause;
  }
...
```
Aus aktuellem Anlass mus ich allerdings auch sagen, das dieses nicht die sauberste Lösung ist, weil der Thread auch während "pause==true" weiter läuft, also "Performance" frisst. Ich habe mal angefangen mich mit Semaphoren zu beschäftigen, und bin davon überzeugt, das es damit besser geht.

mfg Spacerat


----------



## Guest (30. Dez 2008)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Evtl. ist das hier interessant für dich:
> http://www.java-forum.org/de/viewtopic.php?t=36827&highlight=mp3


Klingt so gar nicht schlecht, nur der Kommentar des Autors gefällt mir nicht:


> Was mir daran nicht gefällt ist, dass der Sound kratzt und manchmal unkontrollierte Fehler geworfen werden





			
				Spacerat hat gesagt.:
			
		

> Ich meine, das hatten wir schonmal... (Suche blieb jedoch erfolglos, hmmm)
> Was soll's... Hier nochmal meine Lösung mit 2 Status-Flags...


Damit könnte es evtl. klappen. Nur leider fehlt mir dann immer noch eine Funktion wie "setPosition()" um später dann auch zu Spulen :/ 

Gibt es evtl. andere Möglichkeiten, andere Libs? Ich möchte doch nur einen simplen Mp3-Player programmieren: 
PLAY | PAUSE | RESUME | STOP | SPULEN


----------



## The_S (30. Dez 2008)

FMJ z. B. oder JMF


----------



## Spacerat (30. Dez 2008)

Ich kann ja mal rausplatzen...

Ich entwickele schon seit einiger Zeit ein Interface, mit welchem es möglich sein soll in Java registrierte Datentypen mit einer simplen Methode zu Identifizieren und zu laden. Im Rahmen der Entwicklung entstand damit auch der abstrakte Datentyp "AudioFile", auf den man diese Methoden bereits anwenden kann. Leider hilft dir das zur Stunde nicht weiter...
Das Interface arbeitet prinzipiell wie die alt hergebrachte "datatypes.library" des AmigaOS 3.0 und aufwärts (wer sich erinnern kann...). Datentypen können durch Hinzufügen von Load- und View-Klassen registriert werden. Die Anzahl der bereits vorhandenen Datentypen ist jedoch noch alles andere als hoch. Bei einigen gibt es sogar lizenzrechtliche Gründe, die eine Entwicklung z.Zt. noch verzögern oder gar vermeiden (Ich glaube MP3 findet man auf der Liste unter "verzögert").
Bekannte sagen mir, das das Interface bereits unheimlich mächtig ist, da es im Gegensatz zu anderen Methoden, in Java irgendwelche Dateien zu laden (z.B. findet man in JOGL, Java3D und sogar in den JDK-Demos 3 verschiedene WaveFront-Loader) eine Bibliothek ist. Genau diese Aussagen stürzen mich in das dilemma der Vermarktung. MÄCHTIG bedeutet KOHLE!. Andererseits ist es ein Sakrileg es der Kommune vorzuenthalten. Wenn mir jemand sagt wo und wie, kann ich ja mal 'ne BETA davon auf den Markt schmeissen. Mal sehen was draus wird.

mfg Spacerat


----------

