0

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?

javydreamercsw
  • 5,363
  • 13
  • 61
  • 106

1 Answers1

1

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.

mczerwi
  • 490
  • 2
  • 11
  • I'll give it a try but have one question, I'm not clear what you mean with this: (you need to change you package from your.package). I mean I know what you mean but not sure which package are you referring to. Is this the package of the UI class? – javydreamercsw Jun 29 '17 at 18:41
  • It's the package of `VideoEndedConnector` class, I forgot to add the class name in the answer, now it should be more understandable. – mczerwi Jun 29 '17 at 18:46
  • Got an error compiling: [ERROR] Errors in 'file:/C:/Users/.../video/VideoEndedExtension.java' [ERROR] Line 37: No source code is available for type com.vaadin.ui.Video; did you forget to inherit a required module? [ERROR] Line 28: No source code is available for type com.vaadin.server.AbstractExtension; did you forget to inherit a required module? Any idea? – javydreamercsw Jun 29 '17 at 19:06
  • Are you placing `VideoEndedExtension` in `client` package? It seems that GWT tries to compile it. Only `VideoEndedConnector` and `VideoEndedRpc` should be placed in `client` package. – mczerwi Jun 29 '17 at 19:11
  • Not sure what you mean by client package. – javydreamercsw Jun 29 '17 at 19:15
  • As described in [docs (bottom of the page)](https://vaadin.com/docs/-/part/framework/gwt/gwt-extension.html#gwt.extension.connector), client-side classes need to be placed under a `client` package, so they can be compiled to JS and included in widgetset. It seems that `VideoEndedExtension` is placed in that package and GWT tries to compile it. I got the same error as you when I moved it there and tried to recompile my widgetset. – mczerwi Jun 29 '17 at 19:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/147981/discussion-between-javydreamercsw-and-m-czerwinski). – javydreamercsw Jun 29 '17 at 19:25
  • After a painful session with Czerwinski (not painful because of him, because of Vaadin) I got it working with this answer. Thanks Czerwinski for the time you took to troubleshoot this. – javydreamercsw Jun 29 '17 at 20:33