2013-05-01 15 views
5

Quindi di recente ho iniziato a lavorare con JavaFX per provare a inserire video e audio nei miei programmi java. L'audio ha funzionato bene, ma per qualche ragione ogni volta che provo a riprodurre un file video, restituisce un'eccezione MEDIA_UNSUPPORTED. Ho letto in giro e ho visto che il file video doveva essere MP4 (che è), quindi ho provato a convertirlo in un tipo diverso, quindi riconvertirlo in MP4 (H.264 & AAC) con alcuni convertitori diversi e niente cambia.MP4 non supportato in JavaFX?

Ecco il codice con cui sto lavorando:

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

}

L'errore si verifica sulla linea in cui viene inizializzato l'oggetto "Media" (inizio del costruttore). Sono a una perdita totale per vedere qual è il problema. Ho visto domande circa l'riprodurre file audio ma il video non si presenta, ma non ha nemmeno farlo per me ...

Nel caso in cui qualcuno ne ha bisogno:

Eclipse

JDK 7

JavaFX 2.0

Windows 7 Pro

EDIT:

Prima di tutto, ho notato che sto effettivamente utilizzando JavaFX 2.0 ... Potrebbe essere questo il problema?

Ho provato entrambe le versioni fornite nella risposta, ed entrambi restituisce questo errore (chiamato dal statusListener) quando si utilizza l'URL fornito da questa risposta:

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" 

Quando si utilizza il mio file, il programma restituisce questo errore immediatamente dopo aver chiamato il costruttore Media, come prima:

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) 

Ho aggiornato il codice che sto usando sopra.

RISOLTO! Il motivo è che stavo usando un JavaFX inappropriato (e forse JDK) per il lavoro. Non ho davvero il controllo di quella roba dal momento che questi sono computer scolastici, ma questo mi ha incasinato qualcosa di buono ... Grazie per l'aiuto! L'ho aggiornato con il mio codice finale.

risposta

7

Questo ha funzionato per me dopo aver modificato un po 'il programma per risolvere un paio di problemi.

swingvideoplayer

Alcune modifiche sono applicate:

  1. Un MediaView occorre visualizzare il video, quindi bisogna essere creato e inserito in una scena JavaFX attivo al fine per il video di essere visto .
  2. Alcuni controlli JavaFX devono essere creati sul thread dell'applicazione JavaFX anziché sul thread principale, altrimenti si ottiene java.lang.IllegalStateException: Toolkit not initialized.
  3. Gli eventi di errore del supporto di monitoraggio e l'aggiunta di alcuni registri diagnostici consentono di risolvere i problemi di codifica dei supporti.

Una JavaFX unica soluzione

Il programma incorpora JavaFX in un'applicazione swing, che è un po 'più complessa, allora solo giocando media in un'applicazione standard JavaFX. Il codice corrispondente per la riproduzione di un mp4 in un'applicazione JavaFX standard viene fornito nella risposta a: Can't play mp4 converted file - JavaFX 2.1. Si consiglia di utilizzare solo JavaFX, a meno che non si abbia un'esigenza specifica per Swing (come l'incorporamento del lettore multimediale basato su JavaFX all'interno di un'applicazione Swing di grandi dimensioni esistente).

Oracle fornisce un buon tutorial per Incorporating Media Assets Into JavaFX Applications.


Il JavaFX media package description documenta i mezzi di riproduzione codifiche, contenitori e protocolli che JavaFX supporta.


Esempio per la riproduzione di video mp4 da un'oscillazione App utilizzando un JavaFX MediaPlayer

Nota il campione coglie solo un sottoinsieme dei possibili errori dei supporti. Per un modello di codice in grado di rilevare e registrare tutti gli errori relativi ai supporti, vedere 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); 
     } 
    }); 
    } 
} 

risolto!

È bello vedere che il poster originale è stato in grado di far funzionare la riproduzione del video e l'errore finale era semplicemente l'utilizzo di una vecchia versione JavaFX (2.0) che non supporta la riproduzione di mp4. L'aggiornamento a JavaFX 2.2+ (che supporta la riproduzione di mp4) ha risolto il problema.

+0

In realtà, avevo già provato l'esempio che hai fornito per l'altra domanda e, come questo codice, restituisce ancora lo stesso errore di prima, e nessuno dei due avrebbe giocato. Ho notato, tuttavia, che quando uso il mio file, ottengo un errore rosso, mentre il link che stai fornendo restituisce un errore attraverso l'ascoltatore statusProperty ... – Chaos

+0

grazie mille per quel campione! – Chris

+0

Sto usando javaFx 2.2 e ottengo ancora questo errore. C'è qualche altro problema che non è stato delineato in questo post? – cp101020304