• How to use event listeners in Wowza Media Server

    You can use event listeners in Wowza Media Server™ to capture certain events in order to extend the server functionality. Server event listeners and virtual host event listeners can be configured in the Server.xml file and are called when events occur at a server or virtual host level. Other event listeners can be invoked using API methods and are called when events occur that the listener is configured to listen for. For more information about these methods, see the Wowza Media Server Server-Side API. This article describes the most common event listeners.

    Contents



    Overview

    Server Listener (IServerNotify2)

    Virtual Host Listener (IVHostNotify)

    MediaStream Listener (IMediaStreamNotify)

    MediaStream Action Listeners (IMediaStreamActionNotify3)

    Stream Name Alias Provider (IMediaStreamNameAliasProvider2)

    Other Event Listeners

    Overview



    With most event listeners, you can have multiple listeners of the same type. When an event is triggered, the listener method is called for each listener in the order that the listeners are added in the configuration file. For server listeners and virtual host Listeners, this is the order that they appear in the [install-dir]/conf/Server.xml file. For other listeners, this is the order that their add*Listener method was called. It's important to remember this when working with multiple listeners as one listener could set or modify a value and then another listener could modify the previous value. The values that are specified by the last listener that's called are always used.

    Other event listeners only have one instance per application instance. These are normally invoked with a Set method instead of an Add method. These listeners are used to override the default action that would occur when an event is triggered.

    When a new listener interface version is released to add new functionality, the new version has a number allocated and the original version is retained for backward compatibility. Old listener versions might not be removed so you should always use the newer version in any new code.

    Server Listener (IServerNotify2)



    Server listeners are notified of the server lifecycle and are a great place to invoke and attach functionality that you want to make available when Wowza Media Server is running. Examples of such functionality include:

    • Database configuration.

    • Custom code that must run on server startup or shutdown.

    • 3rd-party services such as Web Services or custom HTTP interfaces.

    The following example shows a simple server listener that just logs each of the listener calls:
    package com.mycompany.wms;
    
    import com.wowza.wms.logging.*;
    import com.wowza.wms.server.*;
    
    public class MyServerListener implements IServerNotify2
    {
    	/*
    	 * Called after the Server.xml file has been loaded. This is the earliest point where you can access Server events.
    	 */
    	public void onServerConfigLoaded(IServer server)
    	{
    		WMSLoggerFactory.getLogger(null).info("onServerConfigLoaded");
    	}
    
    	/*
    	 * Called after the Server is created but not yet initialized.
    	 */
    	public void onServerCreate(IServer server)
    	{
    		WMSLoggerFactory.getLogger(null).info("onServerCreate");
    	}
    
    	/*
    	 * Called after the Server is initialized.  At this point, the server is running, all VHosts have been initialized and the Server is ready to accept connections.
    	 */
    	public void onServerInit(IServer server)
    	{
    		WMSLoggerFactory.getLogger(null).info("onServerInit");
    	}
    
    	/*
    	 * Called when the Server starts to shut down.
    	 */
    	public void onServerShutdownStart(IServer server)
    	{
    		WMSLoggerFactory.getLogger(null).info("onServerShutdownStart");
    	}
    
    	/*
    	 * Called when the Server shutdown process is complete.  This is the last event that is triggered before the Wowza process exits.
    	 */
    	public void onServerShutdownComplete(IServer server)
    	{
    		WMSLoggerFactory.getLogger(null).info("onServerShutdownComplete");
    	}
    
    }
    After a server listener is compiled, packaged into a .jar file, and placed in the [install-dir]/lib folder, it can be invoked by adding an entry to the <ServerListeners> container in [install-dir]/conf/Server.xml:
    <ServerListener>
    	<BaseClass>com.mycompany.wms.MyServerListener</BaseClass>
    </ServerListener>
    See Also:


    Virtual Host Listener (IVHostNotify)



    Virtual host listeners are notified of the virtual host lifecycle. When the server starts, the listener onVHostCreate and onVHostInit methods are called for each virtual host that's configured in [install-dir]/conf/VHosts.xml. When these methods are called, the virtual host isn't ready to accept connections so any configuration that's required after a virtual host is started should be done in onServerInit (see above), which is called after the virtual hosts are initialized.

    Note: Only one instance of each virtual host listener is running. When running multiple virtual hosts, be careful when using instance-level variables in the listener.

    The following example shows a simple virtual host listener that just logs each of the listener calls:
    package com.mycompany.wms;
    
    import com.wowza.wms.amf.AMFDataList;
    import com.wowza.wms.client.IClient;
    import com.wowza.wms.logging.WMSLoggerFactory;
    import com.wowza.wms.request.RequestFunction;
    import com.wowza.wms.vhost.IVHost;
    import com.wowza.wms.vhost.IVHostNotify;
    
    public class MyVHostListener implements IVHostNotify
    {
    
    	/*
    	 * Called when the Virtual Host is first created.
    	 */
    	@Override
    	public void onVHostCreate(IVHost vhost)
    	{
    		WMSLoggerFactory.getLogger(null).info("onVHostCreate");
    	}
    
    	/*
    	 * Called when the Virtual Host is first initialized.
    	 */
    	@Override
    	public void onVHostInit(IVHost vhost)
    	{
    		WMSLoggerFactory.getLogger(null).info("onVHostInit");
    	}
    
    	/*
    	 * Called when the Virtual Host starts to shut down.
    	 */
    	@Override
    	public void onVHostShutdownStart(IVHost vhost)
    	{
    		WMSLoggerFactory.getLogger(null).info("onVHostShutdownStart");
    	}
    
    	/*
    	 * Called when the Virtual Host shutdown process is complete.
    	 */
    	@Override
    	public void onVHostShutdownComplete(IVHost vhost)
    	{
    		WMSLoggerFactory.getLogger(null).info("onVHostShutdownComplete");
    	}
    
    	/*
    	 * Called whenever an RTMP client connects to the Virtual Host.
    	 */
    	@Override
    	public void onVHostClientConnect(IVHost vhost, IClient inClient, RequestFunction function, AMFDataList params)
    	{
    		WMSLoggerFactory.getLogger(null).info("onVHostClientConnect");
    	}
    
    }
    After a virtual host listener is compiled, packaged into a .jar file, and placed in the [install-dir]/lib folder, it can be invoked by adding an entry to the <VHostListeners> container in [install-dir]/conf/Server.xml:
    <VHostListener>
    	<BaseClass>com.mycompany.wms.MyVHostListener</BaseClass>
    </VHostListener>
    See Also:


    MediaStream Listener (IMediaStreamNotify)



    MediaStream listeners are used to listen for stream Create and Destroy events. These listeners are used in custom classes that aren't Wowza Media Server modules.

    The following example shows a simple MediaStream listener that logs the stream Create and Destroy events:
    package com.mycompany.wms;
    
    import com.wowza.wms.logging.WMSLoggerFactory;
    import com.wowza.wms.stream.IMediaStream;
    import com.wowza.wms.stream.IMediaStreamNotify;
    
    public class MyMediaStreamListener implements IMediaStreamNotify
    {
    
    	@Override
    	public void onMediaStreamCreate(IMediaStream stream)
    	{
    		WMSLoggerFactory.getLogger(null).info("onMediaStreamCreate: " + stream.getSrc());
    	}
    
    	@Override
    	public void onMediaStreamDestroy(IMediaStream stream)
    	{
    		WMSLoggerFactory.getLogger(null).info("onMediaStreamDestroy: " + stream.getSrc());
    	}
    }
    This listener is added or removed using appInstance methods.
    package com.mycompany.wms;
    
    import com.wowza.wms.application.IApplicationInstance;
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.*;
    
    public class MyModule extends ModuleBase
    {
    	private IMediaStreamNotify mediaStreamListener = new MyMediaStreamListener();
    
    	public void onAppStart(IApplicationInstance appInstance)
    	{
    		appInstance.addMediaStreamListener(mediaStreamListener);
    	}
    	
    	public void onAppStop(IApplicationInstance appInstance)
    	{
    		appInstance.removeMediaStreamListener(mediaStreamListener);
    	}
    }
    There are also Module Stream Event methods that capture the MediaStream Create and Destroy events. Any module that has these methods is also called when the events occur.
    package com.mycompany.wms;
    
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.*;
    
    public class MyModule extends ModuleBase
    {
    
    	public void onStreamCreate(IMediaStream stream)
    	{
    		getLogger().info("onStreamCreate: " + stream.getSrc());
    	}
    
    	public void onStreamDestroy(IMediaStream stream)
    	{
    		getLogger().info("onStreamDestroy: " + stream.getSrc());
    	}
    
    }

    MediaStream Action Listener (IMediaStreamActionNotify3)



    MediaStream action listeners receive Play, Pause, Seek, and Stop events for Adobe Flash Player streams. They also receive publish, codec, and metadata events for all published streams. They don't receive player events from HTTP or RTSP streams. The following example shows a simple MediaStream action listener:
    package com.mycompany.wms;
    
    import com.wowza.wms.amf.AMFPacket;
    import com.wowza.wms.logging.WMSLoggerFactory;
    import com.wowza.wms.media.model.MediaCodecInfoAudio;
    import com.wowza.wms.media.model.MediaCodecInfoVideo;
    import com.wowza.wms.stream.IMediaStream;
    import com.wowza.wms.stream.IMediaStreamActionNotify3;
    
    public class MyMediaStreamListener implements IMediaStreamActionNotify3
    {
    
    	@Override
    	public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket)
    	{
    		WMSLoggerFactory.getLogger(null).info("onMetaData: " + stream.getName());
    	}
    
    	@Override
    	public void onPauseRaw(IMediaStream stream, boolean isPause, double location)
    	{
    		WMSLoggerFactory.getLogger(null).info("onPauseRaw: " + stream.getName());
    	}
    
    	@Override
    	public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset)
    	{
    		WMSLoggerFactory.getLogger(null).info("onPlay: " + stream.getName());
    	}
    
    	@Override
    	public void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
    	{
    		WMSLoggerFactory.getLogger(null).info("onPublish: " + stream.getName());
    	}
    
    	@Override
    	public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
    	{
    		WMSLoggerFactory.getLogger(null).info("onUnPublish: " + stream.getName());
    	}
    
    	@Override
    	public void onPause(IMediaStream stream, boolean isPause, double location)
    	{
    		WMSLoggerFactory.getLogger(null).info("onPause: " + stream.getName());
    	}
    
    	@Override
    	public void onSeek(IMediaStream stream, double location)
    	{
    		WMSLoggerFactory.getLogger(null).info("onSeek: " + stream.getName());
    	}
    
    	@Override
    	public void onStop(IMediaStream stream)
    	{
    		WMSLoggerFactory.getLogger(null).info("onStop: " + stream.getName());
    	}
    
    	@Override
    	public void onCodecInfoVideo(IMediaStream stream, MediaCodecInfoVideo codecInfoVideo)
    	{
    		WMSLoggerFactory.getLogger(null).info("onCodecInfoVideo: " + stream.getName());
    	}
    
    	@Override
    	public void onCodecInfoAudio(IMediaStream stream, MediaCodecInfoAudio codecInfoAudio)
    	{
    		WMSLoggerFactory.getLogger(null).info("onCodecInfoAudio: " + stream.getName());
    	}
    }
    After a MediaStream listener is compiled, packaged into a .jar file, and placed in the [install-dir]/lib folder, it can be invoked by creating an instance of this object and attaching it to an IMediaStream object. You might do this in an onStreamCreate event method and remove it using an onStreamDestroy event method. For example:
    package com.mycompany.wms;
    
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.*;
    
    public class MyModule extends ModuleBase
    {
    	private MyMediaStreamListener actionListener = new MyMediaStreamListener();
    
    	public void onStreamCreate(IMediaStream stream) 
    	{
    		stream.addClientListener(actionListener);
    	}
    	
    	public void onStreamDestroy(IMediaStream stream)
    	{
    		stream.removeClientListener(actionListener);
    	}
    }
    See Also:


    Stream Name Alias Provider (IMediaStreamNameAliasProvider2)



    A MediaStream Name Alias Provider is a special event listener that's called during stream playback and MediaCaster creation events to resolve the name of the stream that should be played or the URL that the MediaCaster should connect to. An application instance can only have one MediaStream Name Alias Provider. When you set it, it replaces the default Name Provider that uses .stream files.

    The following example shows a simple MediaStream Name Alias Provider listener that simply returns the same name that's passed into each method:
    package com.mycompany.wms;
    
    import com.wowza.wms.application.IApplicationInstance;
    import com.wowza.wms.client.IClient;
    import com.wowza.wms.httpstreamer.model.IHTTPStreamerSession;
    import com.wowza.wms.mediacaster.IMediaCaster;
    import com.wowza.wms.rtp.model.RTPSession;
    import com.wowza.wms.stream.IMediaStreamNameAliasProvider2;
    import com.wowza.wms.stream.livepacketizer.ILiveStreamPacketizer;
    
    public class MyStreamNameAliasProvider implements IMediaStreamNameAliasProvider2
    {
    	@Override
    	public String resolvePlayAlias(IApplicationInstance appInstance, String name)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolvePlayAlias(IApplicationInstance appInstance, String name, IClient client)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolvePlayAlias(IApplicationInstance appInstance, String name, IHTTPStreamerSession httpSession)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolvePlayAlias(IApplicationInstance appInstance, String name, RTPSession rtpSession)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolvePlayAlias(IApplicationInstance appInstance, String name, ILiveStreamPacketizer liveStreamPacketizer)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolveStreamAlias(IApplicationInstance appInstance, String name)
    	{
    		return name;
    	}
    
    	@Override
    	public String resolveStreamAlias(IApplicationInstance appInstance, String name, IMediaCaster mediaCaster)
    	{
    		return name;
    	}
    }
    Again, this is best set during onAppStart in a custom module.
    package com.mycompany.wms;
    
    import com.wowza.wms.application.IApplicationInstance;
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.IMediaStreamNameAliasProvider2;
    
    public class MyModule extends ModuleBase
    {
    	private IMediaStreamNameAliasProvider2 streamNameAliasProvider = new MyStreamNameAliasProvider();
    
    	public void onAppStart(IApplicationInstance appInstance)
    	{
    		appInstance.setStreamNameAliasProvider(streamNameAliasProvider);
    	}
    }
    See Also:



    Other Event Listeners



    There are many other event listeners that are used with Wowza Media Server. For more information, see the Wowza Media Server Server-Side API documentation.

    See Also:



    Originally Published: 05-23-2013.

    If you're having problems or want to discuss this article, post in our forum.