java - 使用 DirectMediaPlayer 通过 vlcj 播放大型视频 (FullHD+)

标签 java vlc libvlc vlcj

我必须在 Java/OpenGL 应用程序中播放相当大的视频,在某些情况下为 UHD (4000x2000)。我现在选择使用 VLCJ 来执行此操作(无法让 GStreamer 足够快地解码)。 使用普通嵌入式播放器时,VLC 本身可以像 VLCJ 一样正常播放视频。

当我使用 directplayer 时,较大的视频开始播放并在几帧后停止,或者根本不开始(仍调用 display(),但始终使用同一帧!)。对我来说,开始于 HDReady(1280x720 仍然可以正常播放)和 FullHD(1920x1080)之间。这似乎与 PC 的性能无关。我在一台已有 5 年历史的笔记本电脑和一台高端机器上进行了测试,结果完全相同。 如果我做错了什么或者 VLCJ DirectPlayer 无法处理更大的视频,您有什么想法吗?

我正在使用 VLC 2.0.0(也尝试过 2.0.3 和 2.0.4)以及来自 github 的最新 VLCJ。

我在线登录:http://pastebin.com/UeyMrVmW

我附上了一个简单的示例,如何设置重现问题的直接播放器。

public class VLCTestPlayer implements RenderCallback, BufferFormatCallback {

protected MediaPlayerFactory mediaPlayerFactory;

protected DirectMediaPlayer mediaPlayer;

public static void main(final String[] args) {
    NativeLibrary.addSearchPath("libvlc",
            "C:\\Program Files (x86)\\VideoLAN\\VLC");
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            VLCTestPlayer testplayer = new VLCTestPlayer(args);
        }
    });
}

private VLCTestPlayer(String[] args) {

    JFrame frame = new JFrame("vlcj Tutorial");

    mediaPlayerFactory = new MediaPlayerFactory("--no-video-title-show", "--verbose=3");

    mediaPlayer = mediaPlayerFactory.newDirectMediaPlayer(this, this);

    String videoFile = "myVideo.mp4";
    boolean started = mediaPlayer.prepareMedia(videoFile);

    if (started)
        mediaPlayer.play();
    System.out.println("Video started: " + started + " from: " + videoFile);

    frame.setLocation(100, 100);
    frame.setSize(1050, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

@Override
public BufferFormat getBufferFormat(int sourceWidth, int sourceHeight) {
    sourceWidth = sourceWidth / 1;
    sourceHeight = sourceHeight / 1;
    System.out.println("Got VideoFormat: " + sourceWidth + "x"
            + sourceHeight);
    BufferFormat format = new BufferFormat("RGBA", sourceWidth,
            sourceHeight, new int[] { sourceWidth * 4 },
            new int[] { sourceHeight });

    return format;
}

@Override
public void display(DirectMediaPlayer mediaPlayer, Memory[] nativeBuffers,
        BufferFormat bufferFormat) {

    ByteBuffer buffer = nativeBuffers[0].getByteBuffer(0,
            (int) bufferFormat.getWidth() * (int) bufferFormat.getHeight()
                    * 4);
    int pos = 4 * ((int) bufferFormat.getWidth()
            * (int) bufferFormat.getHeight() / 2 + (int) bufferFormat
            .getWidth() / 2) + 700;
    System.out.println("Got VideoFrame: " + buffer.get(pos) + ":"
            + buffer.get(pos + 1) + ":" + buffer.get(pos + 2) + ":"
            + buffer.get(pos + 3));
}
}

最佳答案

我想说,尽管您进行了测试,但这几乎肯定是一个性能问题 - 根据我用直接播放器播放高清视频的经验,即使在现代系统上,您所做的方式也行不通,没有硬件加速,它就无法应对。作为粗略的指导,我使用了 6 个月的 i5 台式机几乎无法管理 720p 视频。 (顺便说一句,你在那里的 println 语句肯定不会有任何帮助,当每秒执行多次时,它们可能会比你想象的花费更多的时间。)

但是,可取之处在于您应该能够使用 JavaFX 及其提供的硬件加速类来使其工作 - 请参阅 here了解详情。

关于java - 使用 DirectMediaPlayer 通过 vlcj 播放大型视频 (FullHD+),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13248643/

相关文章:

java - Android 中 R 类导入错误

java - ActiveMQ 消息驱动 bean 到 JSF

java - 如何在liferay中使用集合

c# - 连续播放 VLC 播放列表中的不同视频文件

java - 在多个窗口中使用克隆的 VLCJ

android - 为 x86 构建 LibVLC

c++ - 使用 libvlc_video_set_format_callbacks 逐帧转码视频

java - 将数组与对象一起使用? java

objective-c - 在基于 Swift 的项目中导入 VLCKit(在 c59cb1b 之后)

c# - 如何将 VLC 嵌入到我的 C# 项目中?