MP3-Player-Klasse mit InputStream

Kai008

Erfahrenes Mitglied
Ich habe Klassen zum MP3-Dateien abspielen im Tutorialbereich per JMF endeckt:
http://www.tutorials.de/forum/java-tutorials/330869-java-media-framework.html

Leider unterstützt das aber keine (Zip)InputStream's. Ich habe auch das MP3-Plugin von Sun probiert (wurde hier irgendwo von Tom gepostet) und ein paar andere Dinge, aber habe es nur mit den JMF richtig funktional hinbekommen. (Zumindest per File-Instanz).

Kann mir wer bitte eine Lösung nennen, oder eine MP3-Klasse die das kann?
 
Danke. Ich melde mich in der nächsten Zeit wie es funktioniert, da ich leider zu Hause keinen Internetzugang habe. >_>
 
Ich habe gestern den ganzen Tag versucht selbst einen Wrappler zu schreiben. Habe ihm gerade nicht mit, weil mir in der Früh die Zeit ausgegangen ist. Bringe ihm nächste Woche mal mit, damit ihm event. mal jemand anschauen und mich ausstallieren kann. ^^
Dann bin ich einfach auf Toms umgestiegen, und habe es sofort geschafft den BasicPlayer zum laufen zu bringen. Kann mir wer bitte nur sagen, wo man dort die aktuelle Zeit bei der er ließt abfragen kann, um nen JSlider zu schreiben? Finde es nicht. :(
 
So, hier ist mal mein Wrappler:

Java:
package core.musicplayer;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

final class Wrappler extends InputStream
{
	private static boolean currentRunning;

	private int currentMark;
	private int currentReadPointer;
	private int currentWrapplingPointer;
	
	private String currentStreamIdentificer;
	private Thread currentLockedThread;
	private Thread currentWrappingThread;
	private InputStream currentInputStream;
	private static Map<String, String[]> bufferMap;
	
	static
	{
		bufferMap = new HashMap<String, String[]>();
	}
	public Wrappler(InputStream stream, String identificer, long streamSize, int threadPriority)
	{
		super();
		
		if(threadPriority < Thread.MIN_PRIORITY ^ threadPriority > Thread.MAX_PRIORITY)
			new IllegalArgumentException("Thread Priority is out of range").printStackTrace();
		
		if(currentRunning);//TODO
		
		if(bufferMap.get(identificer) == null)
		{
			bufferMap.put(identificer, new String[(int) streamSize]);
			
			currentWrapplingPointer = 0;
			currentReadPointer = 0;
			currentMark = -1;
			currentInputStream = stream;
			currentStreamIdentificer = identificer;
			
			currentWrappingThread = new Thread(new WrapplerThread());
			currentWrappingThread.setPriority(threadPriority);
			currentWrappingThread.start();
		}
	}
	public int read() throws IOException
	{
		String[] wrappledBytes = bufferMap.get(currentStreamIdentificer);
		
		while(wrappledBytes[currentReadPointer] == null)
			Thread.yield();
		int ret = Integer.parseInt(wrappledBytes[currentReadPointer]);
		currentReadPointer++;
		return(ret);
	}
	public void mark(int i)
	{
		currentMark = currentReadPointer;
	}
	public void reset()
	{
		currentReadPointer = currentMark;
	}
	public void lockThreadUntilCurrentStreamIsReading(Thread t)
	{
		try
		{
			currentLockedThread = t;
			t.join();
		}
		catch(InterruptedException e)
		{
			e.printStackTrace();
		}
	}
	
	private class WrapplerThread extends Thread
	{
		public void run()
		{
			String[] bufferArray = bufferMap.get(currentStreamIdentificer);
			
			try
			{
				int read = 0;
				while((read = currentInputStream.read()) != -1)
				{
					bufferArray[currentWrapplingPointer] = String.valueOf(read);
					currentWrapplingPointer++;
					System.out.println(read);
				}
				if(currentLockedThread != null)
				{
					currentLockedThread.interrupt();
					currentLockedThread = null;
				}
				System.out.println(read);
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
	}
}

Hat zwischendurch plötzlich zum Lesen aufgehört. Ò_ó
Und Toms abgeänderter:

Java:
package core.musicplayer;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
 
public class AsynchronousWrapper extends InputStream
{
	private volatile BufferedInputStream wrappedInputStream;
	private volatile ConcurrentLinkedQueue<byte[]> dataQueue;
	private volatile int overallBytesConsumed;
	private volatile int overallBytesBuffered;
	private volatile int bufferSizeInBytes;

	private byte[] currentByteBuffer;
	private int currentBufferPosition;
	private int currentMarkPos; 
	private ExecutorService executorService;
 
	private volatile boolean eof = false;
       
	private Runnable buffering = new Runnable() {
		public void run()
		{
 			int maxDataQueueSize = 4;
 			int currentBytesBuffered = overallBytesBuffered	- overallBytesConsumed;

			while(!eof)
			{
				try
				{
					if (currentBytesBuffered < bufferSizeInBytes || dataQueue.size() < maxDataQueueSize)
					{
						ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
						
						while((currentBytesBuffered < bufferSizeInBytes) && (!eof))
						{
							byte[] buffer = new byte[bufferSizeInBytes];
							int bytesRead = wrappedInputStream.read(buffer);
 
							while((currentBytesBuffered < bufferSizeInBytes) && (bytesRead != -1))
							{
								byteArrayOutputStream.write(buffer, 0, bytesRead);
	 							overallBytesBuffered += bytesRead;
	 							currentBytesBuffered = overallBytesBuffered - overallBytesConsumed;
							}
							if(bytesRead == -1)
								eof = true;
 						}
						if (!eof)
						{
							dataQueue.add(byteArrayOutputStream.toByteArray());
							currentBytesBuffered = 0;
						}
					}
					else
					{
						TimeUnit.MILLISECONDS.sleep(5L);
					}
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
	};
	
	public AsynchronousWrapper(InputStream inputStream, int bufferSizeInBytes)
	{
		this.wrappedInputStream = new BufferedInputStream(inputStream, bufferSizeInBytes);
		this.bufferSizeInBytes = bufferSizeInBytes;
		this.dataQueue = new ConcurrentLinkedQueue<byte[]>();
 
		this.executorService = Executors.newSingleThreadExecutor();
		this.executorService.execute(this.buffering);
	}
 
	public int read() throws IOException
	{
		waitForCurrentByteBuffer();
		
		if (reachedEndOfStream())
		{
			return -1;
		}
		byte b = currentByteBuffer[currentBufferPosition];
		currentBufferPosition++;
		overallBytesConsumed++;
		return b & 0xFF;
	}
	public void mark(int i)
	{
		currentMarkPos = currentBufferPosition;
	}
	public void reset()
	{
		currentBufferPosition = currentMarkPos;
	}
	private boolean reachedEndOfStream()
	{
		return overallBytesConsumed == overallBytesBuffered;
	}
	private void waitForCurrentByteBuffer()
	{
		if (currentByteBuffer == null || currentBufferPosition > currentByteBuffer.length - 1)
		{
			currentByteBuffer = null;

			while (currentByteBuffer == null && !reachedEndOfStream())
			{
				currentByteBuffer = dataQueue.poll();
				currentBufferPosition = 0;

				try
				{
					TimeUnit.MILLISECONDS.sleep(5L);
				}
				catch(InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	public void close()
	{
		try
		{
			super.close();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		this.executorService.shutdownNow();
	}
}

Und die Hauptplayerklasse:

Java:
package core.musicplayer;

import java.io.IOException;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.swing.JPanel;
import javax.swing.JSlider;

import javazoom.jlgui.basicplayer.BasicController;
import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerEvent;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import javazoom.jlgui.basicplayer.BasicPlayerListener;
import core.Zipholder;

public class MusicPlayer extends Thread
{
	private static final int WRAPPLER_BUFFER_SIZE = 10 * 96 * 1024;
	private static final BasicPlayerListener LISTENER = new BasicPlayerListener() {
		public void progress(int arg0, long arg1, byte[] arg2, Map arg3)
		{
			if(currentSongSize != 0)
			{
				JSlider slider = PlayerPanel.getSongProgressSlider();
				
				double songProgress = (((double)(((Long)arg3.get("mp3.position.byte")) * 100)) /
						currentSongSize);
				slider.setValue((int)songProgress);
			}
		}
		public void opened(Object arg0, Map arg1){}
		public void stateUpdated(BasicPlayerEvent arg0){}
		public void setController(BasicController arg0){}
	};
	
	private static long currentSongSize;
	private static BasicPlayer currentPlayer;
	private static JPanel playerPanel;
	private static AsynchronousWrapper currentWrapper;
	
	static
	{
		playerPanel = new PlayerPanel();
	}
	public MusicPlayer()
	{
		super();
	}
	/*
	public static void setTempo(float speed)
	{
		if(musicPlayer != null)
		{
			musicPlayer.setRate(speed);
		}
	}
	public static void breakPlay()
	{
		if(musicPlayer != null)
		{
			timeAtBreak = musicPlayer.getMediaTime();
			musicPlayer.stop();
		}
	}
	public static void resumePlay()
	{
		if(musicPlayer != null && timeAtBreak != null)
		{
			musicPlayer.setMediaTime(timeAtBreak);
			musicPlayer.start();
		}
	}*/
	public static void stopPlay()
	{
		try
		{
			if(currentWrapper != null)
				currentWrapper.close();
			if(currentPlayer != null)
				currentPlayer.stop();
			currentSongSize = 0L;
		}
		catch (BasicPlayerException e)
		{
			e.printStackTrace();
		}
	}

	public static JPanel getPlayerPanel()
	{
		return(playerPanel);
	}

	public static void playEntry(String entryName)
	{
		ZipFile zipFile = Zipholder.getZipFile();
		ZipEntry entry = zipFile.getEntry(entryName);
		currentSongSize = entry.getSize();

		if(currentPlayer != null)
			stopPlay();

		try
		{
			currentWrapper = new AsynchronousWrapper(zipFile.getInputStream(entry),
					WRAPPLER_BUFFER_SIZE);
			
			currentPlayer = new BasicPlayer();
			currentPlayer.addBasicPlayerListener(LISTENER);
			currentPlayer.open(currentWrapper);
			currentPlayer.play();
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
		catch(BasicPlayerException e)
		{
			e.printStackTrace();
		}
	}
}

Nur wenn ich versuche nach dem ersten Lied ein 2. abzuspielen, fliegt mir eine EOFException. Und das verstehe ich nicht ganz. Keine der Variablen ist ja statisch, und ich erstelle jetzt jedes mal vollkommen neue Instanzen.
 

Neue Beiträge

Zurück