我前天寫了一篇文章,是關于播放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的已連接的播放設備
在此分享一下,希望對有此問題的朋友有一些幫助
盡管千里冰封
依然擁有晴空
你我共同品味JAVA的濃香.
posted on 2007-09-24 09:29
千里冰封 閱讀(1216)
評論(2) 編輯 收藏 所屬分類:
JAVASE