Fix music player can't load demo files from jrt #61

This commit is contained in:
mkpaz 2023-06-17 14:23:40 +04:00
parent 47bbf9d97e
commit 0e6987d4c7
6 changed files with 44 additions and 14 deletions

@ -247,7 +247,7 @@
<configuration>
<toolName>jlink</toolName>
<addModules>
java.base,java.logging,jdk.localedata,java.desktop,java.prefs,javafx.controls,javafx.fxml,javafx.swing,javafx.web
java.base,java.logging,jdk.localedata,jdk.zipfs,java.desktop,java.prefs,javafx.controls,javafx.fxml,javafx.swing,javafx.web
</addModules>
<modulePath>${build.platformModulesDir}</modulePath>
<output>${build.package.runtimeImageDir}</output>

@ -8,7 +8,7 @@ import static atlantafx.sampler.page.showcase.musicplayer.MediaFile.Metadata.NO_
import static atlantafx.sampler.page.showcase.musicplayer.Utils.copyImage;
import atlantafx.sampler.Resources;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
@ -17,7 +17,7 @@ import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
@SuppressWarnings("StringOperationCanBeSimplified")
record MediaFile(File file) {
record MediaFile(Path path) {
private static final Map<String, Metadata> METADATA_CACHE = new HashMap<>();
@ -25,7 +25,7 @@ record MediaFile(File file) {
// media file metadata you have to load it to media player instance, which
// is costly and that instance is not even reusable.
public void readMetadata(Consumer<Metadata> callback) {
var media = new Media(file.toURI().toString());
var media = new Media(path.toUri().toString());
var mediaPlayer = new MediaPlayer(media);
// The media information is obtained asynchronously and so not necessarily
@ -34,7 +34,7 @@ record MediaFile(File file) {
// MediaPlayer and that player has transitioned to Status.READY status.
mediaPlayer.setOnReady(() -> {
Map<String, Object> metadata = media.getMetadata();
callback.accept(METADATA_CACHE.computeIfAbsent(file.getAbsolutePath(), k -> {
callback.accept(METADATA_CACHE.computeIfAbsent(path.toAbsolutePath().toString(), k -> {
var image = getTag(metadata, "image", Image.class, null);
// clone everything to make sure media player will be garbage collected
return new Metadata(
@ -51,7 +51,7 @@ record MediaFile(File file) {
}
public Media createMedia() {
return new Media(file.toURI().toString());
return new Media(path.toUri().toString());
}
private <T> T getTag(Map<String, Object> metadata, String key, Class<T> type, T defaultValue) {

@ -2,10 +2,16 @@
package atlantafx.sampler.page.showcase.musicplayer;
import atlantafx.sampler.Launcher;
import atlantafx.sampler.Resources;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyBooleanProperty;
@ -18,10 +24,32 @@ import javafx.scene.paint.Color;
final class Model {
private static final List<File> DEMO_FILES = List.of(
Paths.get(Resources.getResource("media/Beat Thee.mp3")).toFile(),
Paths.get(Resources.getResource("media/Study and Relax.mp3")).toFile()
private static final List<Path> DEMO_FILES = getDemoFiles();
private static List<Path> getDemoFiles() {
// for the runtime image as it won't create zipfs automatically
URL media = Launcher.class.getResource(Resources.MODULE_DIR + "media");
if (media != null && media.toString().startsWith("jar")) {
try {
try (var fs = FileSystems.newFileSystem(
media.toURI(),
Map.of("create", "true")
)) {
return List.of(
fs.getPath(Resources.MODULE_DIR + "media/Beat Thee.mp3"),
fs.getPath(Resources.MODULE_DIR + "media/Study and Relax.mp3")
);
}
} catch (URISyntaxException | IOException e) {
throw new RuntimeException(e);
}
}
return List.of(
Paths.get(Resources.getResource("media/Beat Thee.mp3")),
Paths.get(Resources.getResource("media/Study and Relax.mp3"))
);
}
private final ObservableList<MediaFile> playlist = FXCollections.observableArrayList();
private final ReadOnlyBooleanWrapper canGoBack = new ReadOnlyBooleanWrapper();

@ -135,7 +135,7 @@ final class PlaylistPane extends VBox {
public Void call() throws InterruptedException {
for (File file : files) {
Thread.sleep(500); // add artificial delay to demonstrate progress bar
Platform.runLater(() -> model.addFile(new MediaFile(file)));
Platform.runLater(() -> model.addFile(new MediaFile(file.toPath())));
progress++;
updateProgress(progress, files.size());
}

@ -86,7 +86,7 @@ final class StartScreen extends BorderPane {
}
for (File file : files) {
model.addFile(new MediaFile(file));
model.addFile(new MediaFile(file.toPath()));
}
}
@ -108,7 +108,7 @@ final class StartScreen extends BorderPane {
if (!p.toAbsolutePath().toString().endsWith(s)) {
continue;
}
model.addFile(new MediaFile(p.toFile()));
model.addFile(new MediaFile(p));
}
});
} catch (Exception e) {

@ -10,6 +10,7 @@ module atlantafx.sampler {
requires javafx.media;
requires javafx.web;
requires javafx.fxml;
requires jdk.zipfs;
requires org.kordamp.ikonli.core;
requires org.kordamp.ikonli.javafx;
@ -39,6 +40,7 @@ module atlantafx.sampler {
opens atlantafx.sampler.assets.styles;
opens atlantafx.sampler.images;
opens atlantafx.sampler.images.modena;
opens atlantafx.sampler.media;
opens atlantafx.sampler.page.general;
opens atlantafx.sampler.page.showcase;
}