如何在没有可显示组件的情况下获得Java中的VLC媒体播放器



我正在使用VLCJ绑定,终于能够遇到几个障碍。现在我来了。我(目前)不需要也不希望看到一个可见的媒体播放器组件(EmbeddedMediaPlayerComponent)。我现在只需要播放音频文件。我有以下方法来处理它:

public static void Play(File AudioFile){
    if (!LibVLCLoader.Loaded) LibVLCLoader.loadLibVLC();
    EmbeddedMediaPlayerComponent EMPC = new EmbeddedMediaPlayerComponent();
    if (EMPC.getMediaPlayer().prepareMedia(AudioFile.getAbsolutePath())){
        EMPC.getMediaPlayer().addMediaPlayerEventListener(new MediaPlayerEventAdapter(){
            @Override public void subItemFinished(MediaPlayer p, int i){
                EMPC.release(true);
            }
        });
        Platform.runLater(() -> EMPC.getMediaPlayer().play());
    }
}

但我一直得到这个例外:

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: The video surface component must be displayable

我理解。这很有道理。但我不需要它是可见的。我只需要声音。我怎样才能做到这一点?

EmbeddedMediaPlayer仅适用于希望在应用程序中嵌入视频表面的情况。

如果你只需要音频,有一个AudioMediaPlayerComponent明确用于此目的。

要创建这样的组件,只需:

AudioMediaPlayerComponent audioMediaPlayerComponent = 
    new AudioMediaPlayerComponent();

您可以将其子类化,例如自定义行为并轻松实现事件处理程序。

与使用通过MediaPlayerFactory创建的非组件媒体播放器相比,使用所谓的"组件"媒体播放器为您提供了一个稍微更好/更容易的API。

如果你的媒体是一个音频文件,这很好。

如果你的媒体实际上是视频,但你只想播放音轨,那么即使你默认使用AudioMediaPlayerComponent,VLC也会打开一个视频窗口。在这种情况下,您仍然需要实际禁用视频输出——最简单的方法是告诉VLC使用vcodec=dummy

我真的不同意像创建一个窗口并将其移出屏幕,或者将其缩小到1x1这样的技巧,这是没有必要的。

在原始问题中发布的代码中存在一个无关的问题。当Play()方法终止时,EMPCEMP变量将超出作用域,从而使媒体播放器有资格进行垃圾收集。将会发生的情况是,一段随机的时间后,您的应用程序可能会崩溃,因为vlcj使用的本地钩子将回调到一个不再存在的Java对象中。您需要通过硬引用保持媒体播放器引用的有效性。

好吧,这样你就可以在EmbeddedMediaPlayerComponent之外创建自己的MediaPlayer对象,如下所示:

public static void Play(File AudioFile){
    if (!LibVLCLoader.Loaded) LibVLCLoader.loadLibVLC();
    MediaPlayerFactory MPF = new MediaPlayerFactory(
        "--video-title=vlcj video output",
        "--no-snapshot-preview",
        "--quiet",
        "--quiet-synchro",
        "--sub-filter=logo:marq",
        "--intf=dummy"
    );
    EmbeddedMediaPlayer EMP = MPF.newEmbeddedMediaPlayer();
    if (EMP.prepareMedia(AudioFile.getAbsolutePath())){
        EMP.addMediaPlayerEventListener(new MediaPlayerEventAdapter(){
            @Override public void subItemFinished(MediaPlayer p, int i){
                EMP.release();
                MPF.release();
            }
        });
        Platform.runLater(() -> EMP.play());
    } else{
        EMP.release();
        MPF.release();
    }
}

最新更新