Wejn s.r.o.

Solving complicated IT problems is our hobby.

On Multiple Wowza Module Instances

During my short tenure developing custom modules for Wowza Media Server I’ve quite often came across the need for multiple module instances within single Application instance.

Having this feature would make some of my modules more UNIX-y (do one thing and do it well).

Without it, I usually solved this need the hard way; I made the module run everything in single instance and implemented complicated logic just to handle the same task in multiple instances (i.e. publishing multiple Stream instances and filling them with proper Playlist data).

And then it struck me; the only reason I was scratching my left ear with my right hand.

I couldn’t properly configure two Wowza module instances within single Application instance as I was reading the same Property keys.

That was the only thing missing – to be able to pull different WMSProperties out of the Application.xml for each instance.

Well, after this aha moment it took less than one hour (of quality time with ant watch and Wowza API documentation) to arrive at an acceptable solution. Not a beautiful one, mind you; just acceptable.

And it’s this simple:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import com.wowza.wms.module.*;
import com.wowza.wms.application.*;
import com.wowza.wms.logging.*;

// get your own name -- you can use it as property prefix

public class Module extends ModuleBase
{
    public void onAppStart(IApplicationInstance ai)
    {
        for (Object mn: ai.getModuleList().getModuleNames()) {
            if (ai.getModuleList().getModuleItem((String) mn).
                    getInstance().equals(this)) {
                getLogger().info("My name: " + (String) mn);
            }
        }
    }
}

To translate this to English: when you lookup your Module’s name and use that as a prefix for all your application instance Property lookups, you can simply do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- ... -->
<Modules>
    <!-- ... -->
    <Module>
        <Name>module1</Name>
        <Description>My awesome Wowza Module (1)</Description>
        <Class>cz.wejn.awesome.Module</Class>
    </Module>
    <Module>
        <Name>module2</Name>
        <Description>My awesome Wowza Module (2)</Description>
        <Class>cz.wejn.awesome.Module</Class>
    </Module>
</Modules>
<!-- ... -->
<Properties>
    <Property>
        <Name>module1ImportantProperty</Name>
        <Value>yay</Value>
    </Property>
    <Property>
        <Name>module2ImportantProperty</Name>
        <Value>yay indeed</Value>
    </Property>
</Properties>

and coupled with the following source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package cz.wejn.awesome;

import com.wowza.wms.module.*;
import com.wowza.wms.application.*;
import com.wowza.wms.logging.*;

// get your own name -- you can use it as property prefix

public class Module extends ModuleBase
{
    private String name = null;

    public void onAppStart(IApplicationInstance ai)
    {
        for (Object mn: ai.getModuleList().getModuleNames()) {
            if (ai.getModuleList().getModuleItem((String) mn).
                    getInstance().equals(this)) {
                // getLogger().info("Found my name: " + (String) mn);
                this.name = (String) mn;
            }
        }

        if (this.name == null) {
            getLogger().warn("awesome.Module[" + ai.getContextStr() +
                "]: Couldn't quite figure out my own name. :-(");
        } else {
            WMSProperties props = ai.getProperties();
            String prop = props.getPropertyStr(this.name +
                "ImportantProperty");
            if (prop == null) {
                getLogger().warn("awesome.Module<" + this.name + ">[" +
                    ai.getContextStr() + "]: No property for me. :-(");
            } else {
                getLogger().info("awesome.Module<" + this.name + ">[" +
                    ai.getContextStr() + "]: Got it: " + prop);
            }
        }
    }
}

will get you following server comments on Application start:

1
2
INFO awesome.Module<module1>[vod/_definst_]: Got it: yay
INFO awesome.Module<module2>[vod/_definst_]: Got it: yay indeed

Now, if that’s not awesome then I don’t know what is.

Btw, you can get the full source code of the example on GitHub.