Java 如何从媒体对象获取元数据

Java 如何从媒体对象获取元数据,java,javafx,metadata,Java,Javafx,Metadata,我正在尝试用JavaFX制作一个mp3播放器,到目前为止,我已经让它能够加载歌曲并播放,但现在我想将媒体对象中的元数据显示到tableview中。我有一个作为模型类的song类,在我的controller类中,我有一个标签,我正在测试,看看是否可以得到要显示的元数据,但它总是以null形式出现 package application; import java.io.File; import javafx.collections.MapChangeListener; import javafx

我正在尝试用JavaFX制作一个mp3播放器,到目前为止,我已经让它能够加载歌曲并播放,但现在我想将媒体对象中的元数据显示到tableview中。我有一个作为模型类的song类,在我的controller类中,我有一个标签,我正在测试,看看是否可以得到要显示的元数据,但它总是以null形式出现

package application;

import java.io.File;

import javafx.collections.MapChangeListener;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

public class Song {
private File file;
private String title;
private String artist;
private String album;
private Media music;
private MediaPlayer mp;

public Song(File file) {
    music = new Media(file.toURI().toString());
    mp = new MediaPlayer(music);
    getMeta();
    artist = (String) mp.getMedia().getMetadata().get("artist");
    title = (String) music.getMetadata().get("title");
    album = (String) music.getMetadata().get("album");
    //artist = "test";
    //album = "test";
    //title = "test";
}


public void play() {
    mp.play();
}

public void pause() {
    mp.pause();
}

public void stop() {
    mp.stop();
}

public String getTitle(){
    return title;
}

public String getArtist(){
    return artist;
}

public String getAlbum(){
    return album;
}





}
在我的控制器类中

// Event Listener on Button[#loadBtn].onAction
@FXML
public void loadFile(ActionEvent event) {
    Node source = (Node) event.getSource();
    Window theStage = source.getScene().getWindow();
    //set fileChooser filter
    FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("MP3 files", "*.mp3");
    fileChooser.getExtensionFilters().add(extFilter);
    fileChooser.setTitle("Select MP3 files");
    //File file = fileChooser.showOpenDialog(theStage);
    //mySong = new Song(file);
    list = fileChooser.showOpenMultipleDialog(theStage);
    if(list!=null){
        for(File x: list) {
            mySong = new Song(x);
        }
    }
    label.setText(mySong.getTitle());
}
在最后一行中,我正在测试元数据是否被正确检索,并且它总是空的。我将标签设置为最初的“test”,这样我就可以知道它是否正在进行任何更改,并且它确实进行了更改,但不符合我的要求。

根据(我的重点):

可以从媒体实例获得关于媒体的信息,例如持续时间、元数据、曲目和视频分辨率媒体信息是异步获取的,因此不一定在类实例化后立即可用。但是,如果实例已与MediaPlayer关联,且该播放机已转换为MediaPlayer.Status.READY状态,则所有信息都应可用。为了在添加元数据或磁道时得到通知,可以分别向getMetadata()和getTracks()返回的集合注册观察者

所以你可以这样做:

public Song(File file) {
    music = new Media(file.toURI().toString());

    music.getMetadata().addListener((Change<? extends String, ? extends Object> c) -> {
        if (c.wasAdded()) {
            if ("artist".equals(c.getKey())) {
                artist = c.getValueAdded().toString();
            } else if ("title".equals(c.getKey())) {
                title = c.getValueAdded().toString();
            } else if ("album".equals(c.getKey())) {
                album = c.getValueAdded().toString();
            }
        }
    });

    mp = new MediaPlayer(music);

}
公共歌曲(文件){
音乐=新媒体(文件.toURI().toString());
music.getMetadata().addListener((根据(我的重点)更改):

有关媒体的信息,如持续时间、元数据、曲目和视频分辨率,可以从媒体实例获取。媒体信息是异步获取的,因此不一定在类实例化后立即可用。但是,如果实例已关联,则所有信息都应可用与MediaPlayer绑定,并且该播放器已转换为MediaPlayer.Status.READY状态。要在添加元数据或曲目时得到通知,可以分别使用getMetadata()和getTracks()返回的集合注册观察者

所以你可以这样做:

public Song(File file) {
    music = new Media(file.toURI().toString());

    music.getMetadata().addListener((Change<? extends String, ? extends Object> c) -> {
        if (c.wasAdded()) {
            if ("artist".equals(c.getKey())) {
                artist = c.getValueAdded().toString();
            } else if ("title".equals(c.getKey())) {
                title = c.getValueAdded().toString();
            } else if ("album".equals(c.getKey())) {
                album = c.getValueAdded().toString();
            }
        }
    });

    mp = new MediaPlayer(music);

}
公共歌曲(文件){
音乐=新媒体(文件.toURI().toString());

music.getMetadata().addListener((更改我尝试了您的解决方案,但它似乎仍然不起作用,我认为唯一的原因可能是我的mp3文件没有元数据?但它似乎起作用了如果(c.wasAdded()){System.out.println(c.getKey()+“:“+c.getValueAdded())}
查看是否有任何元数据被提取。如果你有一个十六进制编辑器,你可以用它打开MP3文件,看看是否可以在里面看到。好的,它在“song”类中提取元数据,但当我运行'code'System.out.println(“song title:+mySong.getArtist());在控制器类中的'code'输出“song title:null”在song类中,它输出“艺人:Foo Fighters album:Saint Cecilia EP title:Saint Cecilia”有什么想法为什么get方法会给出空值吗?@JohnSmith可能是因为您正在调用
mySong.getArtist()
设置艺术家属性之前…?在
艺术家
标题
专辑
歌曲
类中使用JavaFX属性,然后将标签的文本绑定到这些属性。实际上,我在错误的位置运行了打印行,但它确实有效。非常感谢!我尝试了您的解决方案a而且它似乎仍然不起作用,我能想到的唯一原因可能是我的mp3文件没有元数据?但它似乎起作用了如果(c.wasAdded()){System.out.println(c.getKey()+”:“+c.getValueAdded())}
查看是否有任何元数据被提取。如果你有一个十六进制编辑器,你可以用它打开MP3文件,看看是否可以在里面看到。好的,它在“song”类中提取元数据,但当我运行'code'System.out.println(“song title:+mySong.getArtist());在控制器类中的'code'输出“song title:null”在song类中,它输出“艺人:Foo Fighters album:Saint Cecilia EP title:Saint Cecilia”有什么想法为什么get方法会给出空值吗?@JohnSmith可能是因为您正在调用
mySong.getArtist()
在设置艺术家属性之前…?在
艺术家
标题
专辑
歌曲
类中使用JavaFX属性,然后将标签的文本绑定到这些属性。事实上,就是这样,我在错误的位置运行了打印行,但它确实有效。非常感谢!