MediaCasterStreamManager controls start/stop/record of RTP, MPEG-TS and SHOUTcast

Here the complete code (sorry, I needed to remove some parts of our business logic - it’s a project at our university)

S2.java:

package de.mpgz.camm;
import com.wowza.wms.*;
public class S2 extends ModuleBase {
	
	private IApplicationInstance appInstance = null;
	public void onAppStart(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		getLogger().info("onAppStart: " + fullname);
		
		// RESTRICT TO DEFAULT INSTANCE
		if(!appInstance.getName().equalsIgnoreCase(ApplicationInstance.DEFAULT_APPINSTANCE_NAME))
		{
			appInstance.shutdown(false, false);
		} else {
			// Save Instance
			this.appInstance = appInstance;
		}
	}
    
        public void startMediaCasterStream(String group, String streamName, String mediaCasterType, String name, String size, int bitrate)
	{
		try
		{
			while(true)
			{
				getLogger().info("ModuleMediaCasterStreamManager.startMediaCasterStream["+mediaCasterType+"]: "+streamName);
				
				MediaCasterStreamMap mediaCasterMap = this.appInstance.getMediaCasterStreams();
				IVHost vhost = this.appInstance.getVHost();
				MediaCasterStreamManager mediaCasterStreamManager = mediaCasterMap.getStreamManager();
				
				MediaCasterList mediaCasterList = vhost.getMediaCasterList();
				MediaCasterItem mediaCasterDef = mediaCasterList.getMediaCasterDef(mediaCasterType);
				
				if (mediaCasterDef == null)
				{
					getLogger().warn("ModuleMediaCasterStreamManager.startMediaCasterStream: MediaCaster type not found: "+mediaCasterType);
					break;
				}
				
				MediaCasterStreamItem mediaCasterStream = mediaCasterMap.getMediaCaster(streamName);
				if (mediaCasterStream != null)
				{	getLogger().warn("ModuleMediaCasterStreamManager.startMediaCasterStream: MediaCaster already exists[mediacaster]: "+streamName);
					break;
				}
				
				boolean success = mediaCasterStreamManager.startStream(streamName, mediaCasterType);
				if (success)
				{		getLogger().info("ModuleMediaCasterStreamManager.startMediaCasterStream: Stream started: "+streamName);
				}
				else
				{
					getLogger().info("ModuleMediaCasterStreamManager.startMediaCasterStream: Stream failed: "+streamName);
				}
				break;
			}
		}
		catch (Exception e)
		{
			getLogger().error("ModuleMediaCasterStreamManager.startMediaCasterStream: "+e.toString());
		}
	}
	
	// NEEDED INFO: streamName (glf.sdp)
	public void stopMediaCasterStream(String streamName)
	{
		try
		{
			while(true)
			{
				getLogger().info("ModuleMediaCasterStreamManager.stopMediaCasterStream: "+streamName);
						
				MediaCasterStreamMap mediaCasterMap = this.appInstance.getMediaCasterStreams();
				MediaCasterStreamManager mediaCasterStreamManager = mediaCasterMap.getStreamManager();
				boolean success = mediaCasterStreamManager.stopStream(streamName);
				if (success)
				{
					getLogger().info("ModuleStreamStarter.stopMediaCasterStream: Stream stopped: "+streamName);
				}
				else
				{
					getLogger().warn("ModuleMediaCasterStreamManager.stopMediaCasterStream: Stream not found: "+streamName);
				}
				break;
			}
		}
		catch (Exception e)
		{
			getLogger().error("ModuleMediaCasterStreamManager.stopMediaCasterStream: "+e.toString());
		}
	}
}

CaMMServerListener.java:

package de.mpgz.camm;
import com.wowza.wms.*;
import edu.emory.mathcs.backport.java.util.concurrent.locks.WMSReadWriteLock;
public class CaMMServerListener implements IServerNotify {
	private CaMM_S2 Main;
	public void onServerCreate(IServer server) {
		// TODO Auto-generated method stub
		this.Main = new CaMM_S2(server);
	}
	
	private void loadAndLockAppInstance(IVHost vhost, String appName, String appInstanceName)
	{
		IApplication localApplication = null;
		IApplicationInstance localAppInstance = null;
		
		WMSReadWriteLock appLock = vhost.getApplicationLock();
		appLock.writeLock().lock();
		try
		{
	    	localApplication = vhost.getApplication(appName);
    		if (localApplication != null)
    		{
	    		localAppInstance = localApplication.getAppInstance(appInstanceName);
	    		localAppInstance.setApplicationTimeout(0);
	    		if(appName.equalsIgnoreCase("live"))
	    		{
	    			this.Main.setLiveApplication((S2)localAppInstance.getModuleInstance("S2"));
	    		}
    		} else {
    			WMSLoggerFactory.getLogger(null).warn("Application folder ([install-location]/applications/"+appName+") is missing");
    		}
		}
		catch (Exception e)
		{
			WMSLoggerFactory.getLogger(null).error("CaMMServerListener.loadAndLockAppInstance: "+ appName + " - " + e.toString());
		}
		finally
		{
			appLock.writeLock().unlock();
		}
	}
	public void onServerInit(IServer server) {
		IVHost vhost = VHostSingleton.getInstance(VHost.VHOST_DEFAULT);
		loadAndLockAppInstance(vhost, "live", ApplicationInstance.DEFAULT_APPINSTANCE_NAME);
		
		this.Main.startup();
	}
	public void onServerShutdownStart(IServer server) {
		this.Main.shutdown();
	}
	public void onServerShutdownComplete(IServer server) {
		// TODO Auto-generated method stub
	}
}

