Page 1 of 1

JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 27 Aug 2008 10:39
by jgg
]*************************************************************
**** Jump to the third post, please. Thanks. Javi ****
*************************************************************

Hi,

I have written a simple Swing-based JVLC client with the latest 0.9.0-test3 jar library and I have experienced some problems with the Swing integration and the playlist management. I use Ubuntu Linux 8.04 and JDK/JRE 1.6 update 7.

First, the only way I can have a visible integrated JVLC canvas is adding it directly to the JFrame container, having this a border layout and adding the canvas with the center position, while adding button and other panels in north and south positions. I can't use vertical/horizontal box or flow layouts because when launching the application I get a "Content must be displayable" error immediately (even using a flow layout and only adding the canvas). Is there any solution to this issue? Why can't I treat the JVLC canvas as any other Swing component?

On the other side, I have tried to use MediaList and MediaListPlayer classes from the new 0.9.0 JVLC API instead the deprecated Playlist one, but I have got no success. My simple application just adds video files to a list (add button) and allows playing and other simple actions (play, stop, next, mute... buttons). With the deprecated Playlist class I can add and play different video files with no problem, but when I create a MediaList with the new API and add some video files, using the play() and next() methods from the MediaListPlayer class I get an error and the program stops running.

This is the code of my simple application:

Code: Select all

