MediaElement JS Player Component

Thanks for all of the investigation guys. Unfortunately I’m swamped with my day job right now and don’t have time to look into a fix for this.

That said, I’m always open to contributions on GitHub! Feel free to take a look and submit a pull request :slight_smile:

Bryson

I have similar problem. Player doesn’t show any functions, is only empty bar:

anyone can help?

This player is broken, but you can use a direct way, direct html/css/js via iframe, that hackish way (without integration) always works in Vaadin :slight_smile: that way you are free to use whatever good player you want: video.js, mediaelementjs, flowplayer etc.

Hi niceguy - can you provide a bit more explanation on what you mean - maybe an example? I need the features in mediaelements e.g. in particular get current position, play from a given position. With this in mind, I have been looking at the use of GWT i.e.

The methods are available in MediaElement class (https://vaadin.com/api/com/google/gwt/dom/client/MediaElement.html). However this is a client side GWT component. I have been following the guide on how to integrate this on the Vaadin Wiki .

https://vaadin.com/wiki/-/wiki/Main/Integrating+an+existing+GWT+widget

I have made some progress - following the example shown - but not got it working yet - but I think I am close… I would be happy to share where I have got so far, so someone with more expertise may be able to help. It would be great to get this working as a “community effort”.

Hi Everyone -

The “player with no controls” bug has been fixed in version 1.2.8. It was an issue with how Vaadin translates Java POJOs into Javascript objects in version 7.4+.

Hi Bryson, I have integrated your addon to my project and the issue I’m facing is that the player doesn’t load any mp3 file I pass, it only works with YouTube videos. I have tried different paths, I have tried ThemeResource and FileResource and nothing. I am using version 1.3.1

Thanks in advance

Could you post your code here?

Sure, I just took as base code the one you uploaded in github.
As I said, I haven’t been able to reproduce any mp3 files, just YouTube videos so far.
Here is what I have.

package com.monitec.mapatiempos.main.gui.util;

import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;

import com.kbdunn.vaadin.addons.mediaelement.interfaces.CanPlayListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.LoadedDataListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.LoadedMetadataListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.PausedListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.PlaybackEndedListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.PlayingListener;
import com.kbdunn.vaadin.addons.mediaelement.interfaces.StateUpdatedListener;
import com.kbdunn.vaadin.addons.mediaelement.MediaElementPlayer;
import com.monitec.mapatiempos.main.gui.ChartContentPanel;
import com.monitec.mapatiempos.mapa.bs.MapaService;
import com.monitec.mapatiempos.mapa.bs.MapaServiceImpl;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FileResource;
import com.vaadin.server.Resource;
import com.vaadin.server.ThemeResource;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

/**
 * Class MediaPlayerAddonLayout
 * Created on 25/03/2016 by Carlos David carlosmosquera@pwpsoftware.com
 * Base code created  by Bryson, please visit http://bdunn.jelastic.servint.net/Vaadin-Addon-Demo/?a=MejsPlayer for full access
 */
@org.springframework.stereotype.Component
@SuppressWarnings("serial")
@Scope("prototype")
public class MediaPlayerAddonLayout extends VerticalLayout implements
        CanPlayListener, LoadedDataListener, LoadedMetadataListener, PausedListener, PlaybackEndedListener, PlayingListener, StateUpdatedListener,
        View
{

    private static final long serialVersionUID = 1L;
    //public static Map<String, Resource> MEDIA_FILES;
    private static final String VIDEO_YOUTUBE = "The Art of Flight - Trailer (YouTube)";
    //private static final String VIDEO_VIMEO = "The Art of Flight - Trailer (Vimeo)";

    @Autowired
    private MapaService mapaService;

    
/*    static {
        MEDIA_FILES = new LinkedHashMap<String, Resource>();
        //MEDIA_FILES.put(SONG_BONOBO, new ThemeResource("songs/01_Noctuary.mp3"));
        //MEDIA_FILES.put(SONG_ACDC, new ThemeResource("songs/ACDC_-_Back_In_Black-sample.ogg"));
        //MEDIA_FILES.put(VIDEO_FAKER, new ThemeResource("videos/Chet_Faker-Archangel_Live_Sessions.mp4"));
        MEDIA_FILES.put(VIDEO_YOUTUBE, new ExternalResource("https://www.youtube.com/watch?v=jwPSuVk4fhw"));
        //MEDIA_FILES.put(VIDEO_VIMEO, new ExternalResource("https://vimeo.com/20065250"));
        //MEDIA_FILES.put(VIDEO_ALTJ, new ThemeResource("videos/alt-J-Left_Hand_Free.mp4"));
    }*/
    
    private MediaElementPlayer player;
    private Label nowPlaying;
    private ComboBox resources;
    private Button play;
    private Button pause;
    private Button mute;
    private Button unmute;
    private TextField dectectionTimeStamp;
    private TextField volumeInput;
    private TextField detectionTimeStampDisplay;
    private TextField durationDisplay;
    private TextField nameDetectionDisplay;
    private VerticalLayout playerLayout;
    private Map<String, Resource> mediaFiles;
    
    public MediaPlayerAddonLayout() {
        setMargin(true);
        setSpacing(true);
        mediaFiles = new LinkedHashMap<>();
        mediaFiles.put("Captain America Civil WAR", new ExternalResource("https://www.youtube.com/watch?v=jwPSuVk4fhw"));
        mediaFiles.put("Tristania - Darkling", new FileResource(new File("D:/generatedmp3/Darkling.mp3")));
       // mediaFiles.put("sss", new ThemeResource(""))
        buildLayout();
    }
    
    private void buildLayout() {
        setMargin(true);
        addComponent(new ControlPanel());
        
        Panel playerPanel = new Panel();
        playerPanel.setWidth("80%");
        playerPanel.addStyleName(ValoTheme.PANEL_WELL);
        playerLayout = new VerticalLayout();
        playerLayout.setMargin(true);
        playerLayout.setSpacing(true);
        playerLayout.setSizeFull();
        playerPanel.setContent(playerLayout);
        addComponent(playerPanel);
        setComponentAlignment(playerPanel, Alignment.MIDDLE_CENTER);
        
        Label h1 = new Label("MDT Player");
        h1.addStyleName(ValoTheme.LABEL_H1);
        h1.addStyleName(ValoTheme.LABEL_NO_MARGIN);
        h1.setSizeUndefined();
        playerLayout.addComponent(h1);
        playerLayout.setComponentAlignment(h1, Alignment.MIDDLE_CENTER);
        player = new MediaElementPlayer();
        player.setPlayerType(MediaElementPlayer.Type.AUDIO);
        player.addCanPlayListener(this);
        player.addLoadedDataListener(this);
        player.addPauseListener(this);
        player.addPlaybackEndedListener(this);
        player.addPlayingListener(this);
        player.addStateUpdatedListener(this);
        nowPlaying = new Label();
        nowPlaying.setSizeUndefined();
        playerLayout.addComponent(nowPlaying);
        playerLayout.setComponentAlignment(nowPlaying, Alignment.MIDDLE_CENTER);
        playerLayout.addComponent(player);
        playerLayout.setComponentAlignment(player, Alignment.MIDDLE_CENTER);
        
        Label link = new Label("<a href='http://www.pwpsoftware.com' target='_blank'>Powered by PWP Software SAS</a>", ContentMode.HTML);
        link.setSizeUndefined();
        link.addStyleName(ValoTheme.LABEL_SMALL);
        addComponent(link);
        setComponentAlignment(link, Alignment.BOTTOM_RIGHT);
    }


    public Map<String, Resource> getMediaFiles()
    {
        return mediaFiles;
    }

    public void setMediaFiles(Map<String, Resource> mediaFiles)
    {
        this.mediaFiles = mediaFiles;
    }

    @Override
    public void paused(MediaElementPlayer player) {
        Notification.show("Paused!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void metadataLoaded(MediaElementPlayer player) {
        Notification.show("Metadata Loaded!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void dataLoaded(MediaElementPlayer player) {
        Notification.show("Data Loaded!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void canPlay(MediaElementPlayer player) {
        Notification.show("Can Play!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void playing(MediaElementPlayer player) {
        Notification.show("Playing!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void playbackEnded(MediaElementPlayer player) {
        Notification.show("Playback Ended!", Notification.Type.TRAY_NOTIFICATION);
    }

    @Override
    public void stateUpdated(MediaElementPlayer player) {
        detectionTimeStampDisplay.setValue(String.valueOf(player.getCurrentTime()));
        durationDisplay.setValue(String.valueOf(player.getDuration()));
        nameDetectionDisplay.setValue(String.valueOf(player.getVolume()));
    }

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent)
    {

    }

    class ControlPanel extends Panel {
        
        private static final long serialVersionUID = 1L;
        private VerticalLayout content;
        
        public ControlPanel() {
            content = new VerticalLayout();
            content.setMargin(true);
            content.setSpacing(true);
            setContent(content);
            
            initMediaSelectors();
            initControlButtons();
            initInfoLabels();
            initControlInputs();
            
            content.addComponent(resources);
            
            HorizontalLayout inputs = new HorizontalLayout();
            inputs.setSpacing(true);
            inputs.addComponent(detectionTimeStampDisplay);
            inputs.addComponent(durationDisplay);
            inputs.addComponent(nameDetectionDisplay);
            inputs.addComponent(dectectionTimeStamp);
            inputs.addComponent(volumeInput);
            content.addComponent(inputs);
            
            HorizontalLayout controlButtons = new HorizontalLayout();
            controlButtons.setSpacing(true);
            controlButtons.addComponent(play);
            controlButtons.addComponent(pause);
            controlButtons.addComponent(mute);
            controlButtons.addComponent(unmute);
            content.addComponent(controlButtons);
        }
        
        private void initMediaSelectors() {
            resources = new ComboBox("Cargar audio:");
            resources.setWidth("250px");
            resources.setNewItemsAllowed(false);
            resources.setTextInputAllowed(false);
            resources.setNullSelectionAllowed(false);
            resources.setInputPrompt("Seleccione un audio");
            mediaFiles.keySet().forEach(resources::addItem);
            resources.addValueChangeListener(new ValueChangeListener() {
                private static final long serialVersionUID = 1L;

                @Override
                public void valueChange(ValueChangeEvent event) {
                    String key = (String) resources.getValue();
                    player.setSource(mediaFiles.get(key));
                    nowPlaying.setValue("Now Playing: " + key);
                }
            });
        }
        
        private void initControlButtons() {
            play = new Button("Play", new ClickListener() {
                private static final long serialVersionUID = 1L;

                @Override
                public void buttonClick(ClickEvent event) {
                    player.play();
                }
            });
            pause = new Button("Pause", new ClickListener() {
                private static final long serialVersionUID = 1L;

                @Override
                public void buttonClick(ClickEvent event) {
                    player.pause();

                }
            });

            mute = new Button("Mute", new ClickListener() {
                private static final long serialVersionUID = 1L;

                @Override
                public void buttonClick(ClickEvent event) {
                    player.mute();
                }
            });
            unmute = new Button("Unmute", new ClickListener() {
                private static final long serialVersionUID = 1L;

                @Override
                public void buttonClick(ClickEvent event) {
                    player.unmute();
                }
            });
        }
        
        private void initInfoLabels() {
            detectionTimeStampDisplay = new TextField("Fecha Deteccion");
            detectionTimeStampDisplay.setEnabled(false);
            detectionTimeStampDisplay.setValue("2016-02-22 5:39:02"); //TODO: Change this hardcoded timestamp
            durationDisplay = new TextField("Duracion (segundos)");
            durationDisplay.setEnabled(false);
            nameDetectionDisplay = new TextField("Nombre");
            nameDetectionDisplay.setEnabled(false);
        }
        
        private void initControlInputs() {
            dectectionTimeStamp = new TextField("Set Current Time (seconds):");
            dectectionTimeStamp.setValue("0");
            dectectionTimeStamp.setRequired(true);
            volumeInput = new TextField("Set Volume (1-10):");
            volumeInput.setValue("10");
            volumeInput.setRequired(true);
        }
    }
}

Have you tried a simpler implementation to start? Try the code example from the addon page:

MediaElementPlayer audioPlayer = new MediaElementPlayer(); 
layout.addComponent(audioPlayer); 
audioPlayer.setSource(new FileResource(new File("D:/generatedmp3/Darkling.mp3"))); 
audioPlayer.play();

Well, that doesn´t change anything at all. I mean, the main problem is exactly that the setSource method apparently is not doing its job. The File is being created, but the player is not loading the audio.

Yeah, understood, however 4 lines of code are easier to debug than 300.

This issue is new to me - which version of Vaadin and the addon are you using? Please use the code I posted, reply here with any errors and also include the HTML tree for the widget. I’m specifically interested in the audio tag, which should look similar to this:

<audio type="audio/mpeg" src="http://bdunn.jelastic.servint.net/Vaadin-Addon-Demo/VAADIN/songs/01_Noctuary.mp3" id="mejsplayer-205" preload="none"> <object type="application/x-shockwave-flash" data="VAADIN/addons/mejs-player/mediaelement-2.20.0/flashmediaelement.swf"> <param name="movie" value="VAADIN/addons/mejs-player/mediaelement-2.20.0/flashmediaelement.swf"> <param name="flashvars" value="controls=true&amp;amp;file=http://bdunn.jelastic.servint.net/Vaadin-Addon-Demo/VAADIN/songs/01_Noctuary.mp3"> </object> <object type="application/x-silverlight-2" data="VAADIN/addons/mejs-player/mediaelement-2.20.0/silverlightmediaelement.xap"> <param name="movie" value="VAADIN/addons/mejs-player/mediaelement-2.20.0/silverlightmediaelement.xap"> <param name="flashvars" value="controls=true&amp;amp;file=http://bdunn.jelastic.servint.net/Vaadin-Addon-Demo/VAADIN/songs/01_Noctuary.mp3"> </object> </audio> I just tested with Vaadin 7.6.3 and 1.3.1 of the addon and it’s looking good on my end. Of course if you’re observing an errors (Java, JavaScript, Vaadin debug console) please share those.

-Bryson

Hey, thanks for the reply.

I tryed the simpler version as you suggested. And now I’m getting a NullPointerException exactly when calling the setSource method with the File I created.
First I created the new File, then called setSourceMethod.

Check this out:

public void setSource() {
File sourceFile = new File((DCSessionData.getServletContext().getRealPath("audio") + File.separator + "Darkling.mp3"));
player.setSource(new FileResource(sourceFile));

}

Here is the stack trace:

mar 28, 2016 7:44:18 PM com.vaadin.server.DefaultErrorHandler doDefault
SEVERE: 
java.lang.NullPointerException
    at com.vaadin.server.ResourceReference.getURL(ResourceReference.java:48)
    at com.kbdunn.vaadin.addons.mediaelement.MediaElementPlayer.createMediaResource(MediaElementPlayer.java:219)
    at com.kbdunn.vaadin.addons.mediaelement.MediaElementPlayer.setSource(MediaElementPlayer.java:212)
    at com.monitec.mapatiempos.main.gui.MediaPlayer.setSource(MediaPlayer.java:51)
    at com.monitec.mapatiempos.main.gui.menu.DashboardMenu.<init>(DashboardMenu.java:49)
    at com.monitec.mapatiempos.main.gui.VistaPrincipal.<init>(VistaPrincipal.java:26)
    at com.monitec.mapatiempos.main.gui.MapaTiemposUI.showMainView(MapaTiemposUI.java:76)
    at com.monitec.mapatiempos.main.gui.MapaTiemposUI$1.loginSuccessful(MapaTiemposUI.java:57)
    at com.monitec.mapatiempos.security.gui.Login.login(Login.java:121)
    at com.monitec.mapatiempos.security.gui.Login.access$000(Login.java:20)
    at com.monitec.mapatiempos.security.gui.Login$3.buttonClick(Login.java:170)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1008)
    at com.vaadin.ui.Button.fireClick(Button.java:377)
    at com.vaadin.ui.Button$1.click(Button.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:408)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:769)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1667)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:172)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:133)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:497)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248)
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:610)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:539)
    at java.lang.Thread.run(Thread.java:745)

