Skip to content
Knugi edited this page May 23, 2020 · 5 revisions

Welcome

This is a simple implementation of a Flash RTMP server to accept connections and stream requests. The module is organized as follows:

  1. The FlashServer class is the main class to provide the server abstraction. It uses the multitask module for co-operative multitasking. It also uses the App abstract class to implement the applications.
  2. The Server class implements a simple server to receive new Client connections and inform the FlashServer application. The Client class derived from Protocol implements the RTMP client functions. The Protocol class implements the base RTMP protocol parsing. A Client contains various streams from the client, represented using the Stream class.
  3. The Message, Header and Command represent RTMP message, header and command respectively. The FLV class implements functions to perform read and write of FLV file format.

Deploy as a normal server

Typically an application can launch this server as follows:

$ python rtmp.py

To know the command line options use the -h option:

$ python rtmp.py -h

To start the server with a different directory for recording and playing FLV files from, use the following command.

$ python rtmp.py -r some-other-directory/

Note the terminal '/' in the directory name. Without this, it is just used as a prefix in FLV file names.

Testing

I recommend FFmpeg/OBS and FFplay be your testing and debugging tools.

More documentation needed here

Use as a library

If an application wants to use this module as a library, it can launch the server as follows:

>>> agent = FlashServer()   # a new RTMP server instance
>>> agent.root = 'flvs/'    # set the document root to be 'flvs' directory. Default is current './' directory.
>>> agent.start()           # start the server
>>> multitask.run()         # this is needed somewhere in the application to actually start the co-operative multitasking.

Event handling in traditional way

If an application wants to specify a different application other than the default App, it can subclass it and supply the application by setting the server's apps property. The following example shows how to define "myapp" which invokes a 'connected()' method on client when the client connects to the server.

class MyApp(App):         # a new MyApp extends the default App in rtmp module.
    def __init__(self):   # constructor just invokes base class constructor
        App.__init__(self)
    def onConnect(self, client, *args):
        result = App.onConnect(self, client, *args)   # invoke base class method first
        def invokeAdded(self, client):                # define a method to invoke 'connected("some-arg")' on Flash client
            yield client.call('connected', 'some-arg')
        multitask.add(invokeAdded(self, client))      # need to invoke later so that connection is established before callback
        return result     # return True to accept, or None to postpone calling accept()
...
agent.apps = dict({'myapp': MyApp, 'someapp': MyApp, '*': App})

Now the client can connect to rtmp://server/myapp or rtmp://server/someapp and will get connected to this MyApp application. If the client doesn't define "function connected(arg:String):void" in the NetConnection.client object then the server will throw an exception and display the error message.