Vlcj: videoplayer.stop() verursacht JVM-Absturz unter Windows 11 (nur bestimmte Video-Codecs)Java

Java-Forum
Guest
 Vlcj: videoplayer.stop() verursacht JVM-Absturz unter Windows 11 (nur bestimmte Video-Codecs)

Post by Guest »

Nach der Migration meiner Java vlcj-Anwendung auf meinen neuen Windows 11-Computer stürzt das Programm beim Aufruf von vlcjplayer.stop() ab. Ich verwende vlcj4.8.2 in Kombination mit VLC3.0.21. Ich versende meine eigene Oracle JRE, die Version ist 17.0.12.
Dies ist der relevante Teil des Codes, den ich aufrufe (wobei stop() wird über eine Schaltfläche ActionListener aufgerufen und vlcPlayer ist vom Typ EmbeddedMediaPlayer):

Code: Select all

public void stop() {
submit(() -> vlcPlayer.stop());// new since vlcj-4: callback to VLC from a separate thread!
}

public void submit (final Runnable runnable) {
vlcPlayer.submit(runnable);
}
Einige Nebenfakten:
  • Der genau derselbe Code läuft einwandfrei unter Windows 10! Gleiche Java
    Version, gleiche VLC-Version, gleiche Version von vlcj, gleicher Build!
  • Das Problem tritt nur bei bestimmten Videokodierungen auf: mp4< /code>, mkv, ..., während ältere mpeg2-Videos das Problem nicht verursachen!
  • Wenn ich die problematischen Videos mit dem offiziellen vlcj-Test abspiele Anwendung treten keine Abstürze auf! Ich habe die jeweiligen Codeabschnitte verglichen, konnte aber keinen wirklichen Unterschied in der Art und Weise feststellen, wie die Stop-Methode aufgerufen wird.
  • Das Problem scheint nicht mit meinem spezifischen persönlichen System-Setup zusammenzuhängen. Es tritt auf jedem Windows 11-Computer auf, auf dem ich meine Anwendung bisher ausgeführt habe
Die VLC-Protokolldatei enthält keine Fehler. Der Prozess stürzt einfach ab, während Protokolle darauf geschrieben werden. Ich habe die Windows-Ereignisanzeige nach Fehlern durchsucht und konnte die entsprechenden Fehlerereignisse finden. So sehen sie aus (leider auf Deutsch):

Code: Select all

Fehlerhafter Anwendungsname: java.exe, Version: 17.0.12.0, Zeitstempel: 0x31da67d3
Fehlerhafter Modulname: libdirect3d11_filters_plugin.dll, Version: 3.0.21.0, Zeitstempel: 0x0075006c
Ausnahmecode: 0xc0000005
Fehleroffset: 0x000000000000155a
Fehlerhafte Prozess-ID: 0x1E5C
Fehlerhafte Anwendungsstartzeit: 0x1DB641EF886AD0F
Fehlerhafter Anwendungspfad: D:\Java_Programme\Jukebox\jre-17.0.12\bin\java.exe
Fehlerhafter Modulpfad: C:\Program Files\VideoLAN\VLC\plugins\d3d11\libdirect3d11_filters_plugin.dll
Berichts-ID: a6019a38-7882-422c-bafa-2b1fa2bd6f7c
Vollständiger Name des fehlerhaften Pakets:
Fehlerhafte paketbezogene Anwendungs-ID:
Ich habe verschiedene Dinge ausprobiert, wie zum Beispiel die Einstellung der Videoausgabe auf opengl statt auf direct3d11, und ich habe auch die entsprechenden Einstellungen im nativen VLC geändert, aber ohne Erfolg Wirkung. Irgendwie kann ich meinen Player nicht dazu bringen, ein anderes Videoausgabemodul zu verwenden. Andererseits möchte ich Benutzer sowieso nicht dazu zwingen, manuelle Änderungen an solchen Einstellungen vorzunehmen. Ich interessiere mich überhaupt nicht für Video-Codecs, den gesamten nativen Bibliothekskram und die Tiefe von VLC. Ich kämpfe jetzt seit ein paar Tagen damit und verstehe nicht, was falsch sein könnte. Wenn das Problem bei meinem Java-Code liegt, warum läuft er dann auf meinem alten Windows 10-Computer und mit älteren Codecs? Wenn das Problem bei VLC und den installierten Codecs liegt, warum kommt es dann nicht zum Absturz, wenn ich die vlcj-Testanwendung ausführe? Ich habe die neuesten GPU-Treiber installiert und habe eine saubere und frische Windows 11-Installation.

