MP4 unsupported in JavaFX?

折月煮酒 提交于 2019-11-29 10:59:58
jewelsea

This worked for me after I modified your program a little bit to fix a couple of issues.

Some changes I applied:

  1. A MediaView is necessary to view the video, so one needs to be created and added to an active JavaFX scene in order for the video to be seen.
  2. Some JavaFX controls need to be created on the JavaFX application thread rather than the main thread, otherwise you get java.lang.IllegalStateException: Toolkit not initialized.
  3. Monitoring media error events and adding some diagnostic logs helps troubleshoot media encoding issues.

A JavaFX only solution

Your program embeds JavaFX in a Swing application which is a bit more complex then just playing Media in a standard JavaFX application. Corresponding code for playback of an mp4 in a standard JavaFX application is supplied in my answer to: Can't play mp4 converted file - JavaFX 2.1. Using just JavaFX is recommended unless you have a specific need for Swing (such as embedding your JavaFX based media player inside an existing large Swing application).

Oracle provide a good tutorial for Incorporating Media Assets Into JavaFX Applications.


The JavaFX media package description documents the media playback encodings, containers and protocols which JavaFX supports.


Sample for playing back mp4 video from a Swing App using a JavaFX MediaPlayer

Note the sample only catches a subset of the possible media errors. For a code template which can catch and log all media errors see the JavaFX media error handling documentation.

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);
      }
    });
  }
}

SOLVED!

Nice to see that original poster was able to get video playback working and the final error was just using an old JavaFX version (2.0) which does not support mp4 playback. Updating to JavaFX 2.2+ (which does support mp4 playback) fixed the issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!