17

アップデート:

JFXのメディア側はオープンソースであるため、私はこれを自分で調べました。それは確かに可能ですが、JFXソース(JavaとCの両方の部分)を変更して再構築する必要があります。試してみてください-その例ではMKVサポートを追加していますが、他のプラグインでも非常に似ているはずです。

したがって、質問の残りの部分は主に歴史的なものですが、参考のためにここに残しておきます。

バックグラウンド

私はこれまで、アプリケーションでビデオを再生するためにVLCJを使用してきました。動作しますが、可能であれば、JavaFXに移行し、VLCJが複数のビデオを確実に再生する必要があるなど、複数のVMで多くの手間を省くことで、一般的なコーデックに対して同様のレベルのサポートを実現できるかどうかを確認したいと思います。ここでは説明しませんが、詳細に興味がある場合は、この質問に対する私の回答を参照してください。クロスプラットフォームの互換性の問題もあります。MacとLinuxで動作しますが、Macで表示する方法はまだわかりません(あるプロセスが別のプロセスにアクセスするのを防ぐためのセキュリティが確保されていると思います)コンポーネントですが、これもこの質問の範囲を超えています。)

つまり、機能している間は多くのメンテナンスが必要であり、複数のVMを操作して、より簡単な別のソリューションがある場合はそれらを安定してブリッジするのは面倒です。VLCには、ほとんどすべてのものを再生するためのかなり伝説的なレベルのサポートがあります。そのため、これまでにVLCを使用してきました。また、JavaFXで同様の結果が得られるかどうか、または少なくとも可能かどうかを確認したいと思います。クロスプラットフォーム方式でこれを行うための手段を提供します。

リサーチ

JavaFX 2.0はビデオをサポートしています-素晴らしいです!しかし、現時点では、公式ラインは「VP6ビデオとMP3オーディオを含むFLV」をサポートしています。これを拡張して、より多くのコーデックのサポートを追加する方法はありますか?私がサポートしたいハードコーデックはありません。可能な限り多くの場合なので、上記を実行するための拡張可能な方法を探しています。

マシンにネイティブにインストールされたコーデックのビデオを再生し、それ自体をアドバタイズしないのではないかと思いました(機能は明らかにマシンに依存し、クロスプラットフォームではないためです)。一般的なフォーマットであり、それが述べている以外のものを再生することを実際に拒否します。

JavaFX 1.3を見ると、インストールされている場所に応じて、他のプラットフォーム依存コーデックもサポートしています。JavaFX 2でこの動作を実現する方法はありますか?それとも、次のリリースでまったく計画されていますか?ロードマップ上でそれに関する情報や、それに関するOracleからのコメントを見つけることができませんでした。

広範囲に検索して見つけたのはここだけです。これは、それが可能かもしれないことを意味しますが、誰もその方法を知らないようです。また、GStreamerに基づいているかどうか、GStreamerでサポートされているすべての形式がデフォルトで含まれていない理由を知りたいのですが。

JavaFXでDVDを再生するという点では、私はまったくどこにも行けないので、現時点ではそれはダメだと思います。誰かが何かアイデアや情報を持っているなら、私はすべての耳です。

その他のアプローチ

私が半分考えていたアプローチの1つは、ここで説明するように古いJavaFXからJMC jarをクローバリングし、JavaFX2と一緒に機能させることです。

すべてが失敗しました。追加のコーデックのサポートがすぐにサポートされるかどうか/いつサポートされるかについて誰かが情報やリンクを持っている場合は、それも聞いてみたいと思います。または、オラクルの誰かの連絡先の詳細があれば、それもありがたいです!私はしばらくの間Javaでまともなビデオのサポートを待ち望んでいましたが、これはJavaFXがこれに対する答えなのか、それともそれ以上再生されないもう1つの中途半端な試みなのかを理解しようとしているのだと思います。現時点ではありません!私はそれが後者ではないことを望んでいますが、それが事実であることを示すために私はまだ多くを見ていません。

4

5 に答える 5

10

私を信じてください、私はあなたの欲求不満を感じて知っています。私はしばらくの間これを熟考しました、しかし私は私の問題を解決するためにまっすぐでない手段を使わなければなりませんでした。

