2016-10-25 6 views
1

とQuickTimeビデオを再生します。は、私はJavaFXのとMOV動画ファイルを開こうとJavaFXの

ただし、ファイル拡張子を.MOVから.MP4に変更するだけで完全に動作し、ビデオはエラーなく再生されます。

名前を変更せずにJavaFXでファイルを再生するにはどうすればよいですか?

+0

スタックトレースをさらにポストできますか?編集:NVMが原因を見つけました。 'Media'は' Locator'のこのメソッドを呼び出します。この例外はあなたがhttp://pastebin.com/NkTFT2Tkを取得している例外をスローします –

答えて

3

これは2時間楽しかったです。どうぞ!この例のようにゼロバイトのmp4ファイルがあることを確認してください。どのように動作するかはかなり重要です。

public class TestFrame extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     StackPane root = new StackPane(); 
     File actualFile = new File("shelter.mov"); 
     File emptyfile = new File("blank.mp4"); 
     Media media = new Media(emptyfile.toURI().toString()); 
     copyData(media, actualFile); 
     MediaPlayer mediaPlayer = null; 
     try { 
      mediaPlayer = new MediaPlayer(media); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     mediaPlayer.setAutoPlay(true); 
     MediaView mediaView = new MediaView(mediaPlayer); 
     root.getChildren().add(mediaView); 
     Scene scene = new Scene(root, 720, 480); 
     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private void copyData(Media media, File f) { 
     try { 
      Field locatorField = media.getClass().getDeclaredField("jfxLocator"); 
      // Inside block credits: 
      // http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection 
      { 
       Field modifiersField = Field.class.getDeclaredField("modifiers"); 
       modifiersField.setAccessible(true); 
       modifiersField.setInt(locatorField, locatorField.getModifiers() & ~Modifier.FINAL); 
       locatorField.setAccessible(true); 
      } 
      CustomLocator customLocator = new CustomLocator(f.toURI()); 
      customLocator.init(); 
      customLocator.hack("video/mp4", 100000, f.toURI()); 
      locatorField.set(media, customLocator); 
     } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
      e.printStackTrace(); 
     } catch (URISyntaxException e) { 
      e.printStackTrace(); 
     } 
    } 

    static class CustomLocator extends Locator { 
     public CustomLocator(URI uri) throws URISyntaxException { 
      super(uri); 
     } 

     @Override 
     public void init() { 
      try { 
       super.init(); 
      } catch (Exception e) { 
      } 
     } 

     public void hack(String type, long length, URI uri){ 
      this.contentType = type; 
      this.contentLength = length; 
      this.uri = uri; 
      this.cacheMedia(); 
     } 
    } 
} 

どのように動作するのですか?通常、デフォルトのロケータはコンテンツタイプに関する例外をスローし、すべてがそこで終了します。 Mediaのロケータをカスタムのロケータに置き換えると、contentType、length、およびuriを手動で設定すると、覗き見なく再生できます。

+0

これはハックですが、賢いハックです! – Patrick

+0

いつものように、非公開のフィールドとメソッドはJavaのあるバージョンから次のバージョンに変更される可能性があるため、将来のJavaリリースでは機能しない可能性があります。 – VGR

+0

@VGRはい、Javaソースコードを修正する方がよいでしょう。多分バグレポートを追加するべきです。 – Patrick

関連する問題