3

これは私の最初の投稿です。私は現在、Apache-Karaf 3.0.0 の Scala で単純な http オーディオ サーブレットに取り組んでいます。Mavenプロジェクトを使用して構築したいくつかのバンドル内から機能として展開しています。「javax.sound.sampled」ライブラリを使用してオーディオを取得し、AudioSystem から「java.io.File」でファイルをロードしています。

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

これは明らかに実際のコードではありません。些細な部分はすべて取り除いているからです。しかし、これは「getAudioInputStream」呼び出しで失敗する場所です。

このコードを Karaf にデプロイすると、「UnsupportedAudioFileException」で失敗します。ファイルは存在し、読み取り可能です。これは既に検証済みです。また、このコードが以下で実行できることを確認しました。- Scala 2.10.2、2.10.3 - Java 1.7.0_45 (これは、私の Karaf プログラムが使用している JRE と同じです) - SBT 0.12.4 (異なる Scala バージョンを使用)

これが失敗する唯一の場所は、Karaf にデプロイするときです。Karaf がランダムなオーディオ サポートを削除したかどうか、または何が起こっているかはわかりません。それ以外の場合は、SBT または Scala コマンド ラインを使用して展開したときに機能するためです。代替ライブラリも調べましたが、役に立ちませんでした。他のほとんどのソリューションは、サウンドドライバーを介して実際にオーディオを再生することに基づいているようですが、これは私には役に立ちません。実際のバイトデータが必要です。

また、ファイルを送信するだけでは役に立たないことにも注意してください。もう 1 つの要件は、複数のオーディオ ファイルを 1 つのシームレスなオーディオ ストリームにマージできる必要があることです。私はすでにこれを行っています.OSGiに移植する必要があるだけですが、何らかの理由でこのエラーが発生しています. Karaf が関係しているのか、それとも Maven プロジェクトでビルドしたときに何かが壊れたのかはわかりません。私は周りを見回しましたが、問題がどこにあるのかについてのヒントはほとんど見つかりませんでした.

私が使用しているオーディオ ファイルは、Waveform オーディオです。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>

どんな手がかりでも大歓迎です、ありがとう。

4

2 に答える 2

3

AudioSystem は完全には OSGi に対応していないと思います。これは、Aries Spy Fly のドキュメントで見つけたものです。それを機能させるために正確に何をしなければならないかはわかりませんが、これは役立つかもしれません。

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

特殊なケース

SPI Fly は、TCCL パターンを使用して実装を取得するほとんどの SPI プロバイダー/ルックアップ システムに使用できます。ただし、場合によっては、特別な治療が必要です。この特別な処理は、API 自体が META-INF/services 内のリソースの名前と一致しない場合によく必要になります。java.util.ServiceLoader はそのようなケースですが、SPI-Fly には ServiceLoader の知識が組み込まれています。特別な処理が必要な既知の API を以下に示します。

javax.sound.sampled.AudioSystem: このクラスは、java.util.ServiceLoader の前身である (com.sun.media.sound.JDK13Services を介して) 内部で sun.misc.Service を使用します。SPI Fly には (まだ) sun.misc.Service に対する特別な処理はありませんが、AudioSystem.getAudioInputStream() API は、プロバイダー バンドル (関連する META-INF/サービス リソース): SPI-Provider: javax.sound.sampled.AudioSystem コンシューマー側で使用できる SPI-Consumer: javax.sound.sampled.AudioSystem#getAudioInputStream

于 2014-04-09T22:34:14.150 に答える
1

クリスチャンの答えは正しいですが、 spiflyのドキュメント ページへの更新されたリンクを提供したかったのです。具体的には:

Java の java.util.ServiceLoader.load()、sun.misc.Service.providers() などの他の同様のメソッド、および FactoryFinder.find() メソッドなどの他の静的ファインダ メソッドは、「サービス」実装を探すことによって見つけようとします。 Thread Context ClassLoader (TCCL) に表示されるすべての jar の META-INF/services ディレクトリ内のリソース。

OSGi で使用する場合、上記のメカニズムにはいくつかの問題があります。

  1. Thread Context ClassLoader は、一般に OSGi コンテキストでは定義されません。これは呼び出し元が設定できますし、設定する必要がありますが、OSGi では一般にそれを強制することはできません。
  2. 潜在的に多くのバンドルにこの疑似パッケージが含まれ、OSGi フレームワークは特定のパッケージのインポーターに 1 つのエクスポーターのみをバインドするため、バンドルは META-INF/services を Import-Package META-INF/services できません。
  3. 通常、SPI プロバイダーをインスタンス化するには、内部実装クラスへのアクセスが必要です。これらのクラスをエクスポートすると、実装バンドルがそのカプセル化を解除します。
  4. 実装クラスがエクスポートされた場合でも、このクラスをコンシューマ バンドルにインポートすると、提供された特定の実装パッケージにバインドされ、疎結合の原則に違反します。
  5. バンドルには動的なライフサイクルがあります。つまり、バンドルが更新またはアンインストールされると、提供されたサービスが消える可能性があります。java.util.ServiceLoader API は、サービス コンシューマにそのようなイベントを通知するメカニズムを提供しません。

SPI Fly プロジェクトは、OSGi の下で ServiceLoader.load() および同様のメカニズムを使用する既存のコードを使用できるようにします。


com.googlecode.soundlibs2016 年 5 月 20 日の時点で、アーティファクトの新しいバージョンが Maven 中央リポジトリにアップロードされていることに注意してください。これらのアーティファクトの新しいバージョンは、適切な OSGi バンドルです。これは、OSGi コンテナー内で Java Sound API を使用する必要があるすべての人に役立ちます。

Java Sound API を使用して OSGi コンテナー内で MP3 ファイルを再生する方法を示す簡単なサンプル プロジェクトを githubで作成しました。ブランチstatic-weavingをチェックアウトしdynamic-weavingて、それぞれのソリューションを確認してください。

于 2016-06-01T06:41:46.980 に答える