Control nDVR with Flash Media Live Encoder

If you have ever used Flash Media Live Encoder (FMLE) then you will have noticed the ‘Record’ button at the bottom right, next to the tick box for ‘DVR Auto Record’. If you are connected to Wowza and push this button all you should see in your logs is

WARN server comment – Missing function: DVRSetStreamInfo

It is possible to add this function to Wowza using a custom module and the basic pragma for the function is

public void DVRSetStreamInfo(IClient client, RequestFunction function, AMFDataList params) { }

Now when you push the button in FMLE there should be no log entry, as the function is found, however just adding the above line will not actually do anything, further more it is not possible to see any information being sent.
To add some debugging for the function the following can be used

public void DVRSetStreamInfo(IClient client, RequestFunction function, AMFDataList params)
{
for ( int entries = 0 ; entries<params.size(); entries ++ )
{
getLogger().info(“Parameter “+entries+” value “+params.get(entries));
}
}

When you now click the button you get the following output in your Wowza logs

INFO server comment – Parameter 0 value DVRSetStreamInfo
INFO server comment – Parameter 1 value 0.0
INFO server comment – Parameter 2 value null
INFO server comment – Parameter 3 value {Obj[]: streamName: “myStream”, callTime: “Thu, 08 May 2014 10:47:22 GMT”, startRec: “Thu, 08 May 2014 10:47:22 GMT”, stopRec: “Wed, 31 Dec 1969 23:59:59 GMT”, maxLen: 0.0, begOffset: 0.0, endOffset: 0.0, append: false, offline: false, dynamicStreamSet: {Array: 0: “myStream”}}

You can see a variety of parameters in the third entry in the params list. The important elements are streamName, callTime, startRec, stopRec.
If you click the button a second time, so to stop the DVR functionality via FMLE then you will see

INFO server comment – Parameter 0 value DVRSetStreamInfo
INFO server comment – Parameter 1 value 0.0
INFO server comment – Parameter 2 value null
INFO server comment – Parameter 3 value {Obj[]: streamName: “myStream”, callTime: “Thu, 08 May 2014 10:47:28 GMT”, startRec: “Wed, 31 Dec 1969 23:59:59 GMT”, stopRec: “Thu, 08 May 2014 10:47:28 GMT”, maxLen: 0.0, begOffset: 0.0, endOffset: 0.0, append: true, offline: false, dynamicStreamSet: {Array: 0: “myStream”}}

You can see when a DVR request to start is made the stopRec is set to Wed, 31 Dec 1969 23:59:59 GMT, and a request to stop the stopRec is Thu, 08 May 2014 10:47:28 GMT (which is the current time).
Using this simple logic we can build a module which can control nDVR start/stop within Wowza while using FMLE. The function would look like the following

	public void DVRSetStreamInfo(IClient client, RequestFunction function,
			AMFDataList params) 
		{
		HashMap Items = new HashMap(); AMFDataObj arr2 = (AMFDataObj)params.get(3);
		for ( int parts = 0 ; parts < arr2.size(); parts ++ )
			{			
			if ( arr2.get(parts).getClass().getName().equals("com.wowza.wms.amf.AMFDataItem") )
				{
				AMFDataItem thisItem = (AMFDataItem)arr2.get(parts);
				Items.put(arr2.getKey(parts), thisItem.toString());								
				}
			}
		
		if ( Items.containsKey("streamName") && Items.containsKey("stopRec") )
			{
			ILiveStreamDvrRecorder dvrRecorder = null;
			IMediaStream stream = client.getAppInstance().getStreams().getStream(Items.get("streamName"));
			if (Items.get("stopRec").equals("Wed, 31 Dec 1969 23:59:59 GMT") )
				{
				getLogger().info("Start recording called for streamName '"+Items.get("streamName")+"'");
				try 
					{
					dvrRecorder = stream.getDvrRecorder(IDvrConstants.DVR_DEFAULT_RECORDER_ID);
					}
					catch (Exception e) {}
			
				if ( dvrRecorder != null )
					{
					if (dvrRecorder.isRecording()) 
						{
						dvrRecorder.stopRecording();
						}
					dvrRecorder.setRecordingName(Items.get("streamName"));
					dvrRecorder.startRecording();
					}
				}
				else
				{
				getLogger().info("Stop recording called for streamName '"+Items.get("streamName")+"'");
				try 
					{
					dvrRecorder = stream.getDvrRecorder(IDvrConstants.DVR_DEFAULT_RECORDER_ID);
					}
					catch (Exception e) {}
		
				if ( dvrRecorder != null )
					{
					if (dvrRecorder.isRecording()) 
						{
						dvrRecorder.stopRecording();
						}
					}
				}
			}	
		}

For this code to work effectively it needs to be applied into a Wowza Module but also a Property needs to be added to the Application.xml.
Normally when a stream connects to Wowza nDVR (if configured) automatically starts. In this case you do not want this to happen so the following property needs to be added to the DVR section in the Properties block

<Property>
<Name>startRecordingOnStartup</Name>
<Value>false</Value>
<Type>boolean</Type>
</Property>

Comments are closed.