Windows 11下调用videoplayer.stop()触发JVM崩溃(仅特定编解码器)
Windows 11下vlcj调用
stop()时程序崩溃问题 环境信息
- vlcj 4.8.2
- VLC 3.0.21
- 自研Oracle JRE 17.0.12
问题描述
基于Java vlcj开发的应用迁移至Windows 11设备后,调用vlcjplayer.stop()时程序会崩溃。stop()由按钮ActionListener触发,vlcPlayer为EmbeddedMediaPlayer类型。
相关调用代码
public void stop() { submit(() -> vlcPlayer.stop());// vlcj-4新增:通过独立线程回调VLC! } public void submit (final Runnable runnable) { vlcPlayer.submit(runnable); }
补充情况
- 完全相同的代码、Java/VLC/vlcj版本及构建包在Windows 10上运行正常;
- 仅特定视频编码(如
mp4、mkv)会触发问题,旧版mpeg2视频无此现象; - 使用官方vlcj测试应用播放问题视频时不会崩溃,对比代码未发现调用方式差异;
- 该问题并非个人系统独有,所有测试过的Windows 11设备均出现此问题。
错误日志
VLC日志无错误记录,进程在写入日志时崩溃。Windows事件查看器捕获到以下错误信息:
错误应用名称: java.exe, 版本: 17.0.12.0, 时间戳: 0x31da67d3
错误模块名称: libdirect3d11_filters_plugin.dll, 版本: 3.0.21.0, 时间戳: 0x0075006c
异常代码: 0xc0000005
错误偏移量: 0x000000000000155a
错误进程ID: 0x1E5C
错误应用启动时间: 0x1DB641EF886AD0F
错误应用路径: D:\Java_Programme\Jukebox\jre-17.0.12\bin\java.exe
错误模块路径: C:\Program Files\VideoLAN\VLC\plugins\d3d11\libdirect3d11_filters_plugin.dll
报告ID: a6019a38-7882-422c-bafa-2b1fa2bd6f7c
错误包全名:
错误包相关应用ID:
已尝试的解决方案
- 尝试将视频输出设置为
opengl替代direct3d11,修改原生VLC对应设置均无效,无法切换视频输出模块,且不想强制用户手动修改设置; - 已安装最新GPU驱动,系统为全新Windows 11,目前仍无法定位问题原因。
崩溃场景说明
调用vlcplayer.stop()后,在vlcj事件处理器接收stopped()事件的期间,原生VLC抛出错误导致程序崩溃。
正常运行的代码示例
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EtchedBorder; import uk.co.caprica.vlcj.filefilters.swing.SwingFileFilterFactory; import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent; /** * @author Oender */ public class VLCJTest extends JFrame { private static final long serialVersionUID = 1L; private EmbeddedMediaPlayerComponent playerComponent; /** * Constructor */ public VLCJTest() { super.setTitle("VLCJ Test (fixed)"); super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); playerComponent = new EmbeddedMediaPlayerComponent(); initComponents(); } /** * Initialize & arrange components */ private void initComponents() { final JPanel content = new JPanel (new BorderLayout()); content.setPreferredSize (new Dimension(400,300)); final JPanel buttonPanel = new JPanel(); buttonPanel.setBorder(new EtchedBorder()); final JButton openButton = new JButton("Open"); openButton.setFocusable(false); final JButton stopButton = new JButton("Stop Video"); stopButton.setFocusable(false); // attach ActionListener openButton.setActionCommand("Open"); openButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { final JFileChooser chooser = new JFileChooser(); chooser.setFileFilter(SwingFileFilterFactory.newMediaFileFilter()); final int state = chooser.showOpenDialog(null); if (state == JFileChooser.APPROVE_OPTION) { playerComponent.mediaPlayer().media().play(chooser.getSelectedFile().getPath()); } } }); // attach ActionListener stopButton.setActionCommand("Stop"); stopButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { playerComponent.mediaPlayer().controls().stop(); } }); buttonPanel.add(openButton); buttonPanel.add(stopButton); content.add(buttonPanel, BorderLayout.NORTH); content.add(playerComponent, BorderLayout.CENTER); super.setContentPane(content); super.pack(); super.setVisible(true); } /** * @param args */ public static void main (String[] args) { new VLCJTest().setVisible(true); } }
触发崩溃的代码示例
import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EtchedBorder; import com.sun.jna.NativeLibrary; import uk.co.caprica.vlcj.factory.MediaPlayerFactory; import uk.co.caprica.vlcj.filefilters.swing.SwingFileFilterFactory; import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer; import uk.co.caprica.vlcj.player.embedded.videosurface.ComponentVideoSurface; /** * @author Oender */ public class VLCJTest extends JFrame { private static final long serialVersionUID = 1L; private EmbeddedMediaPlayer player; /** * Constructor */ public VLCJTest() { super.setTitle("VLCJ Test (crash)"); super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final Canvas videoCanvas = new Canvas(); player = initPlayer(videoCanvas); initComponents(videoCanvas); } /** * Initialize & arrange components * @param videoCanvas */ private void initComponents (final Canvas videoCanvas) { final JPanel content = new JPanel (new BorderLayout()); content.setPreferredSize (new Dimension(400,300)); final JPanel buttonPanel = new JPanel(); buttonPanel.setBorder(new EtchedBorder()); final JButton openButton = new JButton("Open"); openButton.setFocusable(false); final JButton stopButton = new JButton("Stop Video"); stopButton.setFocusable(false); // attach ActionListener openButton.setActionCommand("Open"); openButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { final JFileChooser chooser = new JFileChooser(); chooser.setFileFilter(SwingFileFilterFactory.newMediaFileFilter()); final int state = chooser.showOpenDialog(null); if (state == JFileChooser.APPROVE_OPTION) { player.media().play(chooser.getSelectedFile().getPath()); } } }); // attach ActionListener stopButton.setActionCommand("Stop"); stopButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent e) { player.controls().stop(); } }); buttonPanel.add(openButton); buttonPanel.add(stopButton); content.add(buttonPanel, BorderLayout.NORTH); content.add(videoCanvas, BorderLayout.CENTER); super.setContentPane(content); super.pack(); super.setVisible(true); } /** * create the EmbeddedMediaPlayer * @param canvas * @return */ private EmbeddedMediaPlayer initPlayer (final Canvas canvas) { final MediaPlayerFactory factory = new MediaPlayerFactory(); final ComponentVideoSurface videoSurface = factory.videoSurfaces().newVideoSurface(canvas); final EmbeddedMediaPlayer mPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer(); mPlayer.videoSurface().set(videoSurface); mPlayer.video().setAdjustVideo(true); return mPlayer; } /** * @param args */ public static void main (String[] args) { NativeLibrary.addSearchPath("libvlc", "C:\\Program Files\\VideoLAN\\VLC"); new VLCJTest().setVisible(true); } }
内容的提问来源于stack exchange,提问作者Bate
相关产品推荐
相关产品推荐