Jeder Hinweis wäre willkommen!
Bearbeiten 1:< /strong>
Es ist mir gelungen, einen Screenshot einer Fehlermeldung zu machen, die VLC in der Konsole protokolliert. (1) ist der Ort, an dem ich vlcplayer.stop() aufrufe, (2) ist der Ort, an dem der vlcj-Ereignishandler das Ereignis „stop()“ empfängt. Dazwischen wirft der native VLC einen Fehler (der natürlich zum Absturz führt):
Image

Bearbeiten [2]:

Unten ist der (abgespeckte) Code, den ich verwende. Die Kette der Methodenaufrufe ist wie folgt:
  • UI-Taste zum Stoppen des Videos wird gedrückt
  • videoPlayer.stop ()
  • submit(vlcPlayer.stop())
  • delegate.stop()
  • vlcDelegate. Controls().stop()
Dies ist die Benutzeroberfläche Klasse, in der das ursprüngliche Ereignis ausgelöst wird:

Code: Select all

public class MainFrame extends JFrame {

//...

public void actionPerformed (ActionEvent e) {
if (e.getSource() == stopVideoButton) {
videoPlayer.stop();
}
}

//...
}
Die VideoPlayer-Klasse ist ein Wrapper um die eigentliche VLC-Player-Instanz.

Code: Select all

public class VideoPlayer {

// the reference to the actual vlc player (interface)
private VLCVideoInterface vlcPlayer;
// the reference to the mediaplayer factory
private MediaPlayerFactory factory;

//...

// initialize the player
public void init (final Map args) {

final Vector enhancedVLCParams = Utilities.copy(vlcParams);
enhancedVLCParams.add("--file-caching=" + bufferSize);
enhancedVLCParams.add("--network-caching=" + bufferSize);

try {// provide VLC params!
factory = new VLCVideoPlayerFactory(enhancedVLCParams);
} catch (Exception e) {
// ...
}

// read FullScreenStrategy from arguments ...
FullScreenStrategy fullScreenStrategy = null;
if (args.containsKey(Argument.FULLSCREEN_STRATEGY)) {
fullScreenStrategy = (FullScreenStrategy)args.get(Argument.FULLSCREEN_STRATEGY);
}

vlcPlayer = factory.newEmbeddedMediaPlayer();// create the vlc player!
vlcPlayer.setFullscreenStrategy(fullScreenStrategy);// assign fs strategy
vlcPlayer.addMediaPlayerEventListener(vlcEventHandler);// attach event handler to catch vlcj events

if (Platform.isWindows()) {
vlcPlayer.setEnableKeyInputHandling(false);
vlcPlayer.setEnableMouseInputHandling(false);
}

vlcPlayer.setLogoFile(VLCJ_LOGO.getPath());
vlcPlayer.setLogoOpacity(0.55f);
vlcPlayer.setLogoLocation(10, 10);
}

// stops the video player. This method is exposed to the outside world
public void stop() {
if (!isPlaying()) {
return;
}
submit(() -> vlcPlayer.stop());// new since vlcj-4: callback to VLC from a separate thread!
}

// calls to the vlc layer happen in a separate thread
public void submit (final Runnable runnable) {
vlcPlayer.submit(runnable);
}

//...
}
Diese Klasse ist meine MediaPlayerFactory, die den VLC-Player erstellt

Code: Select all

public final class VLCVideoPlayerFactory extends MediaPlayerFactory {

// Constructor
public VLCVideoPlayerFactory (final List libvlcArgs) {
super(libvlcArgs);// Delegation an die Superklasse
}

// creates the vlc player instance
public VLCVideoPlayer newEmbeddedMediaPlayer() {
return new VLCVideoPlayer(libvlcInstance);
}
}
Der VLCVideoPlayer ist eine Fassade, die die Implementierung des eigentlichen VLC-Players verbirgt. Der VideoPlayer nutzt die Fassade

Code: Select all

public final class VLCVideoPlayer extends EmbeddedMediaPlayer implements VLCVideoInterface {

private VLCVideoInterface delegate;

// constructor
VLCVideoPlayer (final libvlc_instance_t instance) {
super(instance);
this.delegate = new VLCVideoInterfaceImpl(this);
}

public void stop() {
delegate.stop();
}
}
Diese Klasse repräsentiert den eigentlichen VLC-Videoplayer

Code: Select all

class VLCVideoInterfaceImpl extends VLCInterfaceImpl implements VLCVideoInterface {

// constructor
VLCVideoInterfaceImpl (final EmbeddedMediaPlayer mediaPlayer) {
super(mediaPlayer);
}

// stops the vlc player
public void stop() {
vlcDelegate.controls().stop();// this is the actual vlc stop call!
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post