Thanks a lot.

Interesting. Again, would you please share which version of Vaadin you are using? In 7.6.4 line 48/49 of ResourceReference is:

GlobalResourceHandler globalResourceHandler = connector.getUI()
                    .getSession().getGlobalResourceHandler(false);

Which indicates that the player is not attached to a UI when setSource() is executed. This should be handled by the addon under the covers, which I’ll work on. In the meantime you should be able to work around the issue by first attaching the component to the UI as in the sample code:

layout.addComponent(audioPlayer);

Hope that works for you, let me know if not. The fix to handle this automatically should be simple enough

-Bryson

Just released version 1.3.2 which fixes this issue. If you try it out let me know how it works for you.

-Bryson

Hi,

The new version solved the NullPointerException, but player is still not playing the audio file. I am using Vaadin 7.6.3 and 1.3.2 of your addon.

I created this simple class for testing:

package com.monitec.mapatiempos.main.gui;

import com.kbdunn.vaadin.addons.mediaelement.MediaElementPlayer;
import com.monitec.mapatiempos.security.shared.DCSessionData;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener;
import com.vaadin.server.FileResource;
import com.vaadin.ui.VerticalLayout;
import java.io.File;

/**
* Class MediaPlayer Created by Carlos-David on 28/03/2016 for Monitec REST API Copyright PWP Software SAS 2016 All
* rights reserved. carlosmosquera@pwpsoftware.com
*/

