Custom module to stop stream from post variables

Good afternoon,

I am attempting to custom code a module that will stop a stream. I got the code working that supposedly stops ip streams but I need it to stop rtmp streams so I was trying to merge them together and somehow got some code messed up. If an advanced coder could look at it I would be much obliged.

package com.marestare.wms.module;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.vhost.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
import com.wowza.wms.stream.IMediaStream;
public class CamManager extends HTTProvider2Base {
	public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
		if (!doHTTPAuthentication(vhost, req, resp))
			return;
		
		Map<String, List<String>> params = req.getParameterMap();
		
		String action = "";
		String app = "";
		String streamName = "";
		String mediacasterType = "";
		
		
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.parseBodyForParams(true);
		}
		if (params.containsKey("action"))
			action = params.get("action").get(0);
		
		if (params.containsKey("app"))
			app = params.get("app").get(0);
		
		if (params.containsKey("streamName"))
			streamName = params.get("streamName").get(0);
		
		if (params.containsKey("mediacasterType"))
			mediacasterType = params.get("mediacasterType").get(0);
		
		IApplicationInstance appInstance = vhost.getApplication(app).getAppInstance("_definst_");
		
		String report = action + " " + streamName;
		
		try
		{
		if (action.equalsIgnoreCase("start"))
		{
			appInstance.startMediaCasterStream(streamName, mediacasterType);
		} 
		else if (action.equalsIgnoreCase("stop"))
		{
			appInstance.stopMediaCasterStream(streamName);
			
			stopStream();
		}
		}
		catch(Exception e)
		{
			report = e.getMessage();
		}
		
		
		String retStr = "<html><head><title>MediaCaster HTTProvider</title></head><body>" + report + "</body></html>";
		try {
			OutputStream out = resp.getOutputStream();
			byte[] outBytes = retStr.getBytes();
			out.write(outBytes);
		} catch (Exception e) {
			WMSLoggerFactory.getLogger(null).error(
					"MediaCasterHTTP: " + e.toString());
		}
	}
	public stopStream(IClient client, RequestFunction function,
			AMFDataList params) {
		
		String streamName = getParamString(params, PARAM1);
		
		List<String> published = client.getAppInstance().getPublishStreamNames();
		Iterator iter = published.iterator();
		while (iter.hasNext())
		{
			IMediaStream publishstream = (IMediaStream )iter.next();
			if (publishstream.getName().equalsIgnoreCase(streamName))
			{
				publishstream.getClient().setShutdownClient(true);
			}
		}
	}
}

Hi,

Your onHTTPRequest method is a HTTPProvider method and your stopStream method is a Application Module method.

You need to re-write your stopStream method so that it does not have references to IClient client, RequestFunction function, AMFDataList params.

Roger.

The MediaCaster types are rtp, rtp-record, liverepeater, shoutcast, shoutcast-record

The most common is rtp for restreaming rtsp and udp sources.

The IDE trick when you see that error is hover over it with your cursor (don’t click, just hover) and look for an option to import, which you can select and the IDE will insert an import statement at top.

Richard

Hi,

Something like the following should work.

	public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
		if (!doHTTPAuthentication(vhost, req, resp))
			return;
		
		Map<String, List<String>> params = req.getParameterMap();
		
		String action = "";
		String app = "";
		String streamName = "";
		String mediacasterType = "";
		
		
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.parseBodyForParams(true);
		}
		if (params.containsKey("action"))
			action = params.get("action").get(0);
		
		if (params.containsKey("app"))
			app = params.get("app").get(0);
		
		if (params.containsKey("streamName"))
			streamName = params.get("streamName").get(0);
		
		if (params.containsKey("mediacasterType"))
			mediacasterType = params.get("mediacasterType").get(0);
		
		IApplicationInstance appInstance = vhost.getApplication(app).getAppInstance("_definst_");
		
		String report = action + " " + streamName;
		
		try
		{
		if (action.equalsIgnoreCase("start"))
		{
			appInstance.startMediaCasterStream(streamName, mediacasterType);
		} 
		else if (action.equalsIgnoreCase("stop"))
		{
			if(appInstance.getMediaCasterStreams().getStreamManager().streamExists(streamName))
			{
				appInstance.stopMediaCasterStream(streamName);
			}
			else
			{
				stopStream(appInstance, streamName);
			}
		}
		}
		catch(Exception e)
		{
			report = e.getMessage();
		}
		
		
		String retStr = "<html><head><title>MediaCaster HTTProvider</title></head><body>" + report + "</body></html>";
		try {
			OutputStream out = resp.getOutputStream();
			byte[] outBytes = retStr.getBytes();
			out.write(outBytes);
		} catch (Exception e) {
			WMSLoggerFactory.getLogger(null).error(
					"MediaCasterHTTP: " + e.toString());
		}
	}
	private void stopStream(IApplicationInstance appInstance, String streamName)
	{
		// see if there is a published stream called streamName
		IMediaStream stream = appInstance.getStreams().getStream(streamName);
		if(stream != null)
		{
			// if the stream is a rtmp stream then it will have a client so shut it down
			IClient client = stream.getClient();
			if(client != null)
			{
				client.setShutdownClient(true);
				return;
			}
			
			// else, if it is an rtsp stream, shut down the rtsp session
			RTPStream rtpStream = stream.getRTPStream();
			if(rtpStream != null)
			{
				RTPSession session = rtpStream.getSession();
				if(session != null)
				{
					appInstance.getVHost().getRTPContext().shutdownRTPSession(session);
				}
			}
			
			// could also be an internal stream so it should be shut down by the process that started it and not here.  e.g. transcoder or StreamPublisher.
		}
	}