これを回避する方法はたくさんありますが、それぞれに制限がありますが、何が効果的かによって異なります。

  1. ドキュメントによると、WebViewは、プラットフォームでサポートされているビデオを再生するHTML5で動作します(残念ながらフラッシュではありません)。Webビューを使用してビデオを再生する場合は、これを試すことができます。他のノードで描画することもできます。

  2. ポータブルVLCプレーヤー!ある種のプロジェクター/ディレクターアプリを開発していて、フルスクリーンビデオが必要な場合は、ポータブルVLCプレーヤーで、一方の画面でフルスクリーンでビデオを再生し、もう一方の画面でコントロールを使用できます。このソリューションを使用すると、MacとWindowsで非常にうまく機能します。:)唯一のことは、アプリのフルスクリーンビデオのように見えるだけで、外部アプリであるため、ビデオにノードを描画できないことです。

  3. javafx 2.0アプリケーション内でフラッシュの機能を利用する必要がある場合は、ネイティブブラウザのすべての機能をサポートするswtベースのブラウザ(またはSwingerの場合はDJプロジェクトのようなもの)を使用してください。

于 2011-11-27T00:06:29.823 に答える
10

これで、MKVサポートをJavaFXに正常にコンパイルできました。ネイティブレイヤーでも、ある程度の労力は必要ですが、それほどの労力はかかりません。それを取り巻く議論についてはこちらを、パッチ/JIRAチケットとして提出された結果についてはこちらをご覧ください。

私はここでプロセスに関するはるかに包括的なガイドを書きました。これは、このルートをたどろうとしている他の人にとって興味深いかもしれません。

以下は、他のメディアサポートのコンパイルを実際に真剣に検討する前の簡単な調査ですが、参考のためにここに残しておきます。

JFX8がリリースされ、完全にオープンソースになったので、これをどのように実行できるか、およびJFXソースにパッチを適用せずに実行できるかどうかを少し時間をかけて調べました。残念ながら、後者の点に対する答えは、少なくとも恐ろしいバイトコード操作のハッキングがなければ、ほぼ間違いなくノーです。これについては後日もっと実際的に調べるかもしれませんが、入手可能なソースからこれまでに解決したことを文書化します。

魔法はメディアコンストラクターから始まります。これは最終的にMediaExceptionポップアウトの場所です(MEDIA_UNSUPPORTEDサポートされていない形式を再生しようとするとフラグが付けられます)。そこからロケーターが作成され、そのコンストラクターによってURLがサポートされているものであることが保証されます。init()次に、そのメソッドが別のスレッドで呼び出されます。このスレッドは、URL文字列に対して健全性チェックを実行し、ファイルを読み取り、フォーマットが何であるかを調べます。

したがって、メソッドのこの部分に関連するコードは次のとおりです。

if (scheme.equals("file") || scheme.equals("jar")) {
    InputStream stream = getInputStream(uri);
    stream.close();
    isConnected = true;
    contentType = MediaUtils.filenameToContentType(uriString); // We need to provide at least something
}

if (isConnected) {
    // Check whether content may be played.
    // For WAV use file signature, since it can detect audio format
    // and we can fail sooner, then doing it at runtime.
    // This is important for AudioClip.
    if (MediaUtils.CONTENT_TYPE_WAV.equals(contentType)) {
        contentType = getContentTypeFromFileSignature(uri);
        if (!MediaManager.canPlayContentType(contentType)) {
            isMediaSupported = false;
        }
    } else {
        if (contentType == null || !MediaManager.canPlayContentType(contentType)) {
            // Try content based on file name.
            contentType = MediaUtils.filenameToContentType(uriString);

            if (Locator.DEFAULT_CONTENT_TYPE.equals(contentType)) {
                // Try content based on file signature.
                contentType = getContentTypeFromFileSignature(uri);
            }

            if (!MediaManager.canPlayContentType(contentType)) {
                isMediaSupported = false;
            }
        }
    }

    // Break as connection has been made and media type checked.
    break;
}

これから、名前に基づいてファイルコンテンツを取得する最初の「ダム」の試みが行われていることがわかります(これが行われMediaUtils.filenameToContentType()ます)。その後、さまざまなタイプのwavファイルをチェックするための特別なケースがいくつかありますが、それが失敗した場合は失敗します。実際のファイル署名を調べる賢いチェックに戻ります。これらのチェックは両方ともMediaUtilsにあります。この後者のチェックははるかに広範囲であり、ファイルの最初の数バイトを調べて、そのようにフォーマットを処理できるかどうかを確認します。MEDIA_UNSUPPORTEDそれができない場合、それはベイルアウトして例外をスローし、それが私たちの恐ろしい旗として飛び出します。

