Videocomponent

Hello, I tried the VideoDemo but nothings happens. I clicked on the left and right buttons, in the grey areas, with left and right click but no reactions.

I tried to create a project with a VideoComponent, and call the load function on a .mp4 video but it didn’t work as well. The error result says “Can’t create window”.

Any clues ?

Demo is looking for videos in your ‘Videos’ folder… top panel shows the list of those files.

VideoComponent uses OS video functions, and can only play supported media type. Could be that the format you chose is not support by the Windows native playback system.

1 Like

Ok ! Thank you, I can display my example video in the projucer now.

The problem with my test example was to call the videoComponent.load() in the constructor of my component. So I moved it in a handleAsyncUpdate() and call a triggerAsyncUpdate() in the constructor

Good catch!

You can save the AsyncUpdater and use MessageManager::callAsync() instead. It will do the same thing in this case with less typing:

MessageManager::callAsync ([&] { videoComponent.load(); });
1 Like

Yes, but you have to be very careful when doing it like that in a plugin.
DAWs often open and close your plugin really fast when they are scanning all plugins on startup. Sometimes so fast, that by the time the lambda is executed, the component doesn’t exist anymore, resulting in a crash.
You should definitely use Component::SafePointer.

1 Like

Thank you I didn’t know about that way !

You mean like this ?

class MyEditor {
   Component::SafePointer<VideoComponent> _videoComponent;
}

//in the constructor : 
_videoComponent = new VideoComponent();
MessageManager::callAsync ([&] { 
   if(_videoComponent)
       _videoComponent->load(); 
});

Almost… the SafePointer is copyable, and it wouldn’t help much, if the pointer is owned by the class, whose destruction you want to guard :wink:

If videoComponent is public, it would work like that:

MyClass::MyClass()
{
    Component::SafePointer<MyClass> ptr (this);
    MessageManager::callAsync ([ptr]
    {
        if (ptr != nullptr)
            ptr->videoComponent.load();
    });
}

A cleaner solution is having a loadVideo() method, that you call in a similar way:

MyClass::MyClass()
{
    Component::SafePointer<MyClass> ptr (this);
    MessageManager::callAsync ([ptr]
    {
        if (ptr != nullptr)
            ptr->loadVideo();
    });
}

void MyClass::loadVideo()
{
    videoComponent.load();
}

(good shout @Achder :slight_smile: )

1 Like

Ok, perfect ! And just to be sure, is this a problem of order in the event loop (deleting the object before calling the async callback), or a thread problem here ?

exactly :slight_smile:

There are no other threads involved here. But a message on the queue could lead to the destruction, and could already be scheduled before your callAsync message is processed.

1 Like

Thank you for those answers. Solved subject :slight_smile: