Recorder Module which uses Wowza Streaming Engine APIs

This is a basic module that uses the newer recording APIs to record ALL streams that are made available to Wowza. When a recording is started it will also show up in the Manager and can be managed there.

The code shows how to set up specific parameters such as format and how to set a specific filename for the recording.

package guru.thewowza.module;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.application.*;
import com.wowza.wms.livestreamrecord.manager.*;
import com.wowza.wms.media.model.MediaCodecInfoAudio;
import com.wowza.wms.media.model.MediaCodecInfoVideo;
import com.wowza.wms.module.*;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.stream.IMediaStreamActionNotify3;
import com.wowza.wms.vhost.*;

public class Recorder extends ModuleBase 
{
	private IApplicationInstance appInstance = null;
	private IVHost vhost = null;
	
	public void onAppStart(IApplicationInstance appInstance)
	{
		this.appInstance = appInstance;
		this.vhost = appInstance.getVHost();
		getLogger().info("Recorder.onAppStart");
	} 
	
	public void onAppStop(IApplicationInstance appInstance) 
	{ 
		getLogger().info("Recorder.onAppStop"); 
	}
	
	class StreamListener implements IMediaStreamActionNotify3
	{
		IVHost vhost = null;
		IApplicationInstance appInstance = null;
		
		public StreamListener ( IVHost ivhost, IApplicationInstance appins )
		{
			this.vhost = ivhost;
			this.appInstance = appins;
		}
		
		public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) { }
		public void onPauseRaw(IMediaStream stream, boolean isPause, double location) { }
		public void onPause(IMediaStream stream, boolean isPause, double location) { }
		public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset) { }
		public void onSeek(IMediaStream stream, double location) { }
		public void onStop(IMediaStream stream) { }
		public void onCodecInfoAudio(IMediaStream stream,MediaCodecInfoAudio codecInfoAudio) { }
		public void onCodecInfoVideo(IMediaStream stream,MediaCodecInfoVideo codecInfoVideo) { }

		public void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
		{
			StreamRecorderParameters recordParams = new StreamRecorderParameters(this.appInstance);
			recordParams.fileFormat = IStreamRecorderConstants.FORMAT_MP4;
			recordParams.outputFile = setFilename(streamName,"yyyyMMddHHmmss");
			recordParams.versioningOption = IStreamRecorderConstants.OVERWRITE_FILE;
			recordParams.segmentationType = IStreamRecorderConstants.SEGMENT_NONE;
			recordParams.startOnKeyFrame = true;
			recordParams.recordData = true;
			this.vhost.getLiveStreamRecordManager().startRecording(this.appInstance, streamName, recordParams);
		}

		public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
		{
			IStreamRecorder recorder =  this.vhost.getLiveStreamRecordManager().getRecorder(this.appInstance, streamName);
			if (recorder != null)
			{				
				this.vhost.getLiveStreamRecordManager().stopRecording(this.appInstance, streamName);
			}
		}

	}

	@SuppressWarnings("unchecked")
	public void onStreamCreate(IMediaStream stream)
	{
		IMediaStreamActionNotify3 actionNotify = new StreamListener(this.vhost,this.appInstance);
		WMSProperties props = stream.getProperties();
		synchronized (props)
		{
			props.put("streamActionNotifier", actionNotify);
		}
		stream.addClientListener(actionNotify);
	}

	public void onStreamDestroy(IMediaStream stream)
	{
		IMediaStreamActionNotify3 actionNotify = null;
		WMSProperties props = stream.getProperties();
		synchronized (props)
		{
			actionNotify = (IMediaStreamActionNotify3) stream.getProperties().get("streamActionNotifier");
		}
		if (actionNotify != null)
		{
			stream.removeClientListener(actionNotify);
		}
	}
	
	public String setFilename(String streamName,String format)
	{
		DateFormat dateFormat = new SimpleDateFormat(format);
		Date date = new Date();
		return streamName+"."+dateFormat.format(date)+".mp4";
	}

}

To use this module you will need to add the following into your Application via the Wowza Streaming Engine Manager

Name – Recorder
Description – Recorder
Class – guru.thewowza.module.Recorder


Comments are closed.