Search code examples
videovaadin7

Playing Video on Vaadin


I'm playing an mp4 video on my Vaadin application but have a few issues:

  • Would like to listen to when it ends so I can close the window I used to display it.

Here's my code so far:

    //Display video
    ThemeResource fileResource = new ThemeResource("videos/intro.mp4");
    Video vd = new Video();
    vd.setAutoplay(true);
    vd.setSource(fileResource);
    vd.setResponsive(false);
    vd.setReadOnly(true);
    vd.setSizeFull();
    Window intro = new Window();
    intro.setContent(vd);
    intro.setHeight(100, Unit.PERCENTAGE);
    intro.setWidth(100, Unit.PERCENTAGE);
    intro.center();
    intro.setModal(true);
    addWindow(intro);
    vd.play();

Sadly I was unable to find much information on this component. Any idea?


Solution

  • You can use JavaScript solution from this answer with Vaadin's component extension.

    You need connector class which adds simple JS event listener proposed in cited answer:

    @Connect(VideoEndedExtension.class)
    public class VideoEndedConnector extends AbstractExtensionConnector {
    
        @Override
        protected void extend(ServerConnector target) {
            addVideoEndedListener(((ComponentConnector) target).getWidget().getElement());
        }
    
        private void onVideoEnded() {
            getRpcProxy(VideoEndedRpc.class).onVideoEnded();
        }
    
        private native void addVideoEndedListener(Element el)
        /*-{
              var self = this;
              el.addEventListener('ended', $entry(function(e) {
                  self.@your.package.VideoEndedConnector::onVideoEnded()();
              }), false);
    
        }-*/;
    }
    

    (you need to change your.package to the package which contains VideoEndedConnector class)

    when event occurs the server is informed with the use of RPC:

    public interface VideoEndedRpc extends ServerRpc {
        void onVideoEnded();
    }
    

    the last part is extension which registers RPC on the server side and handles incoming calls:

    public class VideoEndedExtension extends AbstractExtension {
    
        private List<VideoEndedListener> videoEndedListeners = new ArrayList<>();
    
        public interface VideoEndedListener extends Serializable {
            void onVideoEnded();
        }
    
        public void extend(Video video) {
            super.extend(video);
            registerRpc(new VideoEndedRpc() {
    
                @Override
                public void onVideoEnded() {
                    for (VideoEndedListener listener : videoEndedListeners) {
                        listener.onVideoEnded();
                    }               
                }
            });
        }
    
        public void addVideoEndedListener(VideoEndedListener listener) {
            if (listener != null) {
                videoEndedListeners.add(listener);
            }
        }
    }
    

    you can use it with your Video component:

    Video v = new Video("video", new ExternalResource("link.to.video"));
    VideoEndedExtension ext = new VideoEndedExtension();
    ext.extend(v);
    ext.addVideoEndedListener(new VideoEndedListener() {
    
        @Override
        public void onVideoEnded() {
            Notification.show("Video ended");
        }
    });
    

    If you want to read more about Vaadin's extensions check this guide.

    Native JavaScript part uses GWT's JavaScript Native Interface, if it seems weird for you, you can read more about it here.