October 5, 2011

Maven template for Wowza

First of all let me explain why I decided to develop WMSPanel Wowza integration using Maven.
When I started my first steps with Wowza I downloaded Wowza IDE and easily made my first test project. All looked just fine but after some time I decided that Wowza IDE is not applicable in my case because of the following reasons.
  1. It does not support full development cycle. You can create Module or Listener but you cannot create and run Unit Tests, cannot add dependencies that will be copied with your jar before Wowza launch.
  2. After any change of any source file IDE tries to build jar and copy it. I want to have ability to implement some features and then build jar and copy it explicitly.
  3. There are a lot of libraries we cannot work in general. Apache langs and codacs, joda time library. Those who work with Java professionally knows what I'm talking about. Maven is just great when you need to add publically available libraries.
  4. You cannot control jar manifest produced by IDE. If you need your jar to have some additional attributes you should use Maven. Wowza IDE cannot help you here.
Wowza IDE produces regulair jar file with our compiled classes included so we use maven-jar-plugin for making jar library as well.

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <finalName>${project.artifactId}</finalName>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>${libFolderName}/</classpathPrefix>
                        </manifest>
                        <manifestEntries>
                        </manifestEntries>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>

Since your library most probably needs to have dependencies you should separate your dependencies from Wowza server libraries and third-party libraries. This is why we add classpath to our dependency folder into jar manifiest. In addition we ask not to include our pom.xml to resulting jar.

To build our jar file as wowza extention we need to have compile time dependency on Wowza libs.

Our test template depends on wms-server.jar and wms-stream-publish.jar. So we copy these libraries to project' lib folder from wowza/lib folder and add them to dependency section.

    <dependencies>
        <dependency>
            <groupId>com.wms</groupId>
            <artifactId>wms-server</artifactId>
            <version>${wms.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.wms</groupId>
            <artifactId>wms-stream-publish</artifactId>
            <version>${wms.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>1.6</version>
        </dependency>
    </dependencies>

As you can see I added joda runtime library dependency to the project. I don't use joda in code but just added this runtime dependency to show how dependency copy works with maven. You can see joda library in wowza\lib\dep-libs after mvn package


Since neither wms-server.jar nor wms-stream-publish.jar are Maven repository libraries we need to introduce them to Maven. Take a look at maven-install-plugin in pom.xml below. Before packing solution you should call mvn validate each time you add new dependency you need to install. During validate phase maven-install-plugin plugin adds all libraries it's configured with into local Maven repository.

To copy "runtime" library dependencies I use maven-dependency-plugin. It copies all runtime dependencies to target/deps-lib subfolder.

Before launching Wowza you need to copy resulting jar with all dependencied to wowza/lib directory.
I use maven-antrun-plugin for this purposes. When you call mvn package system builds jar and copies jar and it's dependencies to wowza/lib.

The last major case I missed to discuss is debugging. I checked how debugging works for Wowza IDE. It just calls JVM with following parameter(Wowza 2, 3.x)
-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:3387,suspend=y,server=n -Xmx768M "-Dcom.wowza.wms.AppHome=C:/Program Files/Wowza Media Systems/Wowza Media Server 2.2.4" "-Dcom.wowza.wms.ConfigHome=C:/Program Files/Wowza Media Systems/Wowza Media Server 2.2.4" -Dcom.sun.management.jmxremote=true -Dfile.encoding=Cp1251 -classpath "C:\Program Files\Wowza Media Systems\Wowza Media Server 2.2.4\bin\wms-bootstrap.jar" com.wowza.wms.bootstrap.Bootstrap start

Or for new Wowza Engine(aka Wowza 4.0)
-agentlib:jdwp=transport=dt_socket,address=127.0.0. 1:3387,suspend=y,server=n -Xmx768M -Dcom.wowza.wms.AppHome=/usr/local/WowzaStreamingEngine -Dcom.wowza.wms.ConfigHome=/usr/local/WowzaStreamingEngine -Dcom.sun.management.jmxremote=true -Dcom.wowza.wms.native.base="linux" -classpath "/usr/local/WowzaStreamingEngine/bin/wms-bootstrap.jar" com.wowza.wms.bootstrap.Bootstrap start
 
So I just get parameters IDE uses and configured exec:java goal to use JVM parameters above. Open project using any IDE with Maven support and configure Maven goal exec:java and find where you can pass JVM parameters. Pass parameters above and use Debug mode to execute goal since Run mode will not work. If you need Run mode working you need to call Wowza IDE in Run mode and get parameters it uses to call java and then add new exec:java goal with params for Run. I just use Debug during development cycle and don't use Run.

Please note that my approach to Wowza is not yours and you most probably need to fix JVM params. In addition I use Windows and if this is not your case you should change all paths in JVM params appropriately.

Our Wowza Maven template is hosted on GitHub, you can download it there and try. I added Server listener from the following article http://www.wowza.com/forums/content.php?162-Server-side-publishing-using-the-Stream-class so follow installation instruction, such as config change, before you can start Wowza.


The approach described above is just little a example of our WMSPanel agent build system. We have comprehensive installer what fixes Wowza configs during installation, installs resulting Wowza library and its dependencies when client runs it on a production Wowza server. We provide consulting services for existing and new Wowza projects. So if you want to have comprehensive installer for Wowza, run unit test during package your project or use any IDE with Maven support, we can help you.

You may also check WMSPanel, a centralized Wowza reports and statistics web-based solution. It uses Wowza agent for gathering core streaming data and present it via a web server. Check out the feature list and try it free of charge.

Take a look also at Nimble Streamer, the light-weight HTTP streaming server for HLS, Smooth and progressive download streaming and re-streaming.

5 comments:

  1. Nice article. Do you use Spring? Especially dependency injection from ApplicationContext.xml files?

    ReplyDelete
  2. Hi David,
    no we currently don't. But if necessary it's not a problem espesially with maven support

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thanks. I was worried about Spring compatibility with Wowza, but sounds like you are not aware of any issues so I'll go on ahead and start to work on a sample solution.
    PS. Following your sample, I already have my first plugin implemented and running to a debug breakpoint so your blog was really helpful.

    I'll also take a look at your WMSPanel. Looks interesting and helpful as we start to scale.

    ReplyDelete
  5. Welcome,
    I glad this post was helpful. Post your questions and follow our blog to have most recent info from us.

    ReplyDelete