package test; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import org.videolan.jvlc.Audio; import org.videolan.jvlc.JVLC; import org.videolan.jvlc.MediaDescriptor; import org.videolan.jvlc.MediaList; import org.videolan.jvlc.MediaListPlayer; import org.videolan.jvlc.MediaPlayer; import org.videolan.jvlc.Playlist; import org.videolan.jvlc.VLCException; import org.videolan.jvlc.Video; public class GUITest extends JFrame { private JButton playButton, addButton, stopButton, pauseButton, muteButton, nextButton, prevButton, fullscreenButton; private JTextField mrlField; private JPanel buttonPanelUp, buttonPanelBottom, textEntryPanel, buttonPanel; private Canvas canvas; private Container container; private JVLC jvlc; private MediaList mediaList; private MediaListPlayer mediaListPlayer; private MediaDescriptor mediaDescriptor; private Audio audio; private Video video; private Playlist playlist; public GUITest(){ super("JVLC GUI test"); setPreferredSize(new Dimension(500, 500)); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // VIDEO FRAME // New canvas = new Canvas(); jvlc = new JVLC(); mediaList = jvlc.getMediaList(); mediaListPlayer = new MediaListPlayer(jvlc); mediaListPlayer.setMediaList(mediaList); video = new Video(jvlc); audio = new Audio(jvlc); // Deprecated playlist = new Playlist(jvlc); // BUTTONS playButton = new JButton("Play"); playButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ play(); } }); pauseButton = new JButton("Pause"); pauseButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ pause(); } }); stopButton = new JButton("Stop"); stopButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stop(); } }); muteButton = new JButton("Mute"); muteButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ mute(); } }); fullscreenButton = new JButton("Full Screen"); fullscreenButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ fullscreen(); } }); nextButton = new JButton("Next"); nextButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ next(); } }); prevButton = new JButton("Prev"); prevButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ prev(); } }); addButton = new JButton("Add"); addButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ add(); } }); // TEXT FIELD mrlField = new JTextField("/home/dulceangustia/diptvServerLinux32/contents/", 40); // PANELS buttonPanelUp = new JPanel(new FlowLayout()); buttonPanelUp.add(playButton); buttonPanelUp.add(pauseButton); buttonPanelUp.add(stopButton); buttonPanelUp.add(fullscreenButton); buttonPanelBottom = new JPanel(new FlowLayout()); buttonPanelBottom.add(muteButton); buttonPanelBottom.add(prevButton); buttonPanelBottom.add(nextButton); buttonPanelBottom.add(addButton); textEntryPanel = new JPanel(new FlowLayout()); textEntryPanel.add(mrlField); buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); buttonPanel.add(buttonPanelUp); buttonPanel.add(buttonPanelBottom); container = getContentPane(); container.setLayout(new BorderLayout()); container.add(canvas, BorderLayout.CENTER); container.add(buttonPanel, BorderLayout.NORTH); container.add(textEntryPanel, BorderLayout.SOUTH); pack(); setVisible(true); jvlc.setVideoOutput(canvas); } private void play() { mediaListPlayer.playItem(0); // With the deprecated playlist class /*try { playlist.play(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void pause() { if (mediaListPlayer.isPlaying()) mediaListPlayer.pause(); else mediaListPlayer.play(); // With the deprecated playlist class /*try { playlist.togglePause(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void stop() { if (mediaListPlayer.isPlaying()) mediaListPlayer.stop(); // With the deprecated playlist class /*try { playlist.stop(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void mute() { audio.toggleMute(); } private void fullscreen() { //video.toggleFullscreen(mediaListPlayer); } private void next() { mediaListPlayer.next(); // With the deprecated playlist class /*try { playlist.next(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void prev() { //mediaListPlayer.playItem(); // With the deprecated playlist class /*try { playlist.prev(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void add() { mediaDescriptor = new MediaDescriptor(jvlc, mrlField.getText().toString()); mediaList.addMedia(mediaDescriptor); // With the deprecated playlist class /*try { playlist.add(mrlField.getText().toString(), mrlField.getText().toString()); } catch (VLCException e) { e.printStackTrace(); }*/ } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new GUITest(); } }); } }

And this is the error message that appears when I click the next button when I have more than one item in the MediaList:

Code: Select all

[00000001] main libvlc debug: VLC media player - version 0.9.0-test3 Grishenko - (c) 1996-2008 the VideoLAN team [00000001] main libvlc debug: libvlc was configured with ./configure '--mandir=/share/man' '--build=i486-linux-gnu' '--enable-maintaner-mode' '--enable-release' '--prefix=/usr' '--enable-libtool' '--enable-fast-install' '--disable-update-check' '--disable-gnome' '--disable-gtk' '--disable-familiar' '--disable-fb' '--enable-ggi' '--enable-sdl' '--enable-esd' '--enable-mad' '--enable-arts' '--enable-jack' '--enable-pulse' '--enable-lirc' '--enable-a52' '--enable-aa' '--enable-dvbpsi' '--enable-mozilla' '--disable-kde' '--enable-mp4' '--enable-dvb' '--disable-satellite' '--enable-ogg' '--enable-vorbis' '--enable-shout' '--enable-wxwidgets' '--with-wx-config=wx-config' '--enable-qt4' '--disable-slp' '--enable-flac' '--disable-skins' '--disable-basic-skins' '--enable-skins2' '--enable-freetype' '--enable-mkv' '--enable-speex' '--enable-caca' '--enable-live555' '--enable-libmpeg2' '--enable-fribidi' '--enable-cdio' '--enable-mod' '--enable-theora' '--enable-modplug' '--enable-dvdnav' '--enable-gnutls' '--enable-ffmpeg' '--enable-ncurses' '--enable-smb' '--disable-gnomevfs' '--enable-bonjour' '--enable-mpc' '--enable-vcd' '--enable-vcdx' '--enable-notify' '--enable-debug' '--enable-twolame' '--enable-x264' '--enable-faad' '--disable-zvbi' '--enable-telx' '--enable-mediacontrol-bindings' '--disable-x264' '--disable-atmo' '--enable-alsa' '--enable-dv' '--enable-v4l' '--enable-v4l2' '--enable-pvr' '--enable-svgalib' '--enable-dvd' '--without-dvdcss' 'build_alias=i486-linux-gnu' 'CFLAGS=-g -O2' 'LDFLAGS=-Wl,-Bsymbolic-functions' 'CPPFLAGS=' 'CXXFLAGS=-g -O2' [00000001] main libvlc debug: translation test: code is "C" *** LibVLC Exception not handled: No active input Set a breakpoint in 'libvlc_exception_not_handled' to debug. LibVLC fatal error locking mutex in thread 3040652176 at control/media_list.c:174: 35 Error message: Resource deadlock avoided at: /usr/lib/libvlccore.so.0(vlc_pthread_fatal+0xa7)[0xb5301207] /usr/lib/libvlc.so(libvlc_media_list_release+0xa5)[0xb5361c15] /usr/lib/libvlc.so(libvlc_media_list_player_next+0x499)[0xb5362e59] /tmp/jna42322.tmp(ffi_call_SYSV+0x17)[0xb5376f7f] /tmp/jna42322.tmp(ffi_call+0x52)[0xb5376d42] /tmp/jna42322.tmp[0xb536d457] /tmp/jna42322.tmp(Java_com_sun_jna_Function_invokeVoid+0x32)[0xb536dc74] [0xb5d60e9d] [0xb5d59edd] [0xb5d59d77] [0xb5d59d77] [0xb5d59d77] [0xb5d5a253] [0xb5d5a3b9] [0xb5d59edd] [0xb5d59edd] [0xb5d59edd] [0xb5d5a3b9] [0xb5d59edd] [0xb5d5a3b9]
Note that, as randgen22 said, I must use the playItem(0) method instead of play() to start playing the created playlist with MediaList. Is this the way it should be or play() should work as well?

In addition, it seems that there is no implemented method in MediaListPlayer to play the previous item in the playlist as it exists in the deprecated Playlist class. Will it eventually be implemented?

And last but not least, how can I set the full screen mode to a playing media from a MediaList? The Video class has setFullscreen(MediaPlayer, boolean) and toggleFullscreen(MediaPlayer) methods to do that, but they need a MediaPlayer instance, which is only created for a specific file and not for a MediaList, which needs a MediaListPlayer instead a MediaPlayer, so... what should I do to toggle the fullscreen option?


Hope somebody can help me with these issues. Your help is much appreciated.


Thank you,
Javi

Re: JVLC Playlist and Swing integration issues

Posted: 02 Sep 2008 09:58
by jgg
Any idea?

Re: JVLC Playlist and Swing integration issues

Posted: 04 Sep 2008 12:35
by jgg
I update with some issues' reports:


The problems:

1. Once the MediaList has been created with one or more elements through either MediaList.addMedia(String) or MediaList.addMedia(MediaDescriptor) (the two methods have the same effect), when MediaListPlayer.play() is executed this message appear in the console:

Code: Select all

[color=#FF0000]*** LibVLC Exception not handled: No more element to play Set a breakpoint in 'libvlc_exception_not_handled' to debug[/color].
Just the same message as if I try to play with an empty MediaList. Anyway, calling MediaList.size() after each MediaList.add(MediaDescriptor) execution shows a proper number corresponding the added items. I have noticed that the MediaList class has an 'items' ArrayList, which is only used for checking procedures, so the actual MediaList management is done through the Libvlc methods. In order to get it working properly it must be used the MediaListPlayer.playItem(int) and similar methods.

2. Once the playlist has started to be played through MediaListPlayer.playItem(0), when the first item finishes the player stops. If I call MediaListPlayer.next() while playing the first playlist item (before it reaches its end) the application becomes blocked at this call while the item 0 continues playing till its end, so it seems that the 'next'method implementation has some problems (Maybe this method is called as well when the MediaListPlayer listeners get a 'end-reached'-like event, so that could be a connection between the errors). Anyway, the MediaListPlayer.next() method code is quite simple as it only delegates on the Libvlc C function (just as the MediaList.addMedia(MediaDescriptor), MediaList.size() and nearly all the JVLC methods):

Code: Select all

public void next() { libvlc_exception_t exception = new libvlc_exception_t(); jvlc.getLibvlc().libvlc_media_list_player_next(instance, exception); }

Conclusions:

a) I have checked VLC 0.9.0 test 3 as stand-alone application and managed the playlist through the GUI, added many files, jumped from one to next and previous and all works perfectly.

b) Using the corresponding Java bindings (the latest on JVLC website) I have created a Java Swing application which should allow creating a playlist and play it, with some additional and simple commands like clearing or jumping to next items. The source code of this simple application is attached at the end of the post. However, some bugs have been detected as some methods doesn't work as expected.

c) The deprecated Playlist class has also been tested, reporting better results. Anyway, due to the deprecated status of the class, checking the new MediaList and MediaListPlayer classes behaviour was a priority in order to develop applications compliant with future VLC releases.

