2016-10-25 14 views
1

와 퀵타임 비디오를 재생 나는 자바 FX와 MOV 동영상 파일을 열려고 :자바 FX

Media media = new Media ("file:/tmp/file.MOV"); 

을하지만이 MediaException을 던졌습니다 : MEDIA_UNSUPPORTED합니다.

그러나 단순히 파일 확장자를 .MOV에서 .MP4로 변경하면 완벽하게 작동하며 비디오는 오류없이 재생됩니다.

이름을 바꾸지 않고 JavaFX에서 파일을 재생하도록하려면 어떻게해야합니까?

+0

더 많은 스택 추적을 게시 할 수 있습니까? 편집 : NVM이 원인을 발견했습니다. 'Media'는 당신이 http://pastebin.com/NkTFT2Tk를 받고있는 예외를 던지는 Locator의이 메소드를 호출합니다. –

답변

3

음 재미는 두 시간이었습니다. 여기 있네! 그냥 예제에서와 같이 0 바이트의 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(); 
     } 
    } 
} 

작동 방법 : 일반적으로 기본 로케이터는 콘텐츠 형식에 대한 예외를 throw하고 모두 끝납니다. Media의 로케이터를 사용자 지정 위치로 바꾸면 수동으로 contentType, length 및 uri를 설정하면 엿보지 않고 재생할 수 있습니다.

+0

이것은 해킹이나 똑똑한 해킹입니다! – Patrick

+0

언제나 그렇듯이 비공개 필드와 메소드는 한 Java 버전에서 다음 버전으로 변경 될 수 있으므로 향후 Java 릴리스에서는 작동하지 않을 수 있습니다. – VGR

+0

@VGR 예, Java 소스 코드를 수정하는 것이 좋습니다. 어쩌면 버그 보고서를 추가해야합니다. – Patrick