使用 JavaFX 播放 QuickTime 视频
Play a QuickTime video with JavaFX
我尝试用 JavaFX 打开 MOV 视频文件:
Media media = new Media ("file:/tmp/file.MOV");
但它抛出一个 MediaException:MEDIA_UNSUPPORTED。
但是,如果我只是将文件扩展名从 .MOV 更改为 .MP4,它就可以完美运行,视频播放也没有错误。
如何强制 JavaFX 播放我的文件而不必重命名它?
嗯,那两个小时很有趣。干得好!只需确保您有一个零字节的 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:
//
{
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、长度和 uri 使其在没有窥视的情况下播放。
我尝试用 JavaFX 打开 MOV 视频文件:
Media media = new Media ("file:/tmp/file.MOV");
但它抛出一个 MediaException:MEDIA_UNSUPPORTED。
但是,如果我只是将文件扩展名从 .MOV 更改为 .MP4,它就可以完美运行,视频播放也没有错误。
如何强制 JavaFX 播放我的文件而不必重命名它?
嗯,那两个小时很有趣。干得好!只需确保您有一个零字节的 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:
//
{
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、长度和 uri 使其在没有窥视的情况下播放。