java 混频器播放pcm_java mp3播放器 ×××面

一、服务器端:

最近没有系统学习的计划,看了开源的YOYOPlayer(一个相当强大的播放器软件,基于java编写),心里痒痒,比较肤浅的学习下javasound。javasound是比较小巧的底层api,引用网上的一幅 javasound体系结构图:

javasound.gifjavasound实现: 目前使用最多的是 jdk中javax.sound组件 (包括javax.sound.sampled 和 javax.sound.midi包) 和 开源的 Tritonus(http://www.tritonus.org/)组件SPI:是Service Provider Interface(服务提供接口),它的作用是以插件的形式提供音频扩展模块。比如,javax.sound组件中,只支持au,mid,wav等少许音频格式,其中不包括mp3。要想支持mp3格式,那么就需要相应的×××和SPI。所幸的是,已经有相应的开源包。javazoom(http://www.javazoom.net)下的jlayer,是mp3格式的解码包。javazoom下的mp3spi就是spi。只要添加了相应的开源组建包,可以在不修改任何一行代码的情况下,支持其他音频格式。这就是spi的魅力。简单介绍了javasound的体系结构,下面就介绍一个简易的mp3播放器的实现(所谓简易,就是没有界面,除了能播放mp3等文件外,就啥都不能干了 :) )几个步骤:1)得到音频流:

AudioSystem.getAudioInputStream(input)

2)得到音频格式:

audioInputStream.getFormat()

3)初始化数据行信息数据行信息包括(受数据行支持的音频格式;其内部缓冲区的最小和最大大小 )

DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);

4)从混频器获得源数据行SourceDataLine接口提供将音频数据写入数据行的缓冲区中的方法。播放或混合音频的应用程序应该以足够快的速度将数据写入源数据行,以防缓冲区下溢(排空),下溢可能导致单击时音频数据中出现可感知的间断

SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);

5)将音频数据写入源数据行中

line.start();

int readLenth = 0;

while (readLenth != -1) {

readLenth = decodedAudioStream.read(AUDIO_BUFER, 0, AUDIO_BUFER.length);

if (readLenth != -1) {

line.write(AUDIO_BUFER, 0, readLenth);

}

}

line.drain();

line.stop();

line.close();

下面提供完整的简易mp3播放器代码:其中AudioPlayer仅仅是一个接口。

/*** 

 
 

* MP3播放器实现

* 线程不安全,没有必要多个线程去启动播放器

*

*@authorLee Jones*/

public class Mp3Player implements AudioPlayer {

private static final Log    log         = LogFactory.getLog(Mp3Player.class);

private static final byte[] AUDIO_BUFER = new byte[4096];

private AudioInputStream    audioStream;

private AudioFormat         decodedFormat;

private AudioInputStream    decodedAudioStream;

@Override

public void play(InputStream input) {

if (input == null) {

log.warn("input stream is null");

return;

}

try {

init(input);

play();

} catch (Exception e) {

log.error("play error:", e);

}

}

@Override

public void play(File file) {

if (file == null) {

log.warn("audio file is null");

return;

}

try {

play(new FileInputStream(file));

} catch (FileNotFoundException e) {

log.error("file to inputStream error:", e);

}

}

@Override

public void play(URL url) {

if (url == null) {

log.warn("url is null");

return;

}

try {

play(url.openStream());

} catch (IOException e) {

log.error("url open inputStream error:", e);

}

}

/*** init

*

*@paraminput

*@throwsUnsupportedAudioFileException

*@throwsIOException*/

protected void init(InputStream input) throws UnsupportedAudioFileException, IOException {

initAudioStream(input);

initDecodedFormat();

initDecodedAudioStream();

}

/*** init audio input stream

*

*@paraminput:audio input stream

*@throwsIOException

*@throwsUnsupportedAudioFileException*/

protected void initAudioStream(InputStream input) throws UnsupportedAudioFileException, IOException {

audioStream = AudioSystem.getAudioInputStream(input);

}

/*** init decoded format

*

*@throwsUnsupportedAudioFileException

*@throwsIOException*/

protected void initDecodedFormat() throws UnsupportedAudioFileException, IOException {

AudioFormat baseFormat = audioStream.getFormat();

decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,

baseFormat.getChannels(), baseFormat.getChannels() * 2,

baseFormat.getSampleRate(), false);

}

/*** init decoded audio stream*/

protected void initDecodedAudioStream() {

decodedAudioStream = AudioSystem.getAudioInputStream(decodedFormat, audioStream);

}

/*** get source data line

*

*@paraminput audio input stream

*@return*@throwsUnsupportedAudioFileException

*@throwsIOException

*@throwsLineUnavailableException*/

protected SourceDataLine getSourceDataLine() throws UnsupportedAudioFileException, IOException,

LineUnavailableException {

DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);

SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);

line.open(decodedFormat);

return line;

}

/*** play audio

*

*@throwsUnsupportedAudioFileException

*@throwsIOException

*@throwsLineUnavailableException*/

protected void play() throws UnsupportedAudioFileException, IOException, LineUnavailableException {

SourceDataLine line = getSourceDataLine();

line.start();

int readLenth = 0;

while (readLenth != -1) {

readLenth = decodedAudioStream.read(AUDIO_BUFER, 0, AUDIO_BUFER.length);

if (readLenth != -1) {

line.write(AUDIO_BUFER, 0, readLenth);

}

}

line.drain();

line.stop();

line.close();

decodedAudioStream.close();

audioStream.close();

}

}

自己写个main方法即可测试  啦啦啦......

public static void main(String[] args) {

Mp3Player mp3Player=new Mp3Player();

String sourcUrl="C:"+File.separator+"879_mp3.mp3";

File file=new File(sourcUrl);

mp3Player.play(file);

}

最后附上简易播放器:见附件

启动方式:linux用户使用./mp3player.sh,windows用户使用mp3player.bat启动(需要说明的是,必须设置好JAVA_HOME和PATH,并且使用jdk5以上版本。因为启动脚本中的指定classpath的方法需要jdk5版本以上才支持。如果是jdk1.4下的用户,请修改启动脚本)lib目录:是简易播放器的lib包支持log目录:记录log,如果有错误等情况,可查看log。conf目录:因为没有图形界面,所以需要把播放的mp3文件路径手工写入。支持两种形式,一个是本地mp3文件,另一个是网络mp3资源,分别写入到local.txt和net.txt文件中。比如local.txt

/home/jones/data/music/misc/xin_nian_hao.mp3

/home/jones/data/music/misc/guo_ge.mp3

net.txt

http://lubai.com.cn/CGI-BIN/shuanxing.mp3

http://lubai.com.cn/CGI-BIN/shuanxing.mp3

二、客户端:

这个URL直接返回你要说的话的MP3文件。播放就可以了。

html5:支持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值