我正在使用 vlcj 4.8.0 制作音乐播放器,我希望实现其 MediaDiscovery 组件来查找包含音频文件的目录(在本地音乐文件夹中)。到目前为止,我一直在使用 DirectoryChooser 和
file.listFiles(File::isDirectory)
来获取它们,但我认为让 MediaDiscoverer 来处理此功能会更实用。
我对 vlcj 示例存储库中的此示例进行了一些修改,以仅获取包含音乐文件的目录。
public class MediaDiscovererTest {
private static final List<String> musicDirectories = new ArrayList<>();
public static void main(String[] args) throws Exception {
MediaPlayerFactory factory = new MediaPlayerFactory();
List<MediaDiscovererDescription> discoverers = factory.mediaDiscoverers().discoverers(MediaDiscovererCategory.LOCAL_DIRS);
if (discoverers.isEmpty()) {
return;
}
Iterator<MediaDiscovererDescription> iterator = discoverers.iterator();
while (iterator.hasNext()) {
MediaDiscovererDescription discoverer = iterator.next();
if (discoverer.name().equals("picture_dir") || discoverer.name().equals("video_dir")) {
iterator.remove(); // as I'm only interested in audio directories
}
}
for (MediaDiscovererDescription description : discoverers) {
final String name = description.name();
MediaDiscoverer discoverer = factory.mediaDiscoverers().discoverer(name);
MediaList list = discoverer.newMediaList();
MediaListEventAdapter mediaListEventAdapter = new MediaListEventAdapter() {
@Override
public void mediaListItemAdded(MediaList mediaList, MediaRef item, int index) {
Media newMedia = item.newMedia();
System.out.println(newMedia.info().mrl());
// Adding a new directory to the list
musicDirectories.add(newMedia.info().mrl());
newMedia.release();
}
};
list.events().addMediaListEventListener(mediaListEventAdapter);
discoverer.start();
// list.events().removeMediaListEventListener(mediaListEventAdapter);
// discoverer.release();
// list.release();
}
System.out.println(musicDirectories.size()); // <- In this test's current state, this will always be 0
Thread.currentThread().join();
}
}
每当将新项目合并到 MediaList 中时,其路径就会打印到控制台并保存到 musicDirectories 中。这按预期工作。然而,我不清楚如何监控发现过程的进展。具体来说,我想确定它何时结束,这样我就可以确保我的程序仅在发现过程完成后继续进行。
在处理类似的过程时,例如解析 Media(异步操作),可以通过将 MediaEventListener 附加到 MediaPlayer 来知道解析何时完成:
mediaPlayer.events().addMediaEventListener(new MediaEventListener() {
@Override
public void mediaParsedChanged(Media media, MediaParsedStatus newStatus) {
if (newStatus == MediaParsedStatus.DONE) {
// Do something
}
}
});
遗憾的是,我不确定如何为 MediaDiscoverer 实现这样的方法,因为我已经阅读了它的文档,但找不到任何类似的内容。我发现的唯一基本解决方案是使用 Thread.sleep(2000);紧接在
discoverer.start();
之后,但这显然不是一个理想的方法。有没有更可靠的方法来确定发现过程何时完成?
媒体发现器不断运行,直到停止。所以,从这个意义上说,发现永远不会结束。
在实践中,这意味着您的应用程序应该以处理动态变化的媒体列表而不是固定列表的方式进行编码。
这并不是说您停止应用程序直到发现完成然后呈现发现的项目,而是您的应用程序有一个动态播放列表,当发现者添加/删除项目时,该列表不断侦听事件。
当然,您根本不需要使用本机媒体发现器,您只需使用普通的 Java IO 即可查看自己包含媒体的标准位置(这就是您最初所做的,而且非常好)。