2014-04-09 102 views
3

這是我的第一篇文章在這裏。我目前正在使用Apache-Karaf 3.0.0在Scala上開發一個簡單的http音頻servlet。我將它作爲一個特性從一些bundle中部署,我使用maven項目來構建它。我使用'javax.sound.sampled'庫來獲取音頻,並使用'java.io.File'從AudioSystem加載文件。OSGi卡拉夫斯卡拉UnsupportedAudioFileException

val file = new File("audioFile.wav") 
    val audioStream = AudioSystem.getAudioInputStream(file) 

這顯然不是實際的代碼,因爲我已經刪除了所有的瑣碎的位。但是這是'getAudioInputStream'調用失敗的地方。

當我將這段代碼部署到Karaf時,它以'UnsupportedAudioFileException'失敗。該文件確實存在,並且可讀,我已經驗證了這一點。另外,我確定這個代碼可以在下面運行。 - 斯卡拉2.10.2,2.10.3 - 的Java 1.7.0_45(這是相同的JRE我的Karaf程序正在使用) - SBT 0.12.4(隨着不同版本的Scala)

只有這個地方當我將它部署到Karaf時失敗。我不知道Karaf是否已經刪除了一些隨機音頻支持,或者發生了什麼事情,因爲在通過SBT或使用Scala命令行進行部署時,此功能無法正常工作。我也研究過其他庫,但無濟於事。大多數其他解決方案似乎都基於實際通過聲音驅動程序播放音頻,這對我來說毫無用處。我需要實際的字節數據。

另外,請記住,發送文件也是沒用的我。另一個要求是我需要能夠將多個音頻文件合併到一個無縫音頻流中。我已經完成了,我只需要將它移植到OSGi,出於某種原因,我現在得到這個錯誤。我不知道Karaf是否與它有關,或者如果我通過Maven項目構建它已經破壞了某些東西。我環顧四周,發現問題的可能性很小。

我正在使用的音頻文件是波形音頻。 8,000個採樣率,每個採樣16位。我不認爲這實際上會有所作爲,但我不是音頻格式方面的專家。

我的pom.xml依賴關係如下。我使用的唯一插件是Scala編譯器,當然,我的根目錄pom.xml使用的是org.apache.felix maven-bundle-plugin。這裏真的沒有什麼魔法了,但神祕仍然存在。

<dependency> 
     <groupId>org.scala-lang</groupId> 
     <artifactId>scala-library</artifactId> 
     <version>2.10.3</version> 
    </dependency> 
    <dependency> 
     <groupId>javax.servlet</groupId> 
     <artifactId>servlet-api</artifactId> 
     <version>2.5</version> 
    </dependency> 

任何線索將不勝感激,謝謝。

回答

3

我認爲AudioSystem沒有完全準備好OSGi。這是我在白羊座間諜飛行中發現的。 不知道你到底需要做什麼才能使其工作,但這可能會有所幫助。

https://aries.apache.org/modules/spi-fly.html

特殊情況

SPI粉煤灰可以用於使用該TCCL圖案,以獲得實現最SPI提供商/查找系統。但是在某些情況下,需要一些特殊的處理。當API本身與META-INF/services中的資源名稱不匹配時,通常需要這種特殊處理,java.util.ServiceLoader就是這種情況,但是SPI-Fly具有內置的ServiceLoader知識。下面列出了需要特殊處理的已知API:

javax.sound.sampled.AudioSystem:此類使用封面下的sun.misc.Service(通過com.sun.media.sound.JDK13Services),它是java.util.ServiceLoader。在SPI Fly(yet)中沒有針對sun.misc.Service的特殊處理,但是可以通過將AudioSystem.getAudioInputStream()API顯式列入提供程序包(包含相關META-INF /服務資源):SPI-Provider:消費者端的javax.sound.sampled.AudioSystem,您可以使用SPI-Consumer:javax.sound.sampled.AudioSystem#getAudioInputStream

+0

啊!我一定會仔細研究一下。非常感謝你。所有這些對我來說還是很新的。 – TCooper

1

Christian的答案是正確的,但我想提供更新鏈接到spifly文檔頁面。具體做法是:

Java的java.util.ServiceLoader.load(),其他類似的方法,如 sun.misc.Service.providers(),並且也其他靜態finder方法例如 作爲FactoryFinder.find()方法嘗試通過查找線程上下文類加載器 (TCCL)可見的所有jar的META-INF/services 目錄中的資源來找到'服務'實現。

有在 OSGi的使用時許多與上述機制的問題:

  1. 線程上下文ClassLoader未在一般定義在OSGi上下文。它可以並且必須由調用者設置,並且OSGi不能通過 來強制執行該操作。
  2. 捆綁包不能導入包META-INF /服務作爲潛在的許多捆綁包將包含此僞包,並且OSGi框架 將只綁定一個導出器到給定包的導入器。
  3. 實例化一個SPI提供程序通常需要訪問內部實現類,通過導出這些類 實現bundle會破壞其封裝。
  4. 即使導出實現類,將該類導入到使用者包中也會將其綁定到提供的包的特定實現 ,這違反了鬆散耦合的原則。
  5. 軟件包具有動態生命週期,這意味着在更新或卸載軟件包時提供的服務可能會消失。 java.util.ServiceLoader API不提供通知 此類事件的服務使用者的機制。

SPI Fly項目可以使用OSGi下使用 ServiceLoader.load()和類似的機制的現有代碼。


請注意,爲的com.googlecode.soundlibs文物2016年5月20日的新版本被上傳到Maven的中央存儲庫。這些工件的新版本是合適的OSGi捆綁包。這將有助於大家誰需要使用OSGi容器

內的Java聲音API我創建了一個simple example project on github演示如何播放MP3文件使用Java API的聲音OSGi容器內。檢查分支static-weavingdynamic-weaving以查看相應的解決方案。