add MltProfile and update examples
[melted] / mlt++ / test / server.cpp
1 #include <iostream>
2 #include <string>
3 #include <sstream>
4 using namespace std;
5
6 #include <Mlt.h>
7 using namespace Mlt;
8
9 class Custom : public Miracle
10 {
11 private:
12 Event *event;
13 Profile profile;
14
15 public:
16 Custom( char *name = "Custom", int port = 5290, char *config = NULL ) :
17 Miracle( name, port, config ),
18 event( NULL )
19 {
20 // Ensure that we receive the westley document before it's deserialised
21 set( "push-parser-off", 1 );
22 }
23
24 virtual ~Custom( )
25 {
26 delete event;
27 }
28
29 // Optional step - receive the westley document and do something with it
30 Response *received( char *command, char *document )
31 {
32 cerr << document << endl;
33 Producer producer( profile, "westley-xml", document );
34 return push( command, &producer );
35 }
36
37 // Push handling - clear the playlist, append, seek to beginning and play
38 Response *push( char *command, Service *service )
39 {
40 Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
41 Producer producer( *service );
42 if ( producer.is_valid( ) && playlist.is_valid( ) )
43 {
44 playlist.lock( );
45 playlist.clear( );
46 playlist.append( producer );
47 playlist.seek( 0 );
48 playlist.set_speed( 1 );
49 playlist.unlock( );
50 return new Response( 200, "OK" );
51 }
52 return new Response( 400, "Invalid" );
53 }
54
55 // Custom command execution
56 Response *execute( char *command )
57 {
58 Response *response = NULL;
59
60 if ( !strcmp( command, "debug" ) )
61 {
62 // Example of a custom command
63 response = new Response( 200, "Diagnostics output" );
64 for( int i = 0; unit( i ) != NULL; i ++ )
65 {
66 Properties *properties = unit( i );
67 stringstream output;
68 output << string( "Unit " ) << i << endl;
69 for ( int j = 0; j < properties->count( ); j ++ )
70 output << properties->get_name( j ) << " = " << properties->get( j ) << endl;
71 response->write( output.str( ).c_str( ) );
72 }
73 }
74 else
75 {
76 // Use the default command processing
77 response = Miracle::execute( command );
78 }
79
80 // If no event exists and the first unit has been added...
81 if ( event == NULL && unit( 0 ) != NULL )
82 {
83 // Set up the event handling
84 Consumer consumer( ( mlt_consumer )( unit( 0 )->get_data( "consumer" ) ) );
85 event = consumer.listen( "consumer-frame-render", this, ( mlt_listener )frame_render );
86
87 // In this custom case, we'll loop everything on the unit
88 Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) );
89 playlist.set( "eof", "loop" );
90 }
91
92 return response;
93 }
94
95 // Callback for frame render notification
96 static void frame_render( mlt_consumer consumer, Custom *self, mlt_frame frame_ptr )
97 {
98 Frame frame( frame_ptr );
99 self->frame_render_event( frame );
100 }
101
102 // Remove all supers and attributes
103 void frame_render_event( Frame &frame )
104 {
105 // Fetch the c double ended queue structure
106 mlt_deque deque = ( mlt_deque )frame.get_data( "data_queue" );
107
108 // While the deque isn't empty
109 while( deque != NULL && mlt_deque_peek_back( deque ) != NULL )
110 {
111 // Fetch the c properties structure
112 mlt_properties cprops = ( mlt_properties )mlt_deque_pop_back( deque );
113
114 // For fun, convert it to c++ and output it :-)
115 Properties properties( cprops );
116 properties.debug( );
117
118 // Wipe it
119 mlt_properties_close( cprops );
120 }
121 }
122 };
123
124 int main( int argc, char **argv )
125 {
126 Custom server( "Server" );
127 server.start( );
128 server.execute( "uadd sdl" );
129 server.execute( "play u0" );
130 server.wait_for_shutdown( );
131 return 0;
132 }
133