javazoom.jl.player.Player Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jlayer Show documentation
Show all versions of jlayer Show documentation
Maven artifact for JLayer library. http://www.javazoom.net/javalayer/sources.html
/*
* 11/19/04 1.0 moved to LGPL.
* 29/01/00 Initial version. [email protected]
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.player;
import java.io.InputStream;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.decoder.SampleBuffer;
/**
* The Player
class implements a simple player for playback
* of an MPEG audio stream.
*
* @author Mat McGowan
* @since 0.0.8
*/
// REVIEW: the audio device should not be opened until the
// first MPEG audio frame has been decoded.
public class Player
{
/**
* The current frame number.
*/
private int frame = 0;
/**
* The MPEG audio bitstream.
*/
// javac blank final bug.
/*final*/ private Bitstream bitstream;
/**
* The MPEG audio decoder.
*/
/*final*/ private Decoder decoder;
/**
* The AudioDevice the audio samples are written to.
*/
private AudioDevice audio;
/**
* Has the player been closed?
*/
private boolean closed = false;
/**
* Has the player played back all frames from the stream?
*/
private boolean complete = false;
private int lastPosition = 0;
/**
* Creates a new Player
instance.
*/
public Player(InputStream stream) throws JavaLayerException
{
this(stream, null);
}
public Player(InputStream stream, AudioDevice device) throws JavaLayerException
{
bitstream = new Bitstream(stream);
decoder = new Decoder();
if (device!=null)
{
audio = device;
}
else
{
FactoryRegistry r = FactoryRegistry.systemRegistry();
audio = r.createAudioDevice();
}
audio.open(decoder);
}
public void play() throws JavaLayerException
{
play(Integer.MAX_VALUE);
}
/**
* Plays a number of MPEG audio frames.
*
* @param frames The number of frames to play.
* @return true if the last frame was played, or false if there are
* more frames.
*/
public boolean play(int frames) throws JavaLayerException
{
boolean ret = true;
while (frames-- > 0 && ret)
{
ret = decodeFrame();
}
if (!ret)
{
// last frame, ensure all data flushed to the audio device.
AudioDevice out = audio;
if (out!=null)
{
out.flush();
synchronized (this)
{
complete = (!closed);
close();
}
}
}
return ret;
}
/**
* Cloases this player. Any audio currently playing is stopped
* immediately.
*/
public synchronized void close()
{
AudioDevice out = audio;
if (out!=null)
{
closed = true;
audio = null;
// this may fail, so ensure object state is set up before
// calling this method.
out.close();
lastPosition = out.getPosition();
try
{
bitstream.close();
}
catch (BitstreamException ex)
{
}
}
}
/**
* Returns the completed status of this player.
*
* @return true if all available MPEG audio frames have been
* decoded, or false otherwise.
*/
public synchronized boolean isComplete()
{
return complete;
}
/**
* Retrieves the position in milliseconds of the current audio
* sample being played. This method delegates to the
* AudioDevice
that is used by this player to sound
* the decoded audio samples.
*/
public int getPosition()
{
int position = lastPosition;
AudioDevice out = audio;
if (out!=null)
{
position = out.getPosition();
}
return position;
}
/**
* Decodes a single frame.
*
* @return true if there are no more frames to decode, false otherwise.
*/
protected boolean decodeFrame() throws JavaLayerException
{
try
{
AudioDevice out = audio;
if (out==null)
return false;
Header h = bitstream.readFrame();
if (h==null)
return false;
// sample buffer set when decoder constructed
SampleBuffer output = (SampleBuffer)decoder.decodeFrame(h, bitstream);
synchronized (this)
{
out = audio;
if (out!=null)
{
out.write(output.getBuffer(), 0, output.getBufferLength());
}
}
bitstream.closeFrame();
}
catch (RuntimeException ex)
{
throw new JavaLayerException("Exception decoding audio frame", ex);
}
/*
catch (IOException ex)
{
System.out.println("exception decoding audio frame: "+ex);
return false;
}
catch (BitstreamException bitex)
{
System.out.println("exception decoding audio frame: "+bitex);
return false;
}
catch (DecoderException decex)
{
System.out.println("exception decoding audio frame: "+decex);
return false;
}
*/
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy