JMF和MIDI冲突的解决办法

原创 2007年09月25日 09:43:00
我前天写了一篇文章,是关于播放MIDI音乐的,可是看到留言却发现,我那段代码在他的电脑上竟然播不出声音来,这个时候我想,是不是我的电脑不正常,因为我看到网上的例子,得到播放器都是通过这种方法得到的,MidiSystem.getSequencer(),而我用这种方法却会抛出异常,无奈,我只好退而求其次了,用了这个方法,MidiSystem.getSequencer(false),得到一个看似没有连接上设置的MIDI播放器,可是在我的电脑上却能播.于是我就输出我电脑上所有的MIDI设置,代码如下:

MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
for (MidiDevice.Info info : infos) {
System.out.println(info);
MidiDevice device = MidiSystem.getMidiDevice(info);
System.out.println("device=" + device);
System.out.println("is Sequencer?" + (device instanceof Sequencer));
System.out.println("is Synthesizer? " + (device instanceof Synthesizer));
System.out.println("info.name=" + info.getName());
System.out.println("info.vendor=" + info.getVendor());
System.out.println("info.description=" + info.getDescription());
System.out.println("info.toString=" + info.toString());
System.out.println("------------------------------------");

}

输出如下:

Java Sound Sequencer
device=com.sun.media.sound.MixerSequencer@f10c77
is Sequencer?true
is Synthesizer? false
info.name=Java Sound Sequencer
info.vendor=Sun Microsystems
info.description=Software sequencer / synthesizer module
info.toString=Java Sound Sequencer
------------------------------------
Microsoft MIDI ???±
device=com.sun.media.sound.MidiOutDevice@dee55c
is Sequencer?false
is Synthesizer? false
info.name=Microsoft MIDI ???±
info.vendor=Unknown vendor
info.description=Windows MIDI_MAPPER
info.toString=Microsoft MIDI ???±
------------------------------------
Microsoft GS ?¨±í?í??
device=com.sun.media.sound.MidiOutDevice@1a3fb76
is Sequencer?false
is Synthesizer? false
info.name=Microsoft GS ?¨±í?í??
info.vendor=Unknown vendor
info.description=Internal software synthesizer
info.toString=Microsoft GS ?¨±í?í??
------------------------------------
Real Time Sequencer
device=com.sun.media.sound.RealTimeSequencer@76a6d9
is Sequencer?true
is Synthesizer? false
info.name=Real Time Sequencer
info.vendor=Sun Microsystems
info.description=Software sequencer
info.toString=Real Time Sequencer
------------------------------------
Java Sound Synthesizer
device=com.sun.media.sound.MixerSynth@1c42c4b
is Sequencer?false
is Synthesizer? true
info.name=Java Sound Synthesizer
info.vendor=Sun Microsystems
info.description=Software wavetable synthesizer and receiver
info.toString=Java Sound Synthesizer
------------------------------------

  注意上第一个输出,Java Sound Sequencer,这个设备是另外一台电脑所没有的,这个设备是装了JMF以后才有的,后来我试着把JMF卸载了,发现这个设备没了,并且我用MidiSystem.getSequencer()得到的播放器也能用了,也不用MidiSystem.getSequencer(false)了,并且MidiSystem.getSequencer(false)之后,也会出现没有声音的情况.所以我断定一定是JMF搞的鬼了.可是怎么办呢,总不可能不让别人装JMF吧,并且JMF也是多媒体播放的,我们这个工程也是要播放视频的,没有JMF怎么播放视频,怎样让JMF和MIDI能共存呢?后来我在MidiSystem.getSequencer()的API上看到如下几句话:

public static Sequencer getSequencer()
throws MidiUnavailableException

  获得连接到默认设备上的默认的 Sequencer。返回的 Sequencer 实例连接到默认的 Synthesizer,如同由 getSynthesizer() 返回的结果。如果没有可用的 Synthesizer,或者默认的 Synthesizer 无法打开,则 sequencer 会连接到默认的 Receiver,如同由 getReceiver() 返回的结果。该连接是通过从 Sequencer 检索 Transmitter 实例并设置其 Receiver 来建立的。关闭和重新打开 sequencer 将恢复到默认设备的连接。
此方法等效于调用 getSequencer(true)。

  如果定义了系统属性 javax.sound.midi.Sequencer,或者在文件 "sound.properties" 中定义了该属性,则它可用于标识默认的 sequencer。有关详细信息,请参阅类描述。

  返回:
  连接到默认 Receiver 上的默认 sequencer
  抛出:
  MidiUnavailableException - 如果由于资源限制使 sequencer 不可用,或者任何已安装的 MidiDevice 上都没有可用的 Receiver,或者系统中未安装 sequencer。

  现在可以肯定的是,JMF改变了我的系统默认属性,把Java Sound Sequencer当做默认设备了,本来默认设备是:Real Time Sequencer,后来我就在jre/lib文件夹下面找到了sound.properties文件,把里面的 javax.sound.midi.Sequencer项的注释去掉,改为javax.sound.midi.Sequencer=com.sun.media.sound.RealTimeSequencerProvider ,不过,还有一样更简便的方法.那就是在程序初始化的时候加上如下代码:System.setProperty("javax.sound.midi.Sequencer","com.sun.media.sound.RealTimeSequencerProvider"); 把这个属性设为系统属性也有同样的效果,这样编码在程序里面更好一些,因为我们总不可能让用户去改他们的sound.properties文件吧.

呵呵,一切都好了,就像没有装JMF一样,代码依然用
Sequencer midi=MidiSystem.getSequencer();
来获取MIDI的已连接的播放设备 

VC++6.0与office冲突的解决办法

  • 2013年12月16日 16:58
  • 540KB
  • 下载

Cadence16.3和PADS_9.2冲突解决办法

  • 2013年09月16日 21:55
  • 7KB
  • 下载

下拉刷新和图片轮播控件事件冲突之解决办法(达到和淘宝京东同样的效果)

下拉刷新和图片轮播控件事件冲突之解决办法最近想在项目中同时使用这两种控件:1、android-Ultra-Pull-To-Refresh(下拉刷新) 项目地址:https://github.com/...
  • drg1612
  • drg1612
  • 2015年11月11日 14:46
  • 5582

shiro与Druid冲突导致"Session already invalidated"异常及其解决办法

在controller中调用subject.logout()注销登录时会抛出如下异常: java.lang.IllegalStateException: getAttribute: Session a...

vc和offic2007冲突解决办法

  • 2010年11月12日 00:05
  • 19KB
  • 下载

ECSHOP中transport.js和jquery的冲突的简单解决办法

通用头部文件中引用了 {insert_scripts files='transport.js,utils.js'} transport.js与jquery有冲突。原因不...

SVN冲突解决办法.

  • 2010年07月13日 18:40
  • 1KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JMF和MIDI冲突的解决办法
举报原因:
原因补充:

(最多只允许输入30个字)