2017-04-09 136 views
2

我在OS X 10.11.6上使用Java 8u121,并试图使用VLCJ 3.10.1(使用VLC 2.2.4)将音频文件(从MP3到OGG Vorbis)。代码转换似乎工作正常,但在发布MediaPlayer时出现错误。JVM在发布VLCJ MediaPlayer时崩溃

贝娄是我最小的测试代码的基础上,RipAudioTest从VLCJ回购:

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

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

+0

根据您发布的转储,在Java端发布媒体播放器后,可能本机代码仍然会向您发送一个事件(通过libvlc_event_send)。某处可能存在排序问题,或者可能是vlcj清理中的错误。我不确定。 – caprica

+0

有趣的是,我想我会尝试记录事件监听器接收到的所有事件,并在释放媒体播放器之前等待一下,看看我得到了什么......当我尝试过时,我会更新我的问题。我也会尝试在Windows上重复我的测试,看看它是不同的。 –

+0

这很困难,因为vlcj的release()清除实际上在任何其他事情之前实际上明确地注销了本地事件侦听器。也许这在vlcj github项目页面上更好,因为你自己。 – caprica

回答

0

我想我能够回答我的问题,这要感谢caprica的评论。

TL;博士:finished活动结束后,VLC仍然激发其他两个事件:mediaChangednewMedia。如果在释放播放器后发生这种情况,则会崩溃。

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

我试图在Windows 10相同的代码有时候工作,但最常见于player.release()引发错误java.lang.Error: Invalid memory access

然后我试着在player.release()之前添加一条Thread.sleep(1000)声明,我不能再重现崩溃。

所以我用了一个事件监听器来记录大多数事件,并在player.release()之前保留Thread.sleep(1000)声明。我注意到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(),我也无法重现碰撞。

+0

有趣。嗯... – caprica