conf/live/Application.xml:

                        <Module>
				<Name>S2</Name>
				<Description>CaMM S2 Plugin</Description>
				<Class>de.mpgz.camm.S2</Class>
			</Module>

conf/Server.xml

                        <ServerListener>
                            <BaseClass>de.mpgz.camm.CaMMServerListener</BaseClass>
                        </ServerListener>

(You can use auto-generated imports to keep them small.)

And instead of “this.Main = new CaMM_S2(server);” in the CaMMServerListener you can use your own class to check if the .sdp file is existing or wait for network connections (like we do).

Hi Charlie,

I am testing the MediaCasterStreamManger. I try to record an stream delivered by Darwin Streaming Server 6. My problem is that Wowza server records only 2 minutes. The recording works perfect, but the Wowza server receives/requests no more data from the Darwin Streaming server after the 2 minutes. (Connecton to dss closes after 2 minutes)

(another setup together with same encoder, darwin server and the rtplive application works perfect)

regards

schaba

i am using your

/client/mediacasterstreammanager.html

into the field Stream in enter for example my Darwin Streamin URL:

rtsp://c14005-l.m.core.cdn.streamfarm.net/14005dgcom/live/3745ebs/ebs_stream01.sdp

its an public stream, delivered by our Dariwin6 Streaming Server.

When I press the Start Stream button the stream will be recorded for 2 minutes.

When I watch the traffic on the network interfaces I can see udp packets between darwin and the wowza server (Port 6970 / 699x). But after 2 minutes no more udp pakets can be seen on the network interface.

Or is it possible to record the stream using a relayed stream from darwin to wowza, because the rtplive application, which I already use, works perfect.

Wowza URL:

rtmp://c14005-l.z.core.cdn.streamfarm.net/rtplive/14005dgcom/live/3745ebs/ebs_stream01.sdp

(i have installed WowzaMediaServerPro1.6.0-patch22)

Is there a way to record the stream I already push with darwin to the woza server?

rtmp://wowzaserveradress/rtplive/streamname.sdp

Hi!

Is there any way to record MediaCasterStreams if there is no even application instance running?

I mean sheduled recording: separate thread will determine that it is time to start recording - it will launch Application Instance, then start mediaCasterStream

Thank you!

Uh… finally found IVHost.startApplicationInstance… will try it.

Hi Charlie,

Currently I use the MediaCaster Client, for start/stop the Live Streaming… is possible make the same but directly from ServerSide, the idea is don’t use FlashClient…

If this possible, you have any example?

Thanks

Alejandro

Thanks, currently I use the 1.7 version with VLC and SDP file, and don’t need MediaCaster for start from the cliente, only call to the SDP File inside the Content directory… really me ask is for I test the same with 2.0 Preview version and don’t work without MediaCasterClient interface.

Here my need, and I’m a SysAdmin and don’t programing in Java, me home solution now are, use VNC Server start the Browser, open Flash Interface and start the Stream, this Work but is very very bad idea… thanks again…

Alejandro

Matthias,

Yes, please… an example is appreciated… thanks…

Thanks a lot… only one more question, inside the Wowza, you have one example how setting this? for example in Application.xml

Thanks again… I understand the code perfectly…

Can it be use with Wowza2 too?

Thanks in advance.

Ok,

I’ve install the module but I get “Missing function: startMediaCasterStream” in Wowza’s logs :frowning:

I’ve made a mistake when I’ve installed the module.

It’s now work correctly.

Hi,

I would like to add the method getMediaCasterType to MediaCasterStreamManager module because I want to get by flash if a stream is in rtp type or rtp-record type.

I’ve take a look at the source code of MediaCasterManager but I don’t know how to implement the getMediaCasterType method.

Can you help me?

I have installed the StreamNameAlias module and put one alias in StreamNameAlias.txt:

mystream=rtmp://xxx.xx.xx.xx/live/definst/livestream

Then I have tried two scenarios with MediaCasterStreamManager web client.

First scenario:

  1. Start stream rtmp://xx.xx.xx.xx/live/definst/livestream with type ‘liverepeater’ via MediaCasterStreamManager web client.

  2. Connect to ‘mystream’ (described above in StreamNameAlias.txt) and see video in flash video player.

  3. Stop stream.

  4. Video has stopped in the player.

That’s ok.

Second scenario:

  1. Connect to ‘mystream’ (described above in StreamNameAlias.txt) and see video in flash video player.

  2. Try to start stream with the same name via MediaCasterStreamManager web client and get "MediaCaster already exists[mediacaster]: rtmp://xxx.xx.xx.xx/live/definst/livestream"

  3. Then I try to stop the stream and get "Stream not found: rtmp://xxx.xx.xx.xx/live/definst/livestream"

In the second scenario stream is not listed in Active: field. So, why I can’t stop the stream which has been automatically created when the player was connected?

This won’t work:

mystream=rtmp://xxx.xx.xx.xx/live/definst/livestream

Because you are using a rtmp url for stream name.

It works! The application type is ‘liverepeater’ if it matters. I use two applications: one is ‘live’ and another is ‘liverepeater’. Aliases concern a ‘liverepeater’ application.