Controlling MXW through Python: Difference between revisions

From MXWendler Wiki
Jump to navigation Jump to search
Hwendler (talk | contribs)
No edit summary
m Admin moved page 1. Controlling MXW through Python to Controlling MXW through Python: Remove leading index prefix from title
 
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Python is used in MXW trough a plugin interface. Specified program paths are searched for plugins which are registered, and then loaded through the user interface.
<!-- MXWendler wiki page: Controlling MXW through Python (overview / hub) -->
<!-- Intended location: https://wiki.mxwendler.net/index.php?title=1._Controlling_MXW_through_Python -->
<!-- See also: https://wiki.mxwendler.net/index.php?title=Python_command_reference -->
<!-- See also: https://wiki.mxwendler.net/index.php?title=Python_imgui_reference -->
<!-- See also: https://wiki.mxwendler.net/index.php?title=Python_plugin_reference -->


As of version 7.2., plugins are available in the playlist. There are two paths searched during program startup, the program folder and the user folder:
MXWendler StageDesigner embeds '''Python 3.12'''. Python is used in two ways:


* '''(Program folder)/plugins/playlist/python/'''
* '''Command interface / scripting''' &ndash; the module <code>mxw</code> controls the running software (playlist, layers, clips, media, I/O, widgets by their address, ...) from the script console or from within a plugin.
* '''~.StageDesigner/plugins/playlist/python/ (Unix)'''
* '''Plugins''' &ndash; self-contained folders that add a media source or a playlist item and are called back by the host through a defined set of functions (''hooks'').
* '''~.StageDesigner/plugins/playlist/python/ (Windows)'''


Each plugin resides in a folder. Inside this folder, two files have to be present,
'''The presented Python interface is supported in version 7.2. and up'''


* '''mxw_plugin.ini'''
== Where to go ==
* '''mxw_main.py'''


