5

だから私は最近JavaFXを使ってビデオとオーディオを私のJavaプログラムに挿入しようとしました。オーディオは問題なく動作しましたが、何らかの理由でビデオ ファイルを再生しようとすると、MEDIA_UNSUPPORTED 例外が返されます。ビデオ ファイルは MP4 である必要があることを確認したので、別の形式に変換してから、いくつかの異なるコンバーターを使用して MP4 (H.264 & AAC) に再変換してみました。何も変わりません。

ここに私が取り組んでいるコードがあります:

import java.net.URL;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;


public class CallVideo extends JFrame{

public static final String VID_URL = "file:/C:/Users/Public/Videos/Videos/testCon.mp4"; //http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4

private JFXPanel panel;

public CallVideo(String url)
{   
    panel = new JFXPanel();
    Platform.runLater(new Runnable()
    {
        public void run()
        {
            final Media clip = new Media(VID_URL);
            final MediaPlayer player = new MediaPlayer(clip);
            final MediaView viewer = new MediaView(player);
            viewer.setFitHeight(200);
            viewer.setFitWidth(200);
            final Button button = new Button("Bing Zzzzt!");
            button.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event)
                {
                    viewer.getMediaPlayer().seek(Duration.ZERO);
                    viewer.getMediaPlayer().play();
                }
            });

        setMediaEventHandlers(viewer);
            VBox vid = new VBox();
            vid.getChildren().addAll(viewer, button);
            Scene aScene = new Scene(vid, 200, 200);
            panel.setScene(aScene);
        }
    });
    this.add(panel);
    this.setSize(500, 500);
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
}

private void setMediaEventHandlers(final MediaView view) {
    final MediaPlayer player = view.getMediaPlayer();

    System.out.println("Initial: " + player.getStatus());
    player.statusProperty().addListener(new ChangeListener<MediaPlayer.Status>() {
      @Override
      public void changed(ObservableValue<? extends MediaPlayer.Status> observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) {
        System.out.println("Current: " + curStatus);
      }
    });

    if (player.getError() != null) {
      System.out.println("Initial Error: " + player.getError());
    }

    player.setOnError(new Runnable() {
      @Override public void run() {
        System.out.println("Current Error: " + player.getError());
      }
    });
  }

public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run()
        {
            new CallVideo(VID_URL);
        }
    });
}

}

エラーは、「Media」オブジェクトが初期化される行 (コンストラクターの先頭) で発生します。私は問題が何であるかを見るのに完全に途方に暮れています。オーディオの再生についての質問を見たことがありますが、ビデオは表示されませんが、私にとってはそうでもありません...

誰かがそれを必要とする場合:

エクリプス

JDK7

JavaFX 2.0

ウィンドウズ 7 プロ

編集:

まず、私は実際に JavaFX 2.0 を使用していることに気付きました...それが問題なのでしょうか?

回答で提供されている両方のバージョンをテストしましたが、その回答で提供された URL を使用すると、両方ともこのエラー (statusListener によって呼び出されます) を返します。

Current Error: MediaException: MEDIA_UNSUPPORTED : com.sun.media.jfxmedia.MediaException: "Error enter code herelocator unsupported media format" : com.sun.media.jfxmedia.MediaException: "Error locator unsupported media format"

独自のファイルを使用する場合、以前と同様に、プログラムは Media コンストラクターを呼び出すとすぐにこのエラーを返します。

Exception in thread "AWT-EventQueue-0" MediaException: MEDIA_UNSUPPORTED : Unrecognized file signature!
at javafx.scene.media.Media.<init>(Media.java:382)
at CallVideo.<init>(CallVideo.java:27)
at CallVideo$5.run(CallVideo.java:90)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

上記で使用しているコードを更新しました。

解決しました! その理由は、私が仕事に不適切な JavaFX (およびおそらく JDK) を使用していたからです。これらは学校のコンピューターなので、私は本当にそのことを制御できませんが、それは私に何か良いことを台無しにしました...助けてくれてありがとう! 最終的なコードで更新しました。

4

1 に答える 1

7

いくつかの問題を修正するためにプログラムを少し修正した後、これはうまくいきました。

スイングビデオプレーヤー

私が適用したいくつかの変更:

  1. ビデオを表示するにはMediaViewが必要であるため、ビデオを表示するには、MediaView を作成してアクティブな JavaFX シーンに追加する必要があります。
  2. 一部の JavaFX コントロールは、メイン スレッドではなく JavaFX アプリケーション スレッドで作成する必要がありますjava.lang.IllegalStateException: Toolkit not initialized
  3. メディア エラー イベントを監視し、いくつかの診断ログを追加すると、メディア エンコーディングの問題のトラブルシューティングに役立ちます。

