一个简单的音频播放器 :: 【Lunar eclipse月蚀】

来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=286970 存档链接: https://web.archive.org/web/20040906231018id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=286970


【Lunar eclipse月蚀】 <<<java.blogs daily update | 首页 | 使你迅速可以成为java高手...>>> 一个简单的音频播放器 一个简单的音频播放器(漂亮的界面,含全部源码,共3个类)给点 class : BasicPlayer package player1; import java.io.; import java.util.; import java.net.URL; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; import javax.sound.sampled.FloatControl; import javax.sound.sampled.Control; public class BasicPlayer implements Runnable { private static final int EXTERNAL_BUFFER_SIZE = 4000 * 4; private Thread m_thread = null; private Object m_dataSource; private AudioInputStream m_audioInputStream; private AudioFileFormat m_audioFileFormat; private SourceDataLine m_line; private FloatControl m_gainControl; private FloatControl m_panControl; /**

  • These variables are used to distinguish stopped, paused, playing states.
  • We need them to control Thread. / private static final int PLAYING = 0; private static final int PAUSED = 1; private static final int STOPPED = 2; private static final int READY = 3; private int m_status = READY; private long doSeek = -1; private File _file = null; private boolean ifPaused = false; private BasicPlayerListener m_bpl = null; /*
  • Constructs a Basic Player. / public BasicPlayer() { m_dataSource = null; m_audioInputStream = null; m_audioFileFormat = null; m_line = null; m_gainControl = null; m_panControl = null; } /*
  • Constructs a Basic Player with a BasicPlayerListener. / public BasicPlayer(BasicPlayerListener bpl) { this(); m_bpl = bpl; } /*
  • Sets the data source as a file. / protected void setDataSource(File file) throws UnsupportedAudioFileException, LineUnavailableException, IOException { if (file != null) { m_dataSource = file; initAudioInputStream(); } } /*
  • Sets the data source as an url. / protected void setDataSource(URL url) throws UnsupportedAudioFileException, LineUnavailableException, IOException { if (url != null) { m_dataSource = url; initAudioInputStream(); } } /*
  • Inits Audio ressources from the data source.
    • AudioInputStream
    • AudioFileFormat / private void initAudioInputStream() throws UnsupportedAudioFileException, LineUnavailableException, IOException { if (m_dataSource instanceof URL) { initAudioInputStream( (URL) m_dataSource); } else if (m_dataSource instanceof File) { initAudioInputStream( (File) m_dataSource); } } /*
  • Inits Audio ressources from file. / private void initAudioInputStream(File file) throws UnsupportedAudioFileException, IOException { _file = file; m_audioInputStream = AudioSystem.getAudioInputStream(file); m_audioFileFormat = AudioSystem.getAudioFileFormat(file); } /*
  • Inits Audio ressources from URL. / private void initAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException { m_audioInputStream = AudioSystem.getAudioInputStream(url); m_audioFileFormat = AudioSystem.getAudioFileFormat(url); } /*
  • Inits Audio ressources from AudioSystem.
  • DateSource must be present. / protected void initLine() throws LineUnavailableException { if (m_line == null) { createLine(); openLine(); } else { AudioFormat lineAudioFormat = m_line.getFormat(); AudioFormat audioInputStreamFormat = m_audioInputStream == null ? null : m_audioInputStream.getFormat(); if (!lineAudioFormat.equals(audioInputStreamFormat)) { m_line.close(); openLine(); } } } /*
  • Inits a DateLine.
  • We check if the line supports Volume and Pan controls.
  • From the AudioInputStream, i.e. from the sound file, we
  • fetch information about the format of the audio data. These
  • information include the sampling frequency, the number of
  • channels and the size of the samples. There information
  • are needed to ask JavaSound for a suitable output line
  • for this audio file.
  • Furthermore, we have to give JavaSound a hint about how
  • big the internal buffer for the line should be. Here,
  • we say AudioSystem.NOT_SPECIFIED, signaling that we don´t
  • care about the exact size. JavaSound will use some default
  • value for the buffer size. / private void createLine() throws LineUnavailableException { if (m_line == null) { AudioFormat sourceFormat = m_audioInputStream.getFormat(); AudioFormat targetFormat = new AudioFormat(AudioFormat.Encoding. PCM_SIGNED, sourceFormat.getSampleRate(), 16, sourceFormat.getChannels(), sourceFormat.getChannels() * 2, sourceFormat.getSampleRate(), false); m_audioInputStream = AudioSystem.getAudioInputStream(targetFormat, m_audioInputStream); AudioFormat audioFormat = m_audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, AudioSystem.NOT_SPECIFIED); m_line = (SourceDataLine) AudioSystem.getLine(info); /-- Display supported controls --/ Control[] c = m_line.getControls(); for (int p = 0; p < c.length; p++) { } /-- Is Gain Control supported ? --/ if (m_line.isControlSupported(FloatControl.Type.MASTER_GAIN)) { m_gainControl = (FloatControl) m_line.getControl(FloatControl.Type. MASTER_GAIN); } /-- Is Pan control supported ? --*/ if (m_line.isControlSupported(FloatControl.Type.PAN)) { m_panControl = (FloatControl) m_line.getControl(FloatControl.Type.PAN); } } } /**
  • Opens the line. / private void openLine() throws LineUnavailableException { if (m_line != null) { AudioFormat audioFormat = m_audioInputStream.getFormat(); m_line.open(audioFormat, m_line.getBufferSize()); } } /*
  • Stops the playback.
  • Player Status = STOPPED.
  • Thread should free Audio ressources. / protected void stopPlayback() { if ( (m_status == PLAYING) || (m_status == PAUSED)) { if (m_line != null) { m_line.flush(); m_line.stop(); ifPaused=false; } m_status = STOPPED; } } /*
  • Pauses the playback.
  • Player Status = PAUSED. / public void pausePlayback() { if (m_line != null) { if (m_status == PLAYING) { m_line.flush(); m_line.stop(); m_status = PAUSED; ifPaused=true; } } } /*
  • Resumes the playback.
  • Player Status = PLAYING. / public void resumePlayback() { if (m_line != null) { if (m_status == PAUSED) { m_line.start(); m_status = PLAYING; ifPaused=false; } } } /*
  • Starts playback. / public String startPlayback() { if ( (m_status == STOPPED) || (m_status == READY)) { if (! (m_thread == null || !m_thread.isAlive())) { while (m_status != READY) { try { if (m_thread != null) { m_thread.sleep(1000); } } catch (Exception e) { } } } try { initLine(); } catch (Exception e) { //e.printStackTrace(); return "ERROR"; } m_thread = new Thread(this); m_thread.start(); if (m_line != null) { m_line.start(); ifPaused=false; } } return null; } /*
  • Main loop.
  • Player Status == STOPPED => End of Thread + Freeing Audio Ressources.
  • Player Status == PLAYING => Audio stream data sent to Audio line.
  • Player Status == PAUSED => Waiting for another status. / public void run() { if (m_audioInputStream.markSupported()) m_audioInputStream.mark(m_audioFileFormat.getByteLength()); int nBytesRead = 1; m_status = PLAYING; int nBytesCursor = 0; byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; float nFrameSize = (float) m_line.getFormat().getFrameSize(); float nFrameRate = m_line.getFormat().getFrameRate(); float bytesPerSecond = nFrameSize * nFrameRate; int secondsTotal = Math.round( (float) m_audioFileFormat.getByteLength() / bytesPerSecond); while ( (nBytesRead != -1) && (m_status != STOPPED)) { if (m_status == PLAYING) { try { // Seek implementation. if (doSeek > -1) { if ( (secondsTotal != AudioSystem.NOT_SPECIFIED) && (secondsTotal > 0)) { m_line.flush(); m_line.stop(); //m_audioInputStream.reset(); m_audioInputStream.close(); m_audioInputStream = AudioSystem.getAudioInputStream(_file); nBytesCursor = 0; if (m_audioFileFormat.getByteLength() - doSeek < abData.length) { doSeek = m_audioFileFormat.getByteLength() - abData.length; } doSeek = doSeek - doSeek % 4; int toSkip = (int) doSeek; // skip(...) instead of read(...) runs out of memory ?! while ( (toSkip > 0) && (nBytesRead > 0)) { if (toSkip > abData.length) { nBytesRead = m_audioInputStream.read(abData, 0, abData.length); } else { nBytesRead = m_audioInputStream.read(abData, 0, toSkip); } toSkip = toSkip - nBytesRead; nBytesCursor = nBytesCursor + nBytesRead; } m_line.start(); } else { } doSeek = -1; } nBytesRead = m_audioInputStream.read(abData, 0, abData.length); } catch (Exception e) { } if (nBytesRead >= 0) { if (m_bpl != null) { m_bpl.updateMediaData(abData); } int nBytesWritten = m_line.write(abData, 0, nBytesRead); nBytesCursor = nBytesCursor + nBytesWritten; if (m_bpl != null) { m_bpl.updateCursor( (int) Math.round( (float) nBytesCursor / bytesPerSecond), secondsTotal); } } } else { try { Thread.sleep(1000); } catch (Exception e) { } } } if (m_line != null) { try { m_line.drain(); m_line.stop(); m_line.close(); } catch (Exception e) { } finally { m_line = null; } } m_status = READY; if (m_bpl != null) { m_bpl.updateMediaState("EOM"); } } /----------------------------------------------/ /-- Gain Control --/ /----------------------------------------------*/ /**
  • Returns true if Gain control is supported. / public boolean hasGainControl() { return m_gainControl != null; } /*
  • Sets Gain value.
  • Linear scale 0.0 <--> 1.0
  • Threshold Coef. : 1/2 to avoid saturation. / public void setGain(double fGain) { if (hasGainControl()) { double minGainDB = getMinimum(); double ampGainDB = ( (10.0f / 20.0f) * getMaximum()) - getMinimum(); double cste = Math.log(10.0) / 20; double valueDB = minGainDB + (1 / cste) * Math.log(1 + (Math.exp(cste * ampGainDB) - 1) * fGain); //trace(1,getClass().getName(), "Gain : "+valueDB); m_gainControl.setValue( (float) valueDB); } } /*
  • Returns Gain value. / public float getGain() { if (hasGainControl()) { return m_gainControl.getValue(); } else { return 0.0F; } } /*
  • Gets max Gain value. / public float getMaximum() { if (hasGainControl()) { return m_gainControl.getMaximum(); } else { return 0.0F; } } /*
  • Gets min Gain value. / public float getMinimum() { if (hasGainControl()) { return m_gainControl.getMinimum(); } else { return 0.0F; } } /----------------------------------------------/ /-- Pan Control --/ /----------------------------------------------*/ /**
  • Returns true if Pan control is supported. / public boolean hasPanControl() { return m_panControl != null; } /*
  • Returns Pan precision. / public float getPrecision() { if (hasPanControl()) { return m_panControl.getPrecision(); } else { return 0.0F; } } /*
  • Returns Pan value. / public float getPan() { if (hasPanControl()) { return m_panControl.getValue(); } else { return 0.0F; } } /*
  • Sets Pan value.
  • Linear scale : -1.0 <--> +1.0 / public void setPan(float fPan) { if (hasPanControl()) { //trace(1,getClass().getName(), "Pan : "+fPan); m_panControl.setValue(fPan); } } /----------------------------------------------/ /-- Seek --/ /----------------------------------------------*/ /**
  • Sets Seek value.
  • Linear scale : 0.0 <--> +1.0 / public void setSeek(double seek) throws IOException { double length = -1; if ( (m_audioFileFormat != null) && (m_audioFileFormat.getByteLength() != AudioSystem.NOT_SPECIFIED)) { length = (double) m_audioFileFormat.getByteLength(); } long newPos = (long) Math.round(seek * length); doSeek = newPos; } /----------------------------------------------/ /-- Audio Format --/ /----------------------------------------------*/ /**
  • Returns AudioFormat. / public AudioFormat getAudioFormat() { if (m_audioInputStream != null) { return m_audioInputStream.getFormat(); } else { return null; } } /*
  • Returns AudioFileFormat. / public AudioFileFormat getAudioFileFormat() { if (m_audioFileFormat != null) { return m_audioFileFormat; } else { return null; } } /*
  • Gets an InputStream from File. */ protected InputStream openInput(File file) throws IOException { InputStream fileIn = new FileInputStream(file); BufferedInputStream bufIn = new BufferedInputStream(fileIn); return bufIn; } public void ready(File f){ try { openInput(f); setDataSource(f); } catch (IOException ex1) { } catch (LineUnavailableException ex1) { } catch (UnsupportedAudioFileException ex1) { } } public boolean ifPaused(){ return ifPaused; } } a-ben 发表于 2004-07-26 11:01 引用Trackback(0) | 编辑 JAVA 下载 突然的哭泣!!!! 这里提供一些Java资源。 Java咖啡馆06――编写猜数字游戏 java.blogs daily update... 周杰伦<七里香>听 最热门的十篇Java相关文章 java.blogs daily update java.blogs daily update java.blogs daily update ★ 在线翻译 ★ 游戏。。。。 ◆ GRO ◆ GRO/JDK在线源代码.... ★ 超强的JAVA API呀.... ◆ 中国软件CSDN ◇ CSDN/JAVA文档列表.... ◇ CSDN/杂志频道.... ◇ CSDN/IBM技术中心.... ◇ CDSN/技术中心.... ◇ CSDN/程序热门讨论.... ◇ CSDN/JAVA社区..... ◆ SUN公司 ◇ SUN/JAVA技术论坛 ◆ 微软中国 ◇ 微软中国全球技术中心 ◆ 程序员之家 ◇ 免费Java教学视频 ◆ JAVA咖啡屋.... ◆ ChinaJavaWorld技术论坛 ◆ 中国JAVA俱乐部 ◆ JAVA中文网/JAVA-CN ◇ JAVA-CN/技术文摘库.... ◇ JAVA-CN/JSP语法简表 ◇ JAVA-CN/JAVA简史.... ◇ JAVA-CN/动画制作工具.... ◆ 网络社团.... ◇ 网络社团/技术文档.... ◆ Jcreator下载.... ◆ IrfanView....