【问题标题】:JVM crashes when releasing a VLCJ MediaPlayer释放 VLCJ MediaPlayer 时 JVM 崩溃
【发布时间】:2017-04-09 22:38:17
【问题描述】:

我使用的是带有 Java 8u121 的 OS X 10.11.6,我正在尝试使用 VLCJ 3.10.1(带有 VLC 2.2.4)对音频文件(从 MP3 到 OGG Vorbis)进行转码。转码似乎工作正常,但在发布MediaPlayer 时出现错误。

下面是我的最小测试代码,基于来自 VLCJ 存储库的 RipAudioTest

public class VlcjTestMain {

    public static void main(String[] args) throws InterruptedException {
        Path sourceFile = // source file here
        Path targetFile = // target file here

        new NativeDiscovery().discover();
        MediaPlayerFactory factory = new MediaPlayerFactory();
        MediaPlayer player = factory.newHeadlessMediaPlayer();

        CountDownLatch latch = new CountDownLatch(1);
        player.addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            @Override
            public void finished(MediaPlayer mediaPlayer) {
                latch.countDown();
            }

            @Override
            public void error(MediaPlayer mediaPlayer) {
                System.out.println("Rip failed");
                latch.countDown();
            }
        });

        String transcodeOpts =
                ":sout=#transcode{acodec=vorb,vcodec=dummy}:std{dst=" + targetFile.toAbsolutePath().toString() + ",mux=ogg,access=file}";
        player.playMedia(
                sourceFile.toAbsolutePath().toString(),
                transcodeOpts);

        latch.await();
        System.out.println("Finished!");

        player.release();
        System.out.println("Player released");

        factory.release();
        System.out.println("Factory released");
    }
}

转码成功完成,但在player.release(),JVM 崩溃并出现 SIGSEGV 错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00000001224e8649, pid=13561, tid=0x000000000000c253
#
# JRE version: Java(TM) SE Runtime Environment (8.0_121-b13) (build 1.8.0_121-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libvlc.dylib+0x6649]  libvlc_event_send+0x19
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

崩溃日志can be seen here的其余部分。

有谁知道这是什么原因造成的?

【问题讨论】:

  • 根据您发布的转储,在您在 Java 端发布媒体播放器后,本机代码可能仍在向您发送事件(通过 libvlc_event_send)。某处可能存在排序问题,或者可能是 vlcj 清理中的错误。我不确定。
  • 有趣,我想我会尝试记录事件侦听器收到的所有事件,并在释放媒体播放器之前稍等片刻,看看我得到了什么......我会在什么时候更新我的问题我试过了。我还将尝试在 Windows 上重复我的测试,看看是否有所不同。
  • 这很难,因为 vlcj 的 release() 清理实际上在其他任何事情之前明确地取消注册本机事件侦听器。也许这在 vlcj github 项目页面上作为一个问题会更好,由您决定。
  • 我会先看看能不能找到更多,但我可能稍后会打开一个 github 问题,是的。
  • 我已经根据我的观察发布了一个答案 - 我认为这个问题确实可能是由finished 之后触发的事件引起的,尽管我试图释放媒体播放器(当然,我可以只有当我立即释放媒体播放器时才能看到这些事件,所以我可能是错的......)。我的猜测是,我应该将其报告为错误?

标签: java jna vlcj


【解决方案1】:

感谢 caprica 的 cmets,我想我能够回答我的问题。

tl;dr:finished 事件之后,VLC 仍然会触发另外两个事件:mediaChangednewMedia。如果在释放播放器后发生这种情况,它会崩溃。

现在,这里是我的实验细节...

我在 Windows 10 上尝试了相同的代码。它有时可以工作,但最常在 player.release() 上引发错误 java.lang.Error: Invalid memory access

然后我尝试在player.release() 之前添加Thread.sleep(1000) 语句,但我无法再重现崩溃。

所以我使用了一个事件侦听器来记录大多数事件,并将Thread.sleep(1000) 语句保留在player.release() 之前。我注意到在finished 之后收到了两个事件:首先是mediaChanged,然后是newMedia。以下是日志结尾的样子:

mediaStateChanged
finished
Finished!
mediaChanged
newMedia
[00000000209f45b0] mux_ogg mux: Close [this line logged by VLCJ, not by me]
Player released
Factory released

最后,我还尝试删除sleep 语句,但在第二个newMedia 事件(而不是第一个finished 事件)之后调用player.release(),我也无法重现崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多