Wowza Community

Custom Move Module

I have a custom module and I need to move a file once its recorded to an S3 mounted drive. I’m on an EC2 AMI installation of 2.1.2. When I try to move the file, I test to make sure it exists and then attempt to move the file using “renameTo”

Debugging says the file DOES exist but that it “failed to move”. This happens consistently I have attempted to use the built-in filemove module but the versioning screws up the file name because it ends in numbers that are programmatically created and I can’t turn off versioning because I can’t seem to change the filename from the streamName.

Has anybody successfully moved a file to an S3 mount after a recording has been completed?

If it helps the source for the built in file mover is here:

import java.io.*;
import java.util.*;
import com.wowza.util.*;
import com.wowza.wms.module.*;
import com.wowza.wms.application.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.vhost.*;
public class ModuleMediaWriterFileMover extends ModuleBase implements IMediaWriterActionNotify
{
	String fileMoverDestinationPath = null;
	String fileMoverFileExtension = null;
	boolean fileMoverVersionFile = true;
	boolean fileMoverDeleteOriginal = false;
	
	public void onAppStart(IApplicationInstance appInstance)
	{
		appInstance.addMediaWriterListener(this);
		getLogger().info("ModuleMediaWriterFileMover.onAppStart: "+appInstance.getContextStr());
		
		WMSProperties props = appInstance.getProperties();
		
		fileMoverDestinationPath = props.getPropertyStr("fileMoverDestinationPath", fileMoverDestinationPath);
		fileMoverFileExtension = props.getPropertyStr("fileMoverFileExtension", fileMoverFileExtension);
		fileMoverVersionFile = props.getPropertyBoolean("fileMoverVersionFile", fileMoverVersionFile);
		fileMoverDeleteOriginal = props.getPropertyBoolean("fileMoverDeleteOriginal", fileMoverDeleteOriginal);
	}
	
	private String getExtension(IMediaStream stream, String ext)
	{
		if (ext == null)
		{
			String mediaReaderType = stream.getExt().toLowerCase();
			MediaReaderItem mediaReaderItem = stream.getStreams().getVHost().getMediaReaders().getMediaReaderDef(mediaReaderType);
			return mediaReaderItem.getFileExtension();
		}
		
		return ext;
	}
	public void onWriteComplete(IMediaStream stream, File file)
	{
		if (fileMoverDestinationPath != null)
		{
			String streamName = FileUtils.toValidFilename(stream.getName());
			String streamExt = getExtension(stream, fileMoverFileExtension);
			
			Map<String, String> envMap = new HashMap<String, String>();
			
			IApplicationInstance appInstance = stream.getStreams().getAppInstance();
			IVHost vhost = appInstance.getVHost();
			
			envMap.put("com.wowza.wms.context.VHost", vhost.getName());
			envMap.put("com.wowza.wms.context.VHostConfigHome", vhost.getHomePath());
			envMap.put("com.wowza.wms.context.Application", appInstance.getApplication().getName());
			envMap.put("com.wowza.wms.context.ApplicationInstance", appInstance.getName());
			envMap.put("com.wowza.wms.context.StreamName", streamName);
			
			String destinationPath =  SystemUtils.expandEnvironmentVariables(fileMoverDestinationPath, envMap);
			
			if (fileMoverDestinationPath.indexOf("com.wowza.wms.context.StreamName") < 0)
				destinationPath += "/"+streamName+"."+streamExt;
			
			File dstFile = new File(destinationPath);
			
			getLogger().info("ModuleMediaWriterFileMover.onWriteComplete: from: "+file+" to:"+dstFile);
	
			try
			{
				dstFile.getParentFile().mkdirs();
			}
			catch(Exception e)
			{
				getLogger().warn("ModuleMediaWriterFileMover.onWriteComplete[mkdir]: ["+dstFile+"]: "+e.toString());
			}
			
			try
			{
				if (dstFile.exists())
				{
					if (fileMoverVersionFile)
						FileUtils.versionFile(dstFile);
					else
						dstFile.delete();
				}
			}
			catch(Exception e)
			{
				getLogger().warn("ModuleMediaWriterFileMover.onWriteComplete[version]: ["+dstFile+"]: "+e.toString());
			}
			
			try
			{
				FileUtils.copyFile2(file, dstFile);
			}
			catch(Exception e)
			{
				getLogger().warn("ModuleMediaWriterFileMover.onWriteComplete[version]: ["+dstFile+"]: "+e.toString());
			}
	
			try
			{
				if (fileMoverDeleteOriginal && dstFile.exists())
				{
					file.delete();
				}
			}
			catch(Exception e)
			{
				getLogger().warn("ModuleMediaWriterFileMover.onWriteComplete[delOrig]: ["+dstFile+"]: "+e.toString());
			}
		}
	}
	
	public void onFLVAddMetadata(IMediaStream stream, Map<String, Object> extraMetadata)
	{
	}
}

Charlie

Awesome thank you sir, this is what I needed, I did get it to work, if it helps anybody in the future the renameTo() function will not work when moving a file to an S3 mount, I assume this is because its a different filesystem underneath it all.

FileUtils.copyFile2(file, dstfile);

Is the most important bit, this will move any file to dstfile,

Thanks again!