d) The JVLC of MediaList and MediaListPlayer classes seem quite simple and doesn't give any clue in order to guess which are the causes of these issues. Nearly all the code lines are based in the LibVlc object which is a JNA native library binding object, so the calls to VLC C code are made through this object.

e) I have taken a look at the C implementation of the related functions and, as far as I can guess how it works, it seems to be ok (obvious? xD). Anyway, this assertion is supposed to be a stupid one as, as I said in (a), I have checked the VLC application and it worked properly.

f) C code works fine. Java bindings not, but the conflictive methods are entirely based in the C functions. So... WHAT THE HELL CAN I DO? xDDDD.



If I could find the errors (always considering that actually they are... It could be that I don't know how to use the API properly, but this is why I asked for some help from other developers), then I could recode some JVLC parts, rebuild it and get the jar library, but I don't know where the errors are...


So, as always, any help would be much appreciated.

Thanks,
Javi


Simple Java Swing JVLC-based application:

Code: Select all

package test; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import org.videolan.jvlc.Audio; import org.videolan.jvlc.JVLC; import org.videolan.jvlc.MediaDescriptor; import org.videolan.jvlc.MediaList; import org.videolan.jvlc.MediaListPlayer; import org.videolan.jvlc.MediaPlayer; import org.videolan.jvlc.Playlist; import org.videolan.jvlc.VLCException; import org.videolan.jvlc.Video; public class GUITest extends JFrame { private JButton playButton, addButton, clearButton, stopButton, pauseButton, muteButton, nextButton, prevButton, fullscreenButton; private JTextField mrlField; private JPanel buttonPanelUp, buttonPanelBottom, textEntryPanel, buttonPanel; private Canvas canvas; private Container container; private JVLC jvlc; private MediaList mediaList; private MediaListPlayer mediaListPlayer; private MediaDescriptor mediaDescriptor; private Audio audio; private Video video; private Playlist playlist; public GUITest(){ super("JVLC GUI test"); setPreferredSize(new Dimension(500, 500)); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // VIDEO FRAME // New canvas = new Canvas(); jvlc = new JVLC(); mediaList = jvlc.getMediaList(); mediaListPlayer = new MediaListPlayer(jvlc); mediaListPlayer.setMediaList(mediaList); video = new Video(jvlc); audio = new Audio(jvlc); // Deprecated playlist = new Playlist(jvlc); // BUTTONS playButton = new JButton("Play"); playButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ play(); } }); pauseButton = new JButton("Pause"); pauseButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ pause(); } }); stopButton = new JButton("Stop"); stopButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ stop(); } }); muteButton = new JButton("Mute"); muteButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ mute(); } }); fullscreenButton = new JButton("Full Screen"); fullscreenButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ fullscreen(); } }); nextButton = new JButton("Next"); nextButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ next(); } }); prevButton = new JButton("Prev"); prevButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ prev(); } }); addButton = new JButton("Add"); addButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ add(); } }); clearButton = new JButton("Clear"); clearButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ clear(); } }); // TEXT FIELD mrlField = new JTextField("/home/dulceangustia/diptvServerLinux32/contents/", 40); // PANELS buttonPanelUp = new JPanel(new FlowLayout()); buttonPanelUp.add(playButton); buttonPanelUp.add(pauseButton); buttonPanelUp.add(stopButton); buttonPanelUp.add(fullscreenButton); buttonPanelBottom = new JPanel(new FlowLayout()); buttonPanelBottom.add(muteButton); buttonPanelBottom.add(prevButton); buttonPanelBottom.add(nextButton); buttonPanelBottom.add(addButton); buttonPanelBottom.add(clearButton); textEntryPanel = new JPanel(new FlowLayout()); textEntryPanel.add(mrlField); buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); buttonPanel.add(buttonPanelUp); buttonPanel.add(buttonPanelBottom); container = getContentPane(); container.setLayout(new BorderLayout()); container.add(canvas, BorderLayout.CENTER); container.add(buttonPanel, BorderLayout.NORTH); container.add(textEntryPanel, BorderLayout.SOUTH); pack(); setVisible(true); jvlc.setVideoOutput(canvas); } private void play() { mediaListPlayer.playItem(0); // With the deprecated playlist class /*try { playlist.play(); } catch (VLCException e) { e.printStackTrace(); } */ } private void pause() { if (mediaListPlayer.isPlaying()) mediaListPlayer.pause(); else mediaListPlayer.play(); // With the deprecated playlist class /*try { playlist.togglePause(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void stop() { if (mediaListPlayer.isPlaying()) mediaListPlayer.stop(); // With the deprecated playlist class /*try { playlist.stop(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void mute() { audio.toggleMute(); } private void fullscreen() { //video.toggleFullscreen(mediaListPlayer); } private void next() { mediaListPlayer.next(); // With the deprecated playlist class /*try { playlist.next(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void prev() { //mediaListPlayer.playItem(); // With the deprecated playlist class /*try { playlist.prev(); } catch (VLCException e) { e.printStackTrace(); }*/ } private void add() { mediaDescriptor = new MediaDescriptor(jvlc, mrlField.getText().toString()); mediaList.addMedia(mediaDescriptor); System.out.println(mediaList.size()); // With the deprecated playlist class /*try { playlist.add(mrlField.getText().toString(), mrlField.getText().toString()); } catch (VLCException e) { e.printStackTrace(); } */ } private void clear() { /*try { playlist.stop(); playlist.clear(); } catch (Exception e) { e.printStackTrace(); }*/ mediaList.clear(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new GUITest(); } }); } }

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 07 Sep 2008 11:48
by jgg
Any idea on this? Are JVLC developers still on holiday? :D

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 07 Sep 2008 20:36
by littlejohn
Hi,
sorry for the long delay, but I didn't have the time to check the forum before now.

As regards Swing integration, currently you can't use any lightweight components to embed the video output, but only heavyweight ones. I suggest you to read:

http://java.sun.com/products/jfc/tsc/articles/mixing/

and related documents to get more insights on the issue.

For MediaList and MediaPlayer, the native side has some problem, which are the ones you are experiencing on the java side. Hopefully these issues will be worked out on the native side soon. In the while, you may continue to use the Playlist class, or implement your own playlist directly in java, and use the MediaPlayer class with it.

Cheers,
Filippo

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 07 Sep 2008 21:13
by jgg
Hi Filippo,

Thanks for your answer.

What do you mean with "native side"? VLC's C (original) source code? If so, do you know if VLC developers know about this issue?

By the way, do you expect a new JVLC release due to next (and first) VLC 0.9 stable release?


Thank you a lot for your time,
Javi

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 25 Feb 2009 04:36
by viewport
Hi Filippo,

Thanks for your answer.

What do you mean with "native side"? VLC's C (original) source code? If so, do you know if VLC developers know about this issue?

By the way, do you expect a new JVLC release due to next (and first) VLC 0.9 stable release?


Thank you a lot for your time,
Javi
Didn't know this was the forum to post JVLC issues to. I've been using "Development around libVLC". There's a problem with both the Playlist and the Medialist.

The Medialist's clear() method throws a fatal error.

The Playlist's clear() method works, but the play() method is probably bugged. Need to call next() instead.

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 25 Feb 2009 09:00
by jgg
So, how the VLC application team succeeded in the development of the application itself? I mean, I can use VLC (the application) to create and play properly a playlist. Don't they use the Medialist objects? How are they able to manage the programming properly? How can be possible that the native implementation has some errors while it works nice in the VLC app?

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 25 Feb 2009 17:54
by RĂ©mi Denis-Courmont
No, VLC does not use media list objects.

Re: JVLC playlist issues (MediaList and MediaListPlayer objects)

Posted: 25 Feb 2009 22:29
by jgg
So, you manage kind of EOS signals/events, don't you?