Reputation: 2990
Currently, this is how I check if a file is playable through the JavaFX MediaPlayer, since it's the way it is done internally.
import static com.sun.media.jfxmedia.MediaManager.canPlayContentType;
import static com.sun.media.jfxmediaimpl.MediaUtils.filenameToContentType;
public boolean isPlayable(String filename) {
return canPlayContentType(filenameToContentType(filename));
}
the problem is that the packages that contain these Methods "are not API" and not accessible on Java 9 anymore. I know that there are workarounds, but I wonder if there is an actually correct, future-proof way of doing this?
I want this method to populate a Library with all the playable content within a directory:
Files.find(folderPath, Integer.MAX_VALUE, (path, attr) ->
attr.isRegularFile() && isPlayable(path.toFile().getName()))
.forEach(path -> addSong(path));
Upvotes: 2
Views: 1151
Reputation: 169
Try this
//make a class like this
public class FindSongs extends SimpleFileVisitor<Path> {
public static LinkedList<Path> songPaths = new LinkedList<>();
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attr) {
try{
//System.out.println(path.toString());
Media media = new Media(path.toUri().toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.dispose();
songPaths.add(path);
}catch(Exception ex){
//ex.printStackTrace();
System.out.println("not playable: "+path.toString());
}
return CONTINUE;
}
}
//run this
Files.walkFileTree(Paths.get(args[0]), new FindSongs());
Then use FindSongs.songPaths variable for the list of all your songs. :)
Upvotes: 0
Reputation: 31878
I went through the documentation of javafx.media
module for the sake of finding any such built-in API and was unable to find one.
A look at the existing Implementation of filenameToContentType(String filename)
, which is somewhat:-
if (extension.equals(FILE_TYPE_AIF) || extension.equals(FILE_TYPE_AIFF)) {
contentType = CONTENT_TYPE_AIFF;
} else if ... other content types
That eventually checks if the current file extension is one of the supported container type and returns the content types based on the same.
The other piece on the board crucially was canPlayContentType(String contentType)
which seems to be relying eventually on the supportedContentTypes
for each platform as defined in the NativeMediaManager
class.
Though I haven't tested the solution as proposed below primarily due to unawareness of the overview of the task that you intend to perform eventually. Yet, the closest to your current implementation and what Basic PlayBack guidelines suggests as well, was to try
Construct a Media
instance out of the filename that you were providing.
Check for a MediaException
if any while performing (1).
Further, the exception type MediaException.Type MEDIA_UNSUPPORTED
states that
Indicates that this media type is not supported by this platform.
Drawing from the analogy with this and your current solution, you could probably make use of the this:
private static boolean isPlayable(String filename) {
try {
Media media = new Media(filename);
} catch (MediaException e) {
if (e.getType() == MediaException.Type.MEDIA_UNSUPPORTED) {
return false;
}
}
return true;
}
PS: Though I believe this could be further optimized if you actually start making use of the Media
constructed(as in the above stub) right away in your piece of code instead of just dropping it.
Upvotes: 1