Roger.

Hey Roger,

Thanks for replying. I am not really sure how to re-write the stopStream without those as they are integral parts of defining a cam stream and stopping it. Could you provide any advise on re-writing it or areas of documentation that may go over in greater detail how?

Thanks.

Hey Roger,

Thanks for answering this so long ago. Unfortunately something came up and I wasn’t able to finish this at the time. I am currently diving back in and redid my learing through the Wowza IDE guide. This is the code I have now based off of your changes. Please let me know if any parts are unnecessary.

package com.marestare.wms.module;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.vhost.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.vhost.*;
public class MyHTTPProvider extends HTTProvider2Base {
	public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
		if (!doHTTPAuthentication(vhost, req, resp))
			return;
		
		Map<String, List<String>> params = req.getParameterMap();
		
		String action = "";
		String app = "";
		String streamName = "";
		String mediacasterType = "";
		
		
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.parseBodyForParams(true);
		}
		if (params.containsKey("action"))
			action = params.get("action").get(0);
		
		if (params.containsKey("app"))
			app = params.get("app").get(0);
		
		if (params.containsKey("streamName"))
			streamName = params.get("streamName").get(0);
		
		if (params.containsKey("mediacasterType"))
			mediacasterType = params.get("mediacasterType").get(0);
		
		IApplicationInstance appInstance = vhost.getApplication(app).getAppInstance("_definst_");
		
		String report = action + " " + streamName;
		
		try
		{
		if (action.equalsIgnoreCase("start"))
		{
			appInstance.startMediaCasterStream(streamName, mediacasterType);
		} 
		else if (action.equalsIgnoreCase("stop"))
		{
			if(appInstance.getMediaCasterStreams().getStreamManager().streamExists(streamName))
			{
				appInstance.stopMediaCasterStream(streamName);
			}
			else
			{
				stopStream(appInstance, streamName);
			}
		}
		}
		catch(Exception e)
		{
			report = e.getMessage();
		}
		
		
		String retStr = "<html><head><title>MediaCaster HTTProvider</title></head><body>" + report + "</body></html>";
		try {
			OutputStream out = resp.getOutputStream();
			byte[] outBytes = retStr.getBytes();
			out.write(outBytes);
		} catch (Exception e) {
			WMSLoggerFactory.getLogger(null).error(
					"MediaCasterHTTP: " + e.toString());
		}
	}
	private void stopStream(IApplicationInstance appInstance, String streamName)
	{
		// see if there is a published stream called streamName
		IMediaStream stream = appInstance.getStreams().getStream(streamName);
		if(stream != null)
		{
			// if the stream is a rtmp stream then it will have a client so shut it down
			IClient client = stream.getClient();
			if(client != null)
			{
				client.setShutdownClient(true);
				return;
			}
			
			// else, if it is an rtsp stream, shut down the rtsp session
			RTPStream rtpStream = stream.getRTPStream();
			if(rtpStream != null)
			{
				RTPSession session = rtpStream.getSession();
				if(session != null)
				{
					appInstance.getVHost().getRTPContext().shutdownRTPSession(session);
				}
			}
			
			// could also be an internal stream so it should be shut down by the process that started it and not here.  e.g. transcoder or StreamPublisher.
		}
	}
}

Based on that I should be able to add the following code to VHost.xml

<HTTPProvider>
    <BaseClass>com.marestare.wms.module.MyHTTPProvider</BaseClass>
    <RequestFilters>*myhttpprovider</RequestFilters>
    <AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>

And then I can use this link to query it, right?

http://[WowzaServerIp]:port(1935)/myhttpprovider

