mediaPlayer.setSpu() 不工作

mediaPlayer.setSpu() not working

目前我正在编写一些基于 VLCJ 的代码来播放视频内容,它工作得很好,但我正在努力使 setSpu() 方法正常工作。

顺便提一下,在加载外部字幕时,在视频文件之外的文件中,它工作正常。当我尝试播放媒体文件中包含的字幕时出现问题。 (例如 MKV 文件中包含的潜艇)。

仔细阅读了GitHubpost"setSpu not working #278",我想可能是我没有正确调用setSpu()方法。

为简单起见,我试图让它在示例中运行 "uk.co.caprica.vlcj.test.basic.TestPlayer"。

在 TestPlayer.java class 上,我加载了所有本机 vlc 所需的库并配置了 mediaPath 和 mediaPlayer,因此如果我执行 class,媒体播放器会正确构建,然后视频开始播放。

现在,为了尝试使字幕正常工作,我在 "PlayerControlsPanel.java" 上重复使用了按钮 "subTitlesButton"。首先,由于要设置的spu是TrackDescription的ID,我添加了如下代码,执行得到spuDescriptions列表:

subTitlesButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            System.out.println(mediaPlayer.getSpuDescriptions());
        }
    });

当按下 Sub-titles 按钮时,得到以下输出:

spuDescriptions=[TrackDescription[id=-1,description=Deshabilitar], TrackDescription[id=3,description=Pista 1 - [Español]], TrackDescription[id=4,description=Pista 2 - [Inglés]], TrackDescription[id=5,description=Pista 3 - [Español]]]

所以,为了简单起见,我只是尝试添加以下代码并执行它:

subTitlesButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            System.out.println(mediaPlayer.getSpuDescriptions());
            mediaPlayer.setSpu(3); // TrackDescription[id=3,description=Track 1 - [Spanish]]
        }
    });

预期的结果是 ID=3 的字幕 "Track 1 - [Spanish]" 出现在屏幕上,但没有任何反应。视频继续播放并正常播放,但未显示 sub-title。

所有其他按钮,当你按下它们时工作正常,你会得到预期的结果(暂停、停止、播放、快进、倒回等等)...所以我不明白为什么 media.setSpu() 在那里不工作。

非常感谢您的帮助:) 提前致谢。

EDITED 确切的问题是媒体文件 (video.mkv) 中包含的所有字幕都是 UTF8 文本编码的。我尝试使用 mkvmerge re-mount video.mkv 文件,但这个程序总是将 SRT 文件转换为 UTF8 文本格式。 解决方法 将 SRT 文件转换为 ASS 字幕格式。如果 video.mkv 包含 .ASS 字幕格式,则 VLC 和 vlcj 库都能正确加载字幕。

非常感谢您提供的所有帮助。

如果这个问题可以归结为如何使用非 ASCII 字符的外部 SPU 文件,您可以试试这个:

假设您有一些外部 SPU 文件的文件名,该文件名包含非 ASCII 字符,我们称其为 spuFileName...

尝试:

String asciiFileName = new File(spuFileName)
    .toURI()
    .toASCIIString();

或者:

String asciiFileName = new File(spuFileName)
    .toURI()
    .toASCIIString()
    .replaceFirst("file:/", "file:///");

然后在为 vlcj 指定 SPU 文件时使用 asciiFileName

如果我没记错的话,LibVLC 在其 API 上需要 ASCII 字符串。如果您尝试播放文件名包含非 ASCII 字符的视频(vlcj 会检测到并自动处理),也会出现此问题。

但我不确定这是否真的是您的问题,因为根据您发布的部分日志,看起来 VLC 确实已正确检测到 SPU 轨道。

另一方面,如果这个建议确实有效,可以更改 vlcj 以自动处理这种情况(外部 SPU 文件)。

在实际选择 SPU 进行显示时,无论 SPU 是在单独的文件中还是包含在视频本身中,唯一重要的是 SPU 轨道的 ID。 vlcj 将此 id 直接传递给 LibVLC API 方法。轨道描述字符串没有被直接编码这一事实并不重要。

在早期版本的 VLC 中,这个 id 实际上是 SPU 轨道的 index - 所以 0、1、2、3 等等。

对于当前版本的 VLC(这是在 2013 年 2 月左右更改的,我认为这意味着 VLC 2.1+)已修复为使用实际的 SPU 轨道标识符。

因此,根据您的 VLC 版本,如果曲目标识符对您不起作用,请尝试传递索引。