ただし、タイプが正しく識別されている場合は、さらに別のハードルを通過する必要があります。現在のプラットフォームでサポートされている必要があります。一部のプラットフォームは環境に応じて動的にロードされますが、GSTPlatform常に存在するため、ここに追加の(ユニバーサル)フォーマットを配置する必要があります。これは比較的単純で、CONTENT_TYPESサポートされている形式の配列を保持するだけの配列が存在します。

残念ながら、JavaFXリポジトリのクローン作成は現時点では失敗しているようです。そうでない場合は、これの一部を実行しようとします。しかし、上記の代わりに、さらなるフォーマットのサポートを追加するために実際に何が起こる必要がありますか?実際、それほど難しいことではないようです。

  1. MediaUtilsではfilenameToContentType()、新しいファイル拡張子を処理するためのサポートをメソッドに追加する必要があります。これは些細なことです。

  2. fileSignatureToContentType()同じクラスで、シグネチャに基づいてファイルタイプを計算するために、メソッドにサポートを追加する必要があります。これは少し複雑ですが、それでもそれほど悪くはありません。現在のコードは、ファイル拡張子から形式が正しく(またはまったく)識別されていない場合にのみフォールバックとしてこれを使用しているように見えるため、これはオプションの場合もあります。さまざまな形式のファイル署名の包括的なリストがここにあり、このタスクに役立ちます。

  3. GSTPlatformでは、サポートされているコンテンツタイプのリストに新しいコンテンツタイプを追加する必要があります。

Java側では、コンテンツタイプを受け入れ、少なくともネイティブGstreamerレイヤーに渡そうとするために必要なのはこれだけのようです。

ただし、私はGStreamerの専門家ではないため、JavaFXが現在拒否している、処理および再生できる形式が他にもたくさんあることは承知していますが、GStreamerがこの容量をどれだけ正確に削除したかはわかりません。彼らは間違いなく上記のJavaレイヤーでそれを行っていますが、ネイティブのGStreamerレベルでもそれを行っている可能性があります-現時点ではわかりません。

彼らはJFX8用のGStreamerにいくつかの変更を加えたと思いますが、現時点では関連するプロジェクトページにリストされていないため、このバージョンで何が変更されたかを正確に把握するのは非常に困難です。

次のステップは、JFX8ソースを取得し、新しいコンテンツタイプに対して上記の提案された変更を使用してビルドし、ネイティブレベルで発生するエラー(存在する場合)を確認して、そこから取得することです。

于 2014-03-21T16:14:59.527 に答える
6

そして今、Javafx2.1はついにmp4 H.264をサポートするので、上記のスタントなしでうまくいくはずです。:)

于 2012-03-27T23:19:52.150 に答える
5

APIデザインは、独自のコーデックのローリングをサポートしていないようです。ほとんどすべてのクラスが最終的なものです(VideoTrack、Media、MediaPlayerなど)。現在、実際のビデオデコードは内部クラスで行われていると思います。つまり、それらをオーバーライドする方法はありません。

オープンソースのJavaFX2.0の計画がありますが、JDK8のリリースが近づくと思います。うまくいけば、彼らがこれを行うとき、コンストラクターからコーデックをどのように解決するかをMedia(String source)確認し、これに何らかの方法でフックできるかどうかを確認できます。

于 2011-11-25T06:12:20.480 に答える
2

JavaFXバグ追跡システムでこれに対する現在のオープン機能の要求:

リンクされた機能リクエストとそれに関連するコメントを読んで、使用しているJavaFXディストリビューションバージョンの現在のステータス(またはその欠如;-)を理解してください。

InputStreamベースのMediaAPIの場合、JavaFX開発者による後のコメントの1つは、「これをJDK 10で検討することを提案します」であるため、将来的には可能性があると思います...

また、JavaFXが現在特定のエンコーディングタイプのサポートを組み込んでいるかどうかわからない場合は、サポートされているメディアエンコーディングとメディアコンテナタイプの包括的な概要がjavafx.mediaパッケージのjavadocに記載されています( JavaFXのバージョンと一致するjavadocのバージョンを確認します)。

JavaFXでネイティブにサポートされていないメディアタイプであり、ビデオを取得するためだけにネイティブのJavaFXメディアサポートをハックしたくない場合でも、少なくともJavaFXからビデオを再生するための他のソリューションに興味がある人再生、関連する質問への私の答えも見ることができます:

于 2018-01-30T00:11:56.127 に答える