URI 语法和字符串转换有困难
Difficulty with URI syntax and conversion to string
我和我的朋友一直致力于 Java 项目,使用 Media、MediaPlayer 和 MediaView classes 创建一个简单的媒体播放器。但是,从一开始我们就无法成功打开用作测试文件的视频。在多次愤怒的运行时异常之后,我们终于弄清楚问题的根源是传递给每个对象的字符串(媒体需要一个以 URI 格式表示文件路径的字符串)。经过一些修改,我们发现以下URI在我的电脑上可以打开文件:
Media m = new Media("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4");
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
但是,我们后来尝试实现一个 Open 方法,该方法允许用户选择他们想要播放的文件(作为文件对象)。执行此操作时,我们使用以下命令打开文件:
File currentFile = new File(null);
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
Media m = new Media(currentFile.toURI().toString());
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
这又开始给我们运行时异常,所以我们在控制台中使用 println 来找出问题所在。正在使用的字符串现在比应有的字符串少了两个“/”:
"file:/C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4"
但是,即使修改了字符串,我们仍然在选择文件后立即收到相同的运行时错误:
Exception in Application start method
java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
然后我们将整个 Open 方法注释掉并返回到我们的原始代码,但继续收到相同的错误。
我们的完整代码可在此处获得:
智能播放class
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;
public class SmartPlay extends Application {
File currentFile;
Scene scene;
@Override
public void start(Stage primary) {
primary.setTitle("SmartPlay");
selectCurrentFileToOpen();
//Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");
scene = new Scene(player, 720, 480, Color.BLACK);
player.setTop(makeMenus());
primary.setScene(scene);
primary.show();
}
private MenuBar makeMenus() {
MenuBar mb = new MenuBar();
Menu fileMenu = new Menu("File");
MenuItem openItem = new MenuItem("Open...");
openItem.setOnAction(e -> {
selectCurrentFileToOpen();
scene.setRoot(new Player(currentFile.toURI()));
});
MenuItem quitItem = new MenuItem("Quit");
quitItem.setOnAction(e -> Platform.exit());
fileMenu.getItems().addAll(openItem, quitItem);
return mb;
}
public boolean selectCurrentFileToOpen() {
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
return true;
}
public void stop() {
}
public static void main(String[] args) {
launch(args);
}
}
玩家class
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;
public class Player extends BorderPane {
Media m;
MediaPlayer mp;
MediaView mv;
Pane p;
MediaBar bar;
public Player(String file) {
m = new Media(file);
mp = new MediaPlayer(m);
mv = new MediaView(mp);
p = new Pane();
p.getChildren().addAll(mv);
setCenter(p);
bar = new MediaBar(mp);
setBottom(bar);
setStyle("-fx-background-color:#cccccc");
mp.play();
}
}
媒体栏class
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;
public class MediaBar extends HBox {
Slider time = new Slider();
Slider vol = new Slider();
Button playButton = new Button("Pause");
Button halfSpeed = new Button("0.5x");
Button normalSpeed = new Button("1.0x");
Button doubleSpeed = new Button("2.0x");
Label volume = new Label("Volume: ");
Label nowTime;
MediaPlayer player;
public MediaBar(MediaPlayer play) {
player = play;
setAlignment(Pos.CENTER);
setPadding(new Insets(5,10,5,10));
vol.setPrefWidth(70);
vol.setMinWidth(30);
vol.setValue(100);
nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
HBox.setHgrow(time, Priority.ALWAYS);
playButton.setPrefWidth(30);
getChildren().addAll(playButton,time,nowTime,volume,vol);
}
public static String formatTime(Duration duration) { //Whosebug: Jon Skeet
long seconds = (long) duration.toSeconds();
long absSeconds = Math.abs(seconds);
String positive = String.format(
"%d:%02d:%02d",
//absSeconds / 3600,
(absSeconds % 3600) / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
}
所以我 运行 你在命令行中的代码,我能够得到一个更具体的调试错误。因此,您在 MediaBar 中进行的时间格式化似乎导致了错误。我不知道你到底想用它做什么,但你格式化时间的方式不正确。如果您注释掉它以及您用来添加时间格式的其他内容,URI 路径将是正确的,您的视频应该 运行 没问题。我知道您在格式化时缺少“%02d”。至于你在格式化什么,我不太清楚所以我无法帮助你。
我和我的朋友一直致力于 Java 项目,使用 Media、MediaPlayer 和 MediaView classes 创建一个简单的媒体播放器。但是,从一开始我们就无法成功打开用作测试文件的视频。在多次愤怒的运行时异常之后,我们终于弄清楚问题的根源是传递给每个对象的字符串(媒体需要一个以 URI 格式表示文件路径的字符串)。经过一些修改,我们发现以下URI在我的电脑上可以打开文件:
Media m = new Media("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4");
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
但是,我们后来尝试实现一个 Open 方法,该方法允许用户选择他们想要播放的文件(作为文件对象)。执行此操作时,我们使用以下命令打开文件:
File currentFile = new File(null);
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
Media m = new Media(currentFile.toURI().toString());
MediaPlayer mp = new MediaPlayer(m);
MediaView mv = new MediaView(mp);
这又开始给我们运行时异常,所以我们在控制台中使用 println 来找出问题所在。正在使用的字符串现在比应有的字符串少了两个“/”:
"file:/C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXO-MonsterMV.mp4"
但是,即使修改了字符串,我们仍然在选择文件后立即收到相同的运行时错误:
Exception in Application start method
java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication5(LauncherImpl.java:182)
然后我们将整个 Open 方法注释掉并返回到我们的原始代码,但继续收到相同的错误。
我们的完整代码可在此处获得:
智能播放class
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import java.io.File;
import javafx.stage.FileChooser;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.application.Platform;
public class SmartPlay extends Application {
File currentFile;
Scene scene;
@Override
public void start(Stage primary) {
primary.setTitle("SmartPlay");
selectCurrentFileToOpen();
//Player(currentFile.toURI().toString().substring(0,5)+"//"+currentFile.toURI().toString().substring(5));
Player player = new Player("file:///C:/Users/mewww/Google%20Drive/Java/SmartPlay/EXOMonsterMV.mp4");
scene = new Scene(player, 720, 480, Color.BLACK);
player.setTop(makeMenus());
primary.setScene(scene);
primary.show();
}
private MenuBar makeMenus() {
MenuBar mb = new MenuBar();
Menu fileMenu = new Menu("File");
MenuItem openItem = new MenuItem("Open...");
openItem.setOnAction(e -> {
selectCurrentFileToOpen();
scene.setRoot(new Player(currentFile.toURI()));
});
MenuItem quitItem = new MenuItem("Quit");
quitItem.setOnAction(e -> Platform.exit());
fileMenu.getItems().addAll(openItem, quitItem);
return mb;
}
public boolean selectCurrentFileToOpen() {
FileChooser fc = new FileChooser();
fc.setTitle("Open");
currentFile = fc.showOpenDialog(null);
return true;
}
public void stop() {
}
public static void main(String[] args) {
launch(args);
}
}
玩家class
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import java.net.URI;
public class Player extends BorderPane {
Media m;
MediaPlayer mp;
MediaView mv;
Pane p;
MediaBar bar;
public Player(String file) {
m = new Media(file);
mp = new MediaPlayer(m);
mv = new MediaView(mp);
p = new Pane();
p.getChildren().addAll(mv);
setCenter(p);
bar = new MediaBar(mp);
setBottom(bar);
setStyle("-fx-background-color:#cccccc");
mp.play();
}
}
媒体栏class
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.media.MediaPlayer;
import javafx.scene.layout.Priority;
import javafx.scene.control.Slider;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.util.Duration;
public class MediaBar extends HBox {
Slider time = new Slider();
Slider vol = new Slider();
Button playButton = new Button("Pause");
Button halfSpeed = new Button("0.5x");
Button normalSpeed = new Button("1.0x");
Button doubleSpeed = new Button("2.0x");
Label volume = new Label("Volume: ");
Label nowTime;
MediaPlayer player;
public MediaBar(MediaPlayer play) {
player = play;
setAlignment(Pos.CENTER);
setPadding(new Insets(5,10,5,10));
vol.setPrefWidth(70);
vol.setMinWidth(30);
vol.setValue(100);
nowTime = new Label(formatTime(player.getCurrentTime()) + "/" + formatTime(player.getTotalDuration()));
HBox.setHgrow(time, Priority.ALWAYS);
playButton.setPrefWidth(30);
getChildren().addAll(playButton,time,nowTime,volume,vol);
}
public static String formatTime(Duration duration) { //Whosebug: Jon Skeet
long seconds = (long) duration.toSeconds();
long absSeconds = Math.abs(seconds);
String positive = String.format(
"%d:%02d:%02d",
//absSeconds / 3600,
(absSeconds % 3600) / 60,
absSeconds % 60);
return seconds < 0 ? "-" + positive : positive;
}
}
所以我 运行 你在命令行中的代码,我能够得到一个更具体的调试错误。因此,您在 MediaBar 中进行的时间格式化似乎导致了错误。我不知道你到底想用它做什么,但你格式化时间的方式不正确。如果您注释掉它以及您用来添加时间格式的其他内容,URI 路径将是正确的,您的视频应该 运行 没问题。我知道您在格式化时缺少“%02d”。至于你在格式化什么,我不太清楚所以我无法帮助你。