The file '''mxw_plugin.ini''' defines the registration of the plugin. The following fields are valid:
The detailed documentation lives on three dedicated pages; this page only points to them so nothing is documented twice.
{| class="wikitable" style="margin:auto"
|+ Fields
|-
! Tag !! Use !! Values/Example
|-
| plugin_version || Plugin Version || 1
|-
| plugin_script_language || Plugin Script Language || Python
|-
| plugin_action_level || Plugin Activity Switch || disabled = not visible
|-
| plugin_menu_parent || Top level parent in playlist menu || "AI", "IO" ..
|-
| plugin_menu_name || Playlist menu entry || "Face detection"
|-
| plugin_grid_name || Default name in grid (may be completed via script) || "Face detect"
|-
| plugin_grid_bg_color || Default color in grid (may be changed via script) || 0.95 0.05 0.45 1.00 (RGBA with range 0..1)
|-
| plugin_tooltip || Tool tip in grid and panel || "This plugin triggers the playlist when it finds a Face"
|}


 
{| class="wikitable"
An example mxw_plugin.ini looks like this:
 
<syntaxhighlight lang="ini" line>
[mxw_plugin]                            ; must be here
plugin_version = 1                      ; must be V1 (as of V7.2)
plugin_script_language = Python        ; must be Python (as of V7.2)
plugin_menu_parent = AI
plugin_menu_name = NeuronalNet(Dlib) Face Detect Plugin
plugin_grid_name = Face Detect Plugin
plugin_grid_bg_color = 0.950000 0.050000 0.450000 1.000000 ; set plugin color.
plugin_tooltip = This plugin triggers the playlist when it finds a Face using a neuronal net (Dlib)
‎</syntaxhighlight>
 
 
The plugins are defined in a mxw_main.py file. This file is loaded, and the main UI calls the provided interface functions. The following interface functions are available for playlist plugins:
 
{| class="wikitable" style="margin:auto"
|+ Fields
|-
! Function Name !! Details
|-
| '''onCreate()''' || Called when the plugin item is created
|-
|-
| '''onDelete()''' || Called when the plugin item is deleted. Note that this is only called on software shutdown, not called when the plugin is e.g. removed, since items are kept for eventual undo-operations
! Topic !! Page
|-
|-
| '''getColorBG()''' || Get background color, called each render cycle
| The <code>mxw</code> command interface &ndash; software info, <code>playlist</code>, <code>io</code>, <code>widget(address)</code>, <code>media(name)</code>, <code>preload(n)</code>, <code>grabber(name)</code> || [[Python command reference|Python command reference]]
|-
|-
| '''onAction()''' || Called when cue is entered
| Drawing plugin settings panels with <code>mxw_imgui</code> (MXWendler's Dear ImGui binding) || [[Python imgui reference|Python ImGui reference]]
|-
|-
| '''onPostAction()''' || Called when the cue is left
| Writing '''plugins''' &ndash; media and playlist &ndash; the manifest (<code>mxw_plugin.ini</code>), the hooks, per-instance state, examples || [[Python plugin reference|Python plugin reference]]
|-
| '''onPreparePlayback()''' || Called when the playlist gets a preloading command (e.g. when the |< button is pressed)
|-
| '''onActivateInUI()''' || Called when the item is selected in the ui
|-
| '''onActiveCueChange()''' || Called when the playlist seeks
|-
| '''getDuration()''' || Get action duration
|-
| '''getText()''' || Get grid text, called each render cycle (may display some information)
|-
| '''onCleanup()''' || Called when the playlist aborts or seeks
|-
| '''getTimeSinceOnActionIssued()''' ||Get action duration, called each render cycle (may display a countdown)
|-
| '''onPause()''' || Called when the playlist goes paused
|}
|}


== Quick start ==


A minimal look at each entry point; follow the links above for the full reference.


 
'''Scripting.''' From the script console (or any hook), the <code>mxw</code> module reaches the software:
This is a minimal example of video writing and placing the recorded video into the first preload:


<syntaxhighlight lang="Python" line>
<syntaxhighlight lang="Python" line>
import tempfile
import mxw
import mxw, mxw_imgui # for mxw interaction, mxw ui interaction
mxw.print_console("frame " + str(mxw.framecounter))
import cv2         # image processing
mxw.playlist.play()
import numpy as np # math
mxw.widget("/mxw/track/active/layer/active/opacity").setValue(0.5)
 
</syntaxhighlight>
capture_device=""
videosize = (640,480)
f = object()
out = object()


def onCreate():
'''Plugins.''' A plugin is a folder holding a manifest and a Python module:
global capture_device
dev = mxw.media().get_capture_device_names()
capture_device = dev[1]
return


def onAction():
<pre>
global capture_device, out, f
plugins/playlist/python/plugin_my_item/
f = tempfile.NamedTemporaryFile(suffix='.avi')
    mxw_plugin.ini      the manifest: identity, menu entries
f.close()
    mxw_main.py        the Python module with the hook functions
fourcc = cv2.VideoWriter_fourcc('M','P','4','V')
</pre>
out = cv2.VideoWriter(f.name, fourcc, mxw.fps, videosize)
m = mxw.media(capture_device)
if(m.isvalid()):
m.reference(True)
return


def onPostAction():
The host discovers it at startup, shows it in the user interface and calls its hooks at the right moments. See the [[Python plugin reference|Python plugin reference]] for the manifest fields, the full hook list for media and playlist plugins, plugin locations, installing extra packages with <code>mxw-pip</code>, and complete examples.
global capture_device, out, f
out.release()
mxw.preload(1).set_media(f.name)
m = mxw.media(capture_device)
if(m.isvalid()):
m.reference(False)
return


def onNewFrameInPlayoutCue():
== See also ==
global capture_device, out, f
m = mxw.media(capture_device)
if(m.isvalid()):
img = m.get_image_sample_cvmat(videosize[0],videosize[1])
img = np.array(img, copy=False)
img = cv2.flip(img, 0)
out.write(img)
return


# render in panel for settings etc
* [[Python command reference|Python command reference]] &ndash; the <code>mxw</code> module
def onRenderPanel():
* [[Python imgui reference|Python ImGui reference]] &ndash; drawing plugin panels with <code>mxw_imgui</code>
mxw_imgui.text_unformatted("This plugin records a camera")
* [[Python plugin reference|Python plugin reference]] &ndash; writing media and playlist plugins
return
</syntaxhighlight>

Latest revision as of 20:58, 8 August 2026


MXWendler StageDesigner embeds Python 3.12. Python is used in two ways:

  • Command interface / scripting – the module mxw controls the running software (playlist, layers, clips, media, I/O, widgets by their address, ...) from the script console or from within a plugin.
  • Plugins – self-contained folders that add a media source or a playlist item and are called back by the host through a defined set of functions (hooks).

The presented Python interface is supported in version 7.2. and up

Where to go

The detailed documentation lives on three dedicated pages; this page only points to them so nothing is documented twice.

Topic Page
The mxw command interface – software info, playlist, io, widget(address), media(name), preload(n), grabber(name) Python command reference
Drawing plugin settings panels with mxw_imgui (MXWendler's Dear ImGui binding) Python ImGui reference
Writing plugins – media and playlist – the manifest (mxw_plugin.ini), the hooks, per-instance state, examples Python plugin reference

Quick start

A minimal look at each entry point; follow the links above for the full reference.

Scripting. From the script console (or any hook), the mxw module reaches the software:

import mxw
mxw.print_console("frame " + str(mxw.framecounter))
mxw.playlist.play()
mxw.widget("/mxw/track/active/layer/active/opacity").setValue(0.5)

Plugins. A plugin is a folder holding a manifest and a Python module:

plugins/playlist/python/plugin_my_item/
    mxw_plugin.ini      the manifest: identity, menu entries
    mxw_main.py         the Python module with the hook functions

The host discovers it at startup, shows it in the user interface and calls its hooks at the right moments. See the Python plugin reference for the manifest fields, the full hook list for media and playlist plugins, plugin locations, installing extra packages with mxw-pip, and complete examples.

See also