JavaFX のみのソリューション

あなたのプログラムは、JavaFX を Swing アプリケーションに組み込みます。これは、標準の JavaFX アプリケーションでメディアを再生するよりも少し複雑です。標準 JavaFX アプリケーションで mp4 を再生するための対応するコードは、 「mp4 変換ファイルを再生できません - JavaFX 2.1」に対する私の回答で提供されています。Swing が特に必要な場合 (既存の大規模な Swing アプリケーション内に JavaFX ベースのメディア プレーヤーを埋め込むなど) がない限り、JavaFX のみを使用することをお勧めします。

Oracle は、 Incorporating Media Assets Into JavaFX Applicationsの優れたチュートリアルを提供しています。


JavaFX メディア パッケージの説明には、JavaFX がサポートするメディア再生エンコーディング、コンテナ、およびプロトコルが記載されています。


JavaFX MediaPlayer を使用して Swing アプリから mp4 ビデオを再生するサンプル

このサンプルは、考えられるメディア エラーのサブセットのみをキャッチしていることに注意してください。すべてのメディア エラーをキャッチしてログに記録できるコード テンプレートについては、JavaFX メディア エラー処理のドキュメントを参照してください。

import javax.swing.*;
import javafx.application.Platform;
import javafx.beans.value.*;
import javafx.embed.swing.JFXPanel;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.media.*;
import javafx.util.Duration;

public class VideoPlayer extends JFrame {

  public static final String VID_URL = 
    "http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4";

  private static final int VID_WIDTH     = 320;
  private static final int VID_HEIGHT    = 180;
  private static final int PLAYER_WIDTH  = 320;
  private static final int PLAYER_HEIGHT = 265;

  private void play(final String url) {
    final JFXPanel panel = new JFXPanel();
    Platform.runLater(new Runnable() {
      @Override public void run() {
        initFX(panel, url);
      }
    });
    this.add(panel);
    this.setSize(PLAYER_WIDTH, PLAYER_HEIGHT);
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setVisible(true);
  }

  private void initFX(JFXPanel panel, String url) {
    MediaView mediaView = createMediaView(url);

    final Scene playerScene = new Scene(
      createPlayerLayout(mediaView), 
      PLAYER_WIDTH, 
      PLAYER_HEIGHT
    );

    setMediaEventHandlers(
      mediaView
    );

    panel.setScene(playerScene);
  }

  private MediaView createMediaView(String url) {
    final Media clip = new Media(url);
    final MediaPlayer player = new MediaPlayer(clip);
    final MediaView view = new MediaView(player);
    view.setFitWidth(VID_WIDTH);
    view.setFitHeight(VID_HEIGHT);
    return view;
  }

  private VBox createPlayerLayout(final MediaView view) {
    final Button button = new Button("Play From Start");
    button.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        view.getMediaPlayer().seek(Duration.ZERO);
        view.getMediaPlayer().play();
      }
    });

    final VBox layout = new VBox(8);
    layout.setAlignment(Pos.CENTER);
    layout.getChildren().addAll(
      view,
      button
    );

    layout.setStyle("-fx-background-color: linear-gradient(to bottom, derive(lightseagreen, -20%), lightseagreen);");

    return layout;
  }

  private void setMediaEventHandlers(final MediaView view) {
    final MediaPlayer player = view.getMediaPlayer();

    System.out.println("Initial: " + player.getStatus());
    player.statusProperty().addListener(new ChangeListener<MediaPlayer.Status>() {
      @Override
      public void changed(ObservableValue<? extends MediaPlayer.Status> observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) {
        System.out.println("Current: " + curStatus);
      }
    });

    if (player.getError() != null) {
      System.out.println("Initial Error: " + player.getError());
    }

    player.setOnError(new Runnable() {
      @Override public void run() {
        System.out.println("Current Error: " + player.getError());
      }
    });
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override public void run() {
        VideoPlayer player = new VideoPlayer();
        player.play(VID_URL);
      }
    });
  }
}

解決しました!

元のポスターがビデオ再生を機能させ、最終的なエラーがmp4再生をサポートしていない古いJavaFXバージョン(2.0)を使用していたことを確認できてうれしいです。JavaFX 2.2+ (mp4 再生をサポートする) に更新すると、問題が修正されました。

于 2013-05-01T20:58:10.303 に答える