2013-05-01 12 views
5

Also habe ich vor kurzem angefangen mit JavaFX zu arbeiten, um Video und Audio in meine Java-Programme einzufügen. Audio funktioniert einwandfrei, aber jedes Mal, wenn ich eine Videodatei versuche und wiedergebe, wird eine MEDIA_UNSUPPORTED-Ausnahme zurückgegeben. Ich habe gelesen und sah, dass die Videodatei MP4 sein musste (was es ist), also habe ich versucht, es in einen anderen Typ umzuwandeln und es dann zu MP4 (H.264 & AAC) mit ein paar verschiedenen Konvertern umzuwandeln Nichts verändert sich.MP4 in JavaFX nicht unterstützt?

Hier ist der Code Ich arbeite mit:

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

}

Der Fehler in der Leitung auftritt, wo die „Medien“ Objekt initialisiert wird (Anfang Konstruktor). Ich bin völlig verloren, um zu sehen, was das Problem ist. Ich habe Fragen über die Audio-Wiedergabe zu sehen, aber das Video nicht angezeigt, aber es ist nicht einmal das tun für mich ...

Falls jemand es braucht:

Eclipse-

JDK 7

JavaFX 2.0

Windows 7 Pro

EDIT:

Zunächst habe ich bemerkt, dass ich tatsächlich JavaFX 2.0 benutze ... Könnte das das Problem sein?

Ich habe beiden Versionen in der Antwort zur Verfügung gestellt getestet, und beide Rück dieses Fehlers (von der statusListener genannt), wenn die URL von dieser Antwort zur Verfügung gestellt mit:

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" 

Wenn meine eigene Datei verwenden, das Programm gibt diesen Fehler sofort nach dem Aufrufen des Medienkonstruktors wie zuvor zurück:

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) 

Ich habe den Code, den ich oben verwende, aktualisiert.

Gelöst! Der Grund ist wirklich, dass ich einen unpassenden JavaFX (und möglicherweise JDK) für den Job verwendete. Ich habe nicht wirklich die Kontrolle über dieses Zeug, da dies Schulcomputer sind, aber das hat mir etwas Gutes versüßt ... Danke für die Hilfe! Ich habe es mit meinem endgültigen Code aktualisiert.

Antwort

7

Dies funktionierte für mich, nachdem ich Ihr Programm ein wenig geändert habe, um ein paar Probleme zu beheben.

swingvideoplayer

Einige Änderungen, die ich angewendet:

  1. A MediaView notwendig ist, um das Video zu sehen, so dass man erstellt werden muss und zu einer aktiven JavaFX Szene, um das Video zu sehen .
  2. Einige JavaFX-Steuerelemente müssen im JavaFX-Anwendungsthread und nicht im Hauptthread erstellt werden, andernfalls erhalten Sie java.lang.IllegalStateException: Toolkit not initialized.
  3. Die Überwachung von Medienfehlerereignissen und das Hinzufügen einiger Diagnoseprotokolle hilft bei der Behebung von Mediencodierungsproblemen.

A nur JavaFX Lösung

Ihr Programm bettet JavaFX in einer Swing-Anwendung, die dann von Medien in einem Standard JavaFX-Anwendung nur ein wenig komplexer ist zu spielen. Entsprechender Code für die Wiedergabe eines mp4 in einer Standard-JavaFX-Anwendung wird in meiner Antwort an: Can't play mp4 converted file - JavaFX 2.1 geliefert. Es wird empfohlen, nur JavaFX zu verwenden, es sei denn, Sie benötigen eine spezielle Swing-Funktion (z. B. das Einbetten Ihres JavaFX-basierten Media Players in eine vorhandene große Swing-Anwendung).

Oracle bieten ein gutes Tutorial für Incorporating Media Assets Into JavaFX Applications.


Die JavaFX media package description dokumentiert die Medienwiedergabe-Codierungen, Container und Protokolle, die JavaFX unterstützt.


Beispiel für die Wiedergabe von MP4-Videos von einer Swing-App mit einem JavaFX Mediaplayer

Notiere die Probe nur wieder fängt eine Teilmenge der möglichen Medienfehler. Eine Codevorlage, die alle Medienfehler abfangen und protokollieren kann, finden Sie unter 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); 
     } 
    }); 
    } 
} 

GELÖST!

Schön zu sehen, dass das Original-Poster die Videowiedergabe funktionierte und der letzte Fehler war nur eine alte JavaFX-Version (2.0), die keine mp4-Wiedergabe unterstützt. Das Update auf JavaFX 2.2+ (welches die mp4-Wiedergabe unterstützt) behob das Problem.

+0

Eigentlich hatte ich zuvor das Beispiel versucht, das Sie für die andere Frage gegeben haben, und wie dieser Code gibt es immer noch den gleichen Fehler wie zuvor, und keiner würde spielen. Ich habe jedoch festgestellt, dass bei der Verwendung meiner eigenen Datei ein roter Fehler auftritt, während der von Ihnen angegebene Link einen Fehler über den statusProperty-Listener zurückgibt ... – Chaos

+0

Vielen Dank für dieses Beispiel! – Chris

+0

Ich benutze javaFx 2.2 und bekomme immer noch diesen Fehler. Gibt es ein anderes Problem, das in diesem Beitrag nicht beschrieben wurde? – cp101020304