public class MediaPlayer extends VerticalLayout implements View
{
private MediaElementPlayer player;
public MediaPlayer()
{
player = new MediaElementPlayer();
this.addComponent(player);
}

public void play() { player.play(); }

public void setSource()
{
File sourceFile = new File( (DCSessionData.getServletContext().getRealPath("audio") + File.separator + "Darkling.mp3"));
player.setSource(new FileResource(sourceFile));
}
public void pause() { player.pause(); }
@Override
public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) { } }

I think the problem is that the source is not being set within the audio tag

As you can see in the attached image

I don’t see any java or javascript errors.

Thanks,

David

If you’re using the same code as with the previous version (1.3.1) the only difference is that the exception will be surpressed. This root cause appears to be an issue with your application - the player is unable to retrieve the UI it is attached to and will not set the source until it is attached. It’s strange that you’re seeing the HTML when Vaadin doesn’t think the component has been added.

Could you please post the code that adds your MediaPlayer view to your application?

But why if I set the source with ExternalResource and pass it a YouTube url, the player works just fine. The video is played. The issue only happens when I try to set mp3 files from my local machine.

I’ll attach the code in the next post.

The reason is simple: ExternalResource is just a URL which gets passed to the component, whereas Vaadin must create a URI for any other Resource type. ThemeResources already have accessible URIs (/VAADIN/*), but ConnectorResource subclasses (FileResource, ClassResource) need to be registered explicitly to have a URI assigned. For example Vaadin would assign a URI such as this for a FileResource:

http://localhost:8080/APP/connector/0/58/0/my.mp3

The problem is that attempting to get this URI fails when the component is not attached to a UI. This has been fixed by queuing the player source if the component is not attached, and setting the source using an attach listener.

The root cause of this issue is that MediaElementPlayer#getUI() returns null when you are setting your source, meaning the component is not attached. What’s interesting is that it seems the player is being displayed in your application, which means it should be attached.This may be a Vaadin bug or a problem with your code - please post it when you have the chance.

Hey Bryson.

Thanks for the explanation, after following what you posted, I tryed adding my audio file within a folder under /VAADIN , so I created a folder there, added the mp3 file, created a new ThemeResource and guess what ? Now the source is being set but with a malformed URL. If you check the attached image, the url taking the form of "http://localhost:8080/mapatiempos/login.hmlVAADIN/*
So I don’t why is missing the “/” after the “login.html”.
I am creating the new resource like this:

new ThemeResource("audiotheme/Darkling.mp3")

As I saw that error, I tryed creating the ThemeResource adding the missing “/” before “audiotheme”

but when I do that I get the following exception:

Caused by: java.lang.IllegalArgumentException: Resource ID must be relative (can not begin with /)
    at com.vaadin.server.ThemeResource.<init>(ThemeResource.java:52)
    at com.monitec.mapatiempos.main.gui.util.MediaPlayerView.<clinit>(MediaPlayerView.java:56)
    ... 88 more

24505.png

Great catch, thanks for finding this bug! The ThemeResource URL was not being properly translated, which has been fixed in version 1.3.3. Check it out and let me know if it works for you.

FYI as a result of the corrected URI translation the path of ThemeResources will be different. For example:

player.setSource(new ThemeResource("songs/song.mp3"));

…would have loaded a file at
VAADIN/songs/song.mp3
in version 1.3.2, but will now load the file from the correct location (
VAADIN/themes/mytheme/songs/song.mp3
).