-INTRODUCTION
-------------
+MLT++
+-----
- This document provides a brief tutorial on the use of the mlt++ wrapper
- and bindings.
+ This mlt sub-project provides a C++ wrapping for the MLT library.
+Usage
+-----
+
+ Use the following definitions in a Makefile to compile and link with mlt++:
+
+ CXXFLAGS=`pkg-config --cflags mlt-framework` -Wall
+ LDFLAGS=-lmlt++ `pkg-config --libs mlt-framework`
+
+ Include files for the classes can either be explicitly included, ie:
+
+ #include <mlt++/MltProducer.h>
+ etc
+
+ Or you can include all using:
+
+ #include <mlt++/Mlt.h>
+
+ All definitions are placed in an Mlt namespace, and adhere closely to the C
+ naming convention. Mappings always follow the pattern:
+
+ Factory methods:
+
+ mlt_factory_init ==> Mlt::Factory::init
+ mlt_factory_producer ==> Mlt::Factory::producer
+ mlt_factory_filter ==> Mlt::Factory::filter
+ mlt_factory_transition ==> Mlt::Factory::transition
+ mlt_factory_consumer ==> Mlt::Factory::consumer
+ mlt_factory_close ==> Mlt::Factory::close
+
+ NB: Factory usage for service construction is optional.
+
+ Types:
+
+ mlt_properties ==> Mlt::Properties
+ mlt_frame ==> Mlt::Frame
+ mlt_service ==> Mlt::Service
+ mlt_producer ==> Mlt::Producer
+ mlt_filter ==> Mlt::Filter
+ mlt_transition ==> Mlt::Transition
+ mlt_consumer ==> Mlt::Consumer
+
+ Methods:
+
+ mlt_type_method ==> Mlt::Type.method
+ ie: mlt_playlist_append ==> Mlt::Playlist.append
+
+ Parent methods are available directly on children.
+
+ Additionally, you can specify:
+
+ using namespace Mlt;
+
+ To avoid the enforced use of the Mlt:: prefix.
+
+ Enumerators and macros are reused directly from the C library.
+
+Class Hierarchy
+---------------
+
+ The currently mapped objects are shown in the following hierarchy:
+
+ Factory
+ Properties
+ Frame
+ Service
+ Consumer
+ Field
+ Filter
+ Multitrack
+ Producer
+ Playlist
+ Tractor
+ Transition
+
+Special Cases
+-------------
+
+ Care should be taken with wrapper objects.
+
+ Taking, as an example, the C function that returns the immediate consumer of
+ a service:
+
+ mlt_service mlt_service_consumer( mlt_service );
+
+ This maps to:
+
+ Mlt::Service *Mlt::Service.consumer( );
+
+ Note that you get an object back - it is never the original c++ object, but
+ a wrapping object. This is done to keep consistency with the C api which may
+ instantiate C instances - therefore it cannot be assumed that a C++ object
+ exists for all mlt service instances.
+
+ As such, it is mandatory that you delete these objects. The original will
+ not be affected. However, all other modifications (to properties or its
+ state of connection) will be reflected in the original object.
+
+ This approach excludes the use of RTTI to determine the real type of the
+ object - this can only be done by parsing the objects properties.
+
+ Objects may be invalid - always use the is_valid method to check validity
+ before use.
+
+Limitations
+-----------
+
+ The mechanisms for the definition of new services are deliberately
+ excluded from the C++ wrappings - this is done to ensure that service
+ networks constructed can be serialised and used by existing applications
+ which are based on the C API (such as melted).
Hello World
-----------
As an example, consider the following:
- class Westley
+ class Xml
{
private:
Consumer consumer;
Tractor &tractor;
public:
- Westley( MltTractor &tractor ) :
+ Xml( MltTractor &tractor ) :
tractor( tractor ),
- consumer( "westley" )
+ consumer( "xml" )
{
consumer.connect( tractor );
tractor.listen( tractor, "producer-changed",
- ( mlt_listener )Westley::listener );
+ ( mlt_listener )Xml::listener );
}
- static void listener( Properties *tractor, Westley *object )
+ static void listener( Properties *tractor, Xml *object )
{
object->activate( );
}
}
};
- Now, each time the tractor is changed, the westley representation is output to
+ Now, each time the tractor is changed, the XML representation is output to
stderr.
-Servers and Westley Docs
-------------------------
-
- One of the key features of MLT is its server capabilities. This feature
- allows you to pass westley documents seamlessly from one process to
- another and even to different computers on your network.
-
- The miracle playout server is one such example of an application which
- uses this functionality - you can build your own servers into your own
- processes with ease.
-
- A server process would be running as follows:
-
- #include <mlt++/Miracle>
- using namespace Mlt;
-
- int main( void )
- {
- Miracle miracle( "miracle", 5250 );
- miracle.start( );
- miracle.execute( "uadd sdl" );
- miracle.execute( "play u0" );
- miracle.wait_for_shutdown( );
- return 0;
- }
-
- Typically, when you have an MLT object such as a producer or a playlist,
- you can send a westley representation of this to a running server with:
-
- Conumser valerie( "valerie", "localhost:5250" );
- valerie.connect( producer );
- valerie.start( );
-
- The effect of the push will be to append the producer on to the first
- unit (u0).
-
- You can completely customise the miracle server - an example of this
- is shown below.
-
-
That's All Folks...
-------------------
------
-Servers and Westley Docs
+Servers and MLT XML Docs
------------------------
For various reasons, you might want to serialise a producer to a string.
To do this, you just need to specify a property to write to:
- Consumer westley( "westley", "buffer" );
- westley.connect( producer );
- westley.start( );
- buffer = westley.get( "buffer" );
+ Consumer xml( "xml", "buffer" );
+ xml.connect( producer );
+ xml.start( );
+ buffer = xml.get( "buffer" );
You can use any name you want, and you can change it using the "resource"
property. Any name with a '.' in it is considered to be a file. Hence, you
- can use a westley consumer to store multiple instances of the same MLT
+ can use a xml consumer to store multiple instances of the same MLT
object - useful if you want to provide undo/redo capabilities in an
editing application.
- Should you receive an xml document as a string, and you want to send it
+ Should you receive an XML document as a string, and you want to send it
on to a server, you can use:
- Conumser valerie( "valerie", "localhost:5250" );
- valerie.set( "westley", buffer );
- valerie.start( );
+ Consumer client( "mvsp", "localhost:5250" );
+ client.set( "xml", buffer );
+ client.start( );
- If you need to obtain an MLT object from a string:
+ If you need to obtain an MLT object from a XML string:
- Producer producer( "westley-xml", buffer );
+ Producer producer( "xml-string", buffer );
The following shows a working example of an extended server:
- class ShotcutServer : public Miracle
+ class ShotcutServer : public Melted
{
public:
ShotcutServer( char *id, int port ) :
- Miracle( id, port )
+ Melted( id, port )
{
}
// Reject all commands other than push/receive
Response *execute( char *command )
{
- valerie_response response = valerie_response_init( );
- valerie_response_set_error( response, 400, "Not OK" );
+ mvsp_response response = mvsp_response_init( );
+ mvsp_response_set_error( response, 400, "Not OK" );
return new Response( response );
}
// Push document handler
Response *received( char *command, char *doc )
{
- valerie_response response = valerie_response_init( );
+ mvsp_response response = mvsp_response_init( );
// Use doc in some way and assign Response
if ( doc != NULL )
- valerie_response_set_error( response, 200, "OK" );
+ mvsp_response_set_error( response, 200, "OK" );
return new Response( response );
}
// Push service handler
Response *push( char *command, Service *service )
{
- valerie_response response = valerie_response_init( );
+ mvsp_response response = mvsp_response_init( );
// Use service in some way and assign Response
if ( service != NULL )
- valerie_response_set_error( response, 200, "OK" );
+ mvsp_response_set_error( response, 200, "OK" );
return new Response( response );
}
};