# Creating a Video Component

**URL:** <https://forum.inductiveautomation.com/t/creating-a-video-component/55412>\
**Category:** Module Development\
**Created:** [January 26, 2022, 6:07pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412 "2022-01-26T18:07:22Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 26, 2022, 6:07pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/1 "2022-01-26T18:07:22Z")

</div>

Hi I’m somewhat new to building visual components in Ignition and am working on a video component utilizing the VLCJ library. Currently I’m running into the issue of the component not serializing onto the root container, it creates a new instance of a frame and I would like to embed it into the root container. Currently I’m using IntelliJ and Maven to create the module for Ignition 8.1. Any insight and help is much appreciated.  
Class construction:

```auto
public class VLCJComponent extends AbstractVisionComponent {

    private final EmbeddedMediaPlayerComponent myPlayerComponent;

    private JPanel refPanel;
    private MediaPlayerFactory factory;
    private VideoSurface videoSurface;
    private JFrame frame;

    private String VideoPath = null;
    
    public VLCJComponent() {
        // set the perferred size of the component
        setPreferredSize(new Dimension(352, 240));
        
        JFrame frame = new JFrame("Testing VLCj");
        frame.setBounds(10,10,352,240);

        myPlayerComponent = new EmbeddedMediaPlayerComponent() {
            @Override
            protected void onBeforeRelease () {
                super.onBeforeRelease();
            }

            @Override
            protected void onAfterRelease () {
                super.onAfterRelease();
            }
            
            @Override
            public void videoOutput (MediaPlayer mediaPlayer,int newCount){
                super.videoOutput(mediaPlayer, newCount);
            }

            @Override
            public void playing (MediaPlayer mediaPlayer){
                super.playing(mediaPlayer);
            }

            @Override
            public void error (MediaPlayer mediaPlayer){
                super.error(mediaPlayer);
            }
        };
        // display the player
        myPlayerComponent.setVisible(true);
        frame.setContentPane(myPlayerComponent);

        frame.setVisible(true);
        this.add(myPlayerComponent);
    }

    /**
     * This function will play the video. It takes one argument, a String video URL path.
     */
    public void loadVideo (String path){
        myPlayerComponent.mediaPlayer().media().start(path);
    }

    public String getVideoPath(){
        return t(this, VideoPath);
    }

    public void setVideoPath(String VideoPath){
        String old = this.VideoPath;
        this.VideoPath = VideoPath;

        firePropertyChange("VideoPath",old, VideoPath);
        if (VideoPath != null){
            loadVideo(VideoPath);
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [January 26, 2022, 6:44pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/2 "2022-01-26T18:44:46Z")

</div>

I recently ran into a similar issue in my first attempt.

Things I did differently - I had to extend `AbstractVisionPanel` instead of `AbstractVisionComponent`. Also, I put all my components inside a JPanel, not a JFrame. Then I just added my components to my JPanel, and then added my JPanel to my component. You can see how I did mine [here](https://forum.inductiveautomation.com/t/i-am-looking-for-a-tutor-for-module-development/55030/19).

I’m still new to the module development as well but I did have the same issue as you so hopefully this helps.

---

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 26, 2022, 6:52pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/3 "2022-01-26T18:52:11Z")

</div>

Thank you for the reply. I have tried extending the `AbstractVisionPanel` instead of the ‘AbstractVisionComponent’, and ended up running into some issues. The video component did not appear on the root container when I did that. Also when I used JPanel instead of JFrame, when the component was added to the root container, it was just an empty container. I’m able to add buttons, labels, text fields etc, just cannot get this to display.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 26, 2022, 7:31pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/4 "2022-01-26T19:31:44Z")

</div>

Fair warning: VLCJ is not license-compatible with Ignition, unless you pay for a commercial license. You will only be able to use such a module on your own computers.

---

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 26, 2022, 7:36pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/5 "2022-01-26T19:36:35Z")

</div>

Thank you for the information I’m just working on this for an internal module. I did come across that, I’m just looking to capture view and capture some video streams on my computers.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [January 26, 2022, 7:56pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/6 "2022-01-26T19:56:50Z")

</div>

You definitely want a JPanel, not a JFrame, to embed this inside the actual window. When you went down that road, are you sure you `add`ed all of your components to the stack correctly?

What serialization/other errors are you getting? Full stacktrace is helpful.

Scanning the java doc for EmbeddedMediaPlayer briefly, you want to make sure `release` is called by your component. If you extend `AbstractVisionPanel` you’ll get an `onShutdown` method to easily hook into.

---

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 26, 2022, 8:40pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/7 "2022-01-26T20:40:07Z")

</div>

So when I do go with a `JPanel` and not a `JFrame` I end up getting this error:

```auto
15:28:22.830 [AWT-EventQueue-0] ERROR com.inductiveautomation.ignition.client.util.gui.ErrorUtil - null
com.inductiveautomation.ignition.common.xmlserialization.SerializationException: Error invoking [VLCJComponent]org.IgnitionMods.client.VLCJComponent[VLCj Video Player,150,610,350x240,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.synth.SynthBorder@f86cfeb,flags=9,maximumSize=,minimumSize=,preferredSize=java.awt.Dimension[width=352,height=240]].setVideoPath(http://XX.XX.XX.XX:9914/video4.mjpeg)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.handlers.ObjectDeserializationHandler.endSubElement(ObjectDeserializationHandler.java:82)
	at com.inductiveautomation.factorypmi.application.xmlserialization.ComponentDeserializationHandler.endSubElement(ComponentDeserializationHandler.java:102)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.XMLDeserializer$ParseContext.onElementEnd(XMLDeserializer.java:923)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:165)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.readElement(BinaryParser.java:157)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.BinaryParser.parse(BinaryParser.java:51)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.XMLDeserializer.deserializeBinary(XMLDeserializer.java:358)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.XMLDeserializer.deserialize(XMLDeserializer.java:268)
	at com.inductiveautomation.factorypmi.application.model.WindowCache._deserializeWindow(WindowCache.java:381)
	at com.inductiveautomation.factorypmi.application.model.WindowCache._loadWindow(WindowCache.java:324)
	at com.inductiveautomation.factorypmi.application.model.WindowCache.openWindow(WindowCache.java:298)
	at com.inductiveautomation.factorypmi.designer.workspace.WindowWorkspace$DesigntimeWindowOpener.openWindow(WindowWorkspace.java:3730)
	at com.inductiveautomation.factorypmi.designer.workspace.WindowWorkspace.openWindow(WindowWorkspace.java:1482)
	at com.inductiveautomation.factorypmi.designer.workspace.WindowWorkspace$4.lambda$createPanels$2(WindowWorkspace.java:623)
	at com.inductiveautomation.ignition.designer.workspacewelcome.RecentlyModifiedTilePanel$Tile.lambda$new$1(RecentlyModifiedTilePanel.java:206)
	at com.inductiveautomation.ignition.client.util.gui.Listen$1.mousePressed(Listen.java:52)
	at java.desktop/java.awt.AWTEventMulticaster.mousePressed(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at com.jidesoft.docking.DockingUtils.a(Unknown Source)
	at com.jidesoft.docking.DefaultDockingManager.handleEvent(Unknown Source)
	at com.jidesoft.docking.DefaultDockingManager$56.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Unknown Source)
	at java.desktop/java.awt.Toolkit.notifyAWTEventListeners(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException: null
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at com.inductiveautomation.ignition.common.xmlserialization.deserialization.handlers.ObjectDeserializationHandler.endSubElement(ObjectDeserializationHandler.java:69)
	... 63 common frames omitted
Caused by: java.lang.IllegalStateException: The video surface component must be displayable
	at uk.co.caprica.vlcj.player.embedded.videosurface.ComponentVideoSurface.attach(ComponentVideoSurface.java:66)
	at uk.co.caprica.vlcj.player.embedded.VideoSurfaceApi.attachVideoSurface(VideoSurfaceApi.java:80)
	at uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer.onBeforePlay(EmbeddedMediaPlayer.java:125)
	at uk.co.caprica.vlcj.player.base.ControlsApi.play(ControlsApi.java:51)
	at uk.co.caprica.vlcj.player.base.MediaPlayerLatch.play(MediaPlayerLatch.java:66)
	at uk.co.caprica.vlcj.player.base.ControlsApi.start(ControlsApi.java:65)
	at uk.co.caprica.vlcj.player.base.MediaApi.start(MediaApi.java:419)
	at uk.co.caprica.vlcj.player.base.MediaApi.start(MediaApi.java:114)
	at org.IgnitionMods.client.VLCJComponent.loadVideo(VLCJComponent.java:89)
	at org.IgnitionMods.client.VLCJComponent.setVideoPath(VLCJComponent.java:102)
	... 68 common frames omitted

```

I am not sure that all the components are added to the stack correctly. I’ve been trying to find some information regarding that but have not come across anything yet.  
I’ve added the `onShutdown` `release` and tried it and when I add the component to the root container I get this:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/1/11bd6f83d3990b4f4de22ad6c65ff1e6808b13e5.png)

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [January 26, 2022, 9:41pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/8 "2022-01-26T21:41:30Z")

</div>

Look deeper into the stack of the error you posted:  
`Caused by: java.lang.IllegalStateException: The video surface component must be displayable`

That’s coming from the media player component, not Ignition. You need to match Ignition’s lifecycle to your component. Something to try: Leave any `setVideoPath`/`loadVideo` calls out of the constructor (maybe put them in `onStartup`?).

---

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 27, 2022, 11:40am UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/9 "2022-01-27T11:40:11Z")

</div>

I will dig deeper into the stack and look into Ignition’s component lifecycle. I appreciate the feedback. Thank you.

---

<div class="post-metadata">

**Author:** ![ademovicemir](https://avatars.discourse-cdn.com/v4/letter/a/bbce88/32.png) [@ademovicemir](https://forum.inductiveautomation.com/u/ademovicemir)\
**Post date:** [January 27, 2022, 2:57pm UTC](https://forum.inductiveautomation.com/t/creating-a-video-component/55412/10 "2022-01-27T14:57:16Z")

</div>

Thank you for the help and pointing me in the right direction. I was able to get this to work. The reason I was getting the empty container was because I did not set the size on the media player. I put the `loadVideo` on a button and it’s working. Again, thank you so much for the feedback.
