Fix music player can't load demo files from jrt #61
This commit is contained in:
parent
47bbf9d97e
commit
0e6987d4c7
@ -247,7 +247,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<toolName>jlink</toolName>
|
<toolName>jlink</toolName>
|
||||||
<addModules>
|
<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>
|
</addModules>
|
||||||
<modulePath>${build.platformModulesDir}</modulePath>
|
<modulePath>${build.platformModulesDir}</modulePath>
|
||||||
<output>${build.package.runtimeImageDir}</output>
|
<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 static atlantafx.sampler.page.showcase.musicplayer.Utils.copyImage;
|
||||||
|
|
||||||
import atlantafx.sampler.Resources;
|
import atlantafx.sampler.Resources;
|
||||||
import java.io.File;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -17,7 +17,7 @@ import javafx.scene.media.Media;
|
|||||||
import javafx.scene.media.MediaPlayer;
|
import javafx.scene.media.MediaPlayer;
|
||||||
|
|
||||||
@SuppressWarnings("StringOperationCanBeSimplified")
|
@SuppressWarnings("StringOperationCanBeSimplified")
|
||||||
record MediaFile(File file) {
|
record MediaFile(Path path) {
|
||||||
|
|
||||||
private static final Map<String, Metadata> METADATA_CACHE = new HashMap<>();
|
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
|
// media file metadata you have to load it to media player instance, which
|
||||||
// is costly and that instance is not even reusable.
|
// is costly and that instance is not even reusable.
|
||||||
public void readMetadata(Consumer<Metadata> callback) {
|
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);
|
var mediaPlayer = new MediaPlayer(media);
|
||||||
|
|
||||||
// The media information is obtained asynchronously and so not necessarily
|
// 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 and that player has transitioned to Status.READY status.
|
||||||
mediaPlayer.setOnReady(() -> {
|
mediaPlayer.setOnReady(() -> {
|
||||||
Map<String, Object> metadata = media.getMetadata();
|
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);
|
var image = getTag(metadata, "image", Image.class, null);
|
||||||
// clone everything to make sure media player will be garbage collected
|
// clone everything to make sure media player will be garbage collected
|
||||||
return new Metadata(
|
return new Metadata(
|
||||||
@ -51,7 +51,7 @@ record MediaFile(File file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Media createMedia() {
|
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) {
|
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;
|
package atlantafx.sampler.page.showcase.musicplayer;
|
||||||
|
|
||||||
|
import atlantafx.sampler.Launcher;
|
||||||
import atlantafx.sampler.Resources;
|
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.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
@ -18,10 +24,32 @@ import javafx.scene.paint.Color;
|
|||||||
|
|
||||||
final class Model {
|
final class Model {
|
||||||
|
|
||||||
private static final List<File> DEMO_FILES = List.of(
|
private static final List<Path> DEMO_FILES = getDemoFiles();
|
||||||
Paths.get(Resources.getResource("media/Beat Thee.mp3")).toFile(),
|
|
||||||
Paths.get(Resources.getResource("media/Study and Relax.mp3")).toFile()
|
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 ObservableList<MediaFile> playlist = FXCollections.observableArrayList();
|
||||||
private final ReadOnlyBooleanWrapper canGoBack = new ReadOnlyBooleanWrapper();
|
private final ReadOnlyBooleanWrapper canGoBack = new ReadOnlyBooleanWrapper();
|
||||||
|
@ -135,7 +135,7 @@ final class PlaylistPane extends VBox {
|
|||||||
public Void call() throws InterruptedException {
|
public Void call() throws InterruptedException {
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
Thread.sleep(500); // add artificial delay to demonstrate progress bar
|
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++;
|
progress++;
|
||||||
updateProgress(progress, files.size());
|
updateProgress(progress, files.size());
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ final class StartScreen extends BorderPane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (File file : files) {
|
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)) {
|
if (!p.toAbsolutePath().toString().endsWith(s)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
model.addFile(new MediaFile(p.toFile()));
|
model.addFile(new MediaFile(p));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -10,6 +10,7 @@ module atlantafx.sampler {
|
|||||||
requires javafx.media;
|
requires javafx.media;
|
||||||
requires javafx.web;
|
requires javafx.web;
|
||||||
requires javafx.fxml;
|
requires javafx.fxml;
|
||||||
|
requires jdk.zipfs;
|
||||||
|
|
||||||
requires org.kordamp.ikonli.core;
|
requires org.kordamp.ikonli.core;
|
||||||
requires org.kordamp.ikonli.javafx;
|
requires org.kordamp.ikonli.javafx;
|
||||||
@ -39,6 +40,7 @@ module atlantafx.sampler {
|
|||||||
opens atlantafx.sampler.assets.styles;
|
opens atlantafx.sampler.assets.styles;
|
||||||
opens atlantafx.sampler.images;
|
opens atlantafx.sampler.images;
|
||||||
opens atlantafx.sampler.images.modena;
|
opens atlantafx.sampler.images.modena;
|
||||||
|
opens atlantafx.sampler.media;
|
||||||
opens atlantafx.sampler.page.general;
|
opens atlantafx.sampler.page.general;
|
||||||
opens atlantafx.sampler.page.showcase;
|
opens atlantafx.sampler.page.showcase;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user