And I would pass through the following variables via POST.

action

app

streamName

mediacasterType

For mediacasterType what should I put?

Is the stopStream portion at the bottom still required?

Valid actions are start and stop correct?

This will disconnect the stream from the server right? I know some streams will auto try to reconnect though.

Thanks again for all of your help!

I forgot to state that two errors are showing up now in the code.

RTPStream cannot be resolved to a type.

RTPSession cannot be resolved to a type.

Thanks rrlanham, that was helpful to fix the errors. Any idea about my other questions?

Hey Roger,

Thanks for answering this so long ago. Unfortunately something came up and I wasn’t able to finish this at the time. I am currently diving back in and redid my learing through the Wowza IDE guide. This is the code I have now based off of your changes. Please let me know if any parts are unnecessary.

package com.marestare.wms.module;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import java.util.List;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.vhost.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.http.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.vhost.*;
public class MyHTTPProvider extends HTTProvider2Base {
	public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) {
		if (!doHTTPAuthentication(vhost, req, resp))
			return;
		
		Map<String, List<String>> params = req.getParameterMap();
		
		String action = "";
		String app = "";
		String streamName = "";
		String mediacasterType = "";
		
		
		if (req.getMethod().equalsIgnoreCase("post")) {
			req.parseBodyForParams(true);
		}
		if (params.containsKey("action"))
			action = params.get("action").get(0);
		
		if (params.containsKey("app"))
			app = params.get("app").get(0);
		
		if (params.containsKey("streamName"))
			streamName = params.get("streamName").get(0);
		
		if (params.containsKey("mediacasterType"))
			mediacasterType = params.get("mediacasterType").get(0);
		
		IApplicationInstance appInstance = vhost.getApplication(app).getAppInstance("_definst_");
		
		String report = action + " " + streamName;
		
		try
		{
		if (action.equalsIgnoreCase("start"))
		{
			appInstance.startMediaCasterStream(streamName, mediacasterType);
		} 
		else if (action.equalsIgnoreCase("stop"))
		{
			if(appInstance.getMediaCasterStreams().getStreamManager().streamExists(streamName))
			{
				appInstance.stopMediaCasterStream(streamName);
			}
			else
			{
				stopStream(appInstance, streamName);
			}
		}
		}
		catch(Exception e)
		{
			report = e.getMessage();
		}
		
		
		String retStr = "<html><head><title>MediaCaster HTTProvider</title></head><body>" + report + "</body></html>";
		try {
			OutputStream out = resp.getOutputStream();
			byte[] outBytes = retStr.getBytes();
			out.write(outBytes);
		} catch (Exception e) {
			WMSLoggerFactory.getLogger(null).error(
					"MediaCasterHTTP: " + e.toString());
		}
	}
	private void stopStream(IApplicationInstance appInstance, String streamName)
	{
		// see if there is a published stream called streamName
		IMediaStream stream = appInstance.getStreams().getStream(streamName);
		if(stream != null)
		{
			// if the stream is a rtmp stream then it will have a client so shut it down
			IClient client = stream.getClient();
			if(client != null)
			{
				client.setShutdownClient(true);
				return;
			}
			
			// else, if it is an rtsp stream, shut down the rtsp session
			RTPStream rtpStream = stream.getRTPStream();
			if(rtpStream != null)
			{
				RTPSession session = rtpStream.getSession();
				if(session != null)
				{
					appInstance.getVHost().getRTPContext().shutdownRTPSession(session);
				}
			}
			
			// could also be an internal stream so it should be shut down by the process that started it and not here.  e.g. transcoder or StreamPublisher.
		}
	}
}

Based on that I should be able to add the following code to VHost.xml

<HTTPProvider>
    <BaseClass>com.marestare.wms.module.MyHTTPProvider</BaseClass>
    <RequestFilters>*myhttpprovider</RequestFilters>
    <AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>

And then I can use this link to query it, right?

http://[WowzaServerIp]:port(1935)/myhttpprovider

And I would pass through the following variables via POST.

action

app

streamName

mediacasterType

For mediacasterType what should I put?

Is the stopStream portion at the bottom still required?

Valid actions are start and stop correct?

This will disconnect the stream from the server right? I know some streams will auto try to reconnect though.

Thanks again for all of your help!

Nevermind, I was correct.

http://localhost:1935/myhttpprovider?action=stop&app=mymodules&streamName=cam1&mediacasterType=rtsp

is an example usage of it.

Is there anyway to have Wowza detect the mediacasterType rather than us specify it?

Also is there a way for Wowza to tell if the stream is active so I don’t try to turn off a stream that isn’t connected?

Thanks!