# Stream class stream controller

**URL:** <https://community.wowza.com/t/stream-class-stream-controller/244>\
**Category:** Wowza Developer Dojo\
**Tags:** wowza-streaming-server-java-api\
**Created:** [December 17, 2009, 6:23pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244 "2009-12-17T18:23:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/community.wowza.com/system/32/447_2.png) [@system](https://community.wowza.com/u/system)\
**Post date:** [December 17, 2009, 6:23pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/1 "2009-12-17T18:23:32Z")

</div>

[https://www.wowza.com/docs/how-to-control-stream-class-streams-dynamically-modulestreamcontrol](https://www.wowza.com/docs/how-to-control-stream-class-streams-dynamically-modulestreamcontrol)

---

<div class="post-metadata">

**Author:** ![Sebastien\_Faure](https://avatars.discourse-cdn.com/v4/letter/s/9f8e36/32.png) [@Sebastien\_Faure](https://community.wowza.com/u/Sebastien_Faure)\
**Post date:** [June 12, 2010, 7:13pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/2 "2010-06-12T19:13:50Z")

</div>

> You can use this with (or without) the [server listener stream scheduler](https://www.wowza.com/docs/how-to-schedule-streaming-with-wowza-streaming-engine-streampublisher). If this application module is used in the same application that the scheduler populates with Streams and Playlists, you can use this application can be used to control those Streams and Playlists.

I can’t make this work. Server listener is working but _Stream_ entity seems to be different between listener and controller.

I’m using StreamControl Flex app to add 1 playlist to same _Stream_ mentionned in listener.

Then add some streams to the new playlist. When I hit _open playlist on stream_, it does not work. WMS logs only show this single line :

> 2010-06-12 20:02:25 CEST comment server ERROR 500 - - - - - 88.224 - - - - - - - - - - - - - - - – - - - - - - - -

I"ve added a try/catch block in _openPlaylistOnStream_ function but actually exception _getMessage()_ returns this empty string.

What am I missing ?

Thank you.

---

<div class="post-metadata">

**Author:** ![sam\_ola](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sam\_ola](https://community.wowza.com/u/sam_ola)\
**Post date:** [December 21, 2009, 12:23pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/3 "2009-12-21T12:23:26Z")

</div>

> Module to control Stream class streams and playlists. Use this module to dynamically create, setup and start live Stream class streams from static and live sources, and add sources to running Streams.
> 
> You can use this module along with the [Stream class scheduler](https://www.wowza.com/docs/how-to-schedule-streaming-with-wowza-streaming-engine-streampublisher). The Streams and Playlists that you set up in the schedule can be modified and controlled using this application.
> 
> ```auto
> package com.wowza.wms.plugin.collection.module;
> 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.publish.*;
> public class ModuleStreamControl extends ModuleBase {
> 	
> public void openPlaylistOnStream(IClient client, RequestFunction function,
> AMFDataList params) {
> 		
> String streamName = getParamString(params, PARAM1);
> 		
> String playlistName = getParamString(params, PARAM2);
> 		
> Stream stream = (Stream)client.getAppInstance().getProperties().getProperty(streamName);
> 		
> Playlist playlist = (Playlist)client.getAppInstance().getProperties().getProperty(playlistName);
> 		
> playlist.open(stream);
> 	
> }
> public void addItemToPlaylist(IClient client, RequestFunction function,
> AMFDataList params) {
> AMFDataObj obj = getParamObj(params, PARAM1);
> 		
> Playlist playlist = (Playlist)client.getAppInstance().getProperties().getProperty(obj.getString("playListName"));
> 		
> playlist.addItem(obj.getString("itemName"), obj.getInt("itemStart"), obj.getInt("itemDuration"));	
> }
> 	
> 	
> public void playNextPlaylistItem(IClient client, RequestFunction function,
> AMFDataList params) {
> String streamName = getParamString(params, PARAM1);
> 		
> Stream stream = (Stream)client.getAppInstance().getProperties().getProperty(streamName);
> 		
> stream.next();
> 		
> }
> 	
> public void addNewStream(IClient client, RequestFunction function,
> AMFDataList params) {
> 		
> String streamName = getParamString(params, PARAM1);
> 		
> Stream stream = Stream.createInstance(client.getAppInstance(), streamName);
> 		
> client.getAppInstance().getProperties().put(streamName, stream);
> 	
> }
> 	
> public void addNewPlaylist(IClient client, RequestFunction function,
> AMFDataList params) {
> 		
> String playListName = getParamString(params, PARAM1);
> 		
> Playlist playlist = new Playlist(playListName);
> 		
> playlist.setRepeat(true);
> 		
> client.getAppInstance().getProperties().put(playListName, playlist);
> 		
> }
> public void stopStream(IClient client, RequestFunction function,
> AMFDataList params) {
> 		
> String streamName = getParamString(params, PARAM1);
> 		
> Stream stream = Stream.createInstance(client.getAppInstance(), streamName);
> 		
> stream.removeFromPlaylist(streamName);
> 		
> }
> }
> 
> ```
> 
> Actionscript 3
> 
> ```auto
> public function addNewStream():void
> {
> nc.call("addNewStream",null,streamName.text);			
> }
> public function addNewPlaylist():void
> {
> nc.call("addNewPlaylist",null,playlist.text);
> }
> public function stopStream():void
> {
> nc.call("stopStream",null,streamName.text);			
> }
> public function openPlaylistOnStream():void
> {
> nc.call("openPlaylistOnStream",null,streamName.text,playlist.text);
> }
> public function nextItem():void
> {
> nc.call("playNextPlaylistItem",null,streamName.text);
> }
> public function addItemToPlaylist():void
> {
> var obj:Object = new Object();
> obj.playListName = playlist.text;
> obj.itemName = itemName.text;
> obj.itemStart = itemStart.text;
> obj.itemDuration = itemDuration.text;
> nc.call("addItemToPlaylist",null,obj);
> }
> 
> ```
> 
> You can use this with (or without) the [server listener stream scheduler](https://www.wowza.com/docs/how-to-schedule-streaming-with-wowza-streaming-engine-streampublisher). If this application module is used in the same application that the scheduler populates with Streams and Playlists, you can use this application can be used to control those Streams and Playlists. The association between Playlists and Streams in the scheduler is irrelevant in the application module – you can start any Playlist on any Stream.
> 
> This is a [modified version of Wowza Live Player](https://www.wowza.com/downloads/forums/collection/client/StreamClassControl.zip) with these features.
> 
> This client is functional but missing everything in the way of validation, feedback and state (of existing streams on the server). To operate, use the buttons and textinput below the the video display
> 
> Enter a Stream (I filled in “StreamNew”), then click “add stream”
> 
> Enter a Playlist (I filled in “playlistNew”), then click “add playlist”
> 
> Add at least one item to the playlist (I filled in “mp4:Extremists.m4v” with start of 0 and length -1), click “add Item to playlist”
> 
> Then click “open playlist on stream”
> 
> Then in above, enter the streamname, “StreamNew” and click “Play”
> 
> To add a new item, enter a new video name with start and length, and click “add item to playlist”, then click open “open playlist on stream again”. If the video is currently playing, the new item will start playing after the current one or when it cycles through to the end. You can also click “play next item”
> 
> The Stream Control application module and client provide no feedback or listing of active streams. If you are using with the scheduler you have to know what stream name and playlist name to use.
> 
> To add a live stream to a playlist enter “-2” for Video start. You can mix live streams and static content. You can use MediaCaster streams, but be sure to start them using /conf/StartupStreams.xml or in a application module or server listener using MediaCasterStreamManager.
> 
> I set the buffer to 0 for the playback in the provided client app for the moment. Buffer time in the client is a big factor in what the user sees when streams switch.

Does this needs to be compiled or is it already built into the release version of WMS 2.0

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 12:29pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/4 "2009-12-21T12:29:26Z")

</div>

It needs to be compiled. But this module has been added to this collection:

[http://community.wowza.com/t/-/237](http://community.wowza.com/t/-/237)

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 12:53pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/5 "2009-12-21T12:53:44Z")

</div>

Sorry, I need to update the README.html to include this module.

Add this Module to the Modules list in the /conf/live/Application.xml

```auto
<Module>
<Name>streamcontroller</Name>
<Description>ModuleStreamControl</Description>
<Class>com.wowza.wms.plugin.collection.module.ModuleStreamControl</Class>
</Module>

```

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 1:18pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/6 "2009-12-21T13:18:07Z")

</div>

No, you have to add that Module. Add it below the ModuleMediaCasterStreamManager Module.

But make sure it is above

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 1:40pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/7 "2009-12-21T13:40:24Z")

</div>

No, it is not right.

> But make sure it is above

It has to be inside the Modules group. You added it below , so it is outside.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 2:10pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/8 "2009-12-21T14:10:43Z")

</div>

The Modules section looks right, but the Properties section is not. Everything has to be well-formed in XML. Any starting tag has to have a close , and in the right order.

Not correct:

```auto
<Properties>
</Property>
<Property>
<Name>mediaCasterStreamManagerPassword</Name>
<Value>!()$£&^%"!901</Value>
</Properties>

```

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [December 21, 2009, 3:05pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/9 "2009-12-21T15:05:59Z")

</div>

Great! Glad it’s working. Enjoy, it’s a fun system, tho missing much.

If you want to include a live stream, set the start value to “-2”.

If the live stream is MediaCaster stream, like IP cam, you have to start it first. Use the /conf/StartupStreams.xml

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [January 6, 2010, 1:29pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/10 "2010-01-06T13:29:35Z")

</div>

The playlist.open(stream) method doesn’t play a stream, it just sets it, so it wouldn’t be the place to see if the stream existed.

When a Stream class stream plays a Playlist, and it cycles into an Playlist item that does not exist, there is an error:

> WARN server comment - Extremistsx.flv open: java.io.FileNotFoundException: C:\Program Files (x86)\Wowza Media Systems\Wowza Media Server 2\content\Extremistsx.flv (The system cannot find the file specified)

You should be able to handle that error in the IStreamActionNotify interface, onPlaylistItemStart method. Here is a the module modified to implement IStreamActionNotify interface for each Stream it creates. Explore the Stream and PlaylistItem parameters of the onPlaylistItemStart method:

```auto
package com.wowza.wms.plugin.collection.serverlistener;
 
import com.wowza.wms.application.*;
import com.wowza.wms.server.*;
import com.wowza.wms.vhost.*;
import com.wowza.wms.stream.publish.*;
import com.wowza.wms.logging.*;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ServerListenerStreamPublisher implements IServerNotify {
		
	WMSLogger log = WMSLoggerFactory.getLogger(null);
	
	public void onServerInit(IServer server)
	{
		log.info("ServerINIT");
		IVHost vhost = VHostSingleton.getInstance(server.getProperties().getPropertyStr("PublishToVHost", VHost.VHOST_DEFAULT));
		IApplication app = vhost.getApplication(server.getProperties().getPropertyStr("PublishToApplication", "live"));
		String storageDir = app.getAppInstance("_definst_").getStreamStorageDir();

		try
		{
			String smilLoc = storageDir + "/streamschedule.smil";
			File playlistxml = new File(smilLoc);
			
			if (playlistxml.exists() == false){
				log.info("Could not find playlist file: " + smilLoc);
				return;
			}
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(smilLoc);
			document.getDocumentElement().normalize();
			
			NodeList streams = document.getElementsByTagName("stream");
			for (int i = 0; i < streams.getLength(); i++)
			{
				Node streamItem = streams.item(i);
				if (streamItem.getNodeType() == Node.ELEMENT_NODE)
				{ 
					Element e = (Element) streamItem;
					String streamName = e.getAttribute("name");
					Stream stream = Stream.createInstance(vhost, app.getName(), streamName);
					app.getAppInstance("_definst_").getProperties().put(streamName, stream);
				}
			}
			
			NodeList playList = document.getElementsByTagName("playlist");
			if (playList.getLength() == 0){
				log.info("No playlists defined in smil file");
				return;
			}
			for (int i = 0; i < playList.getLength(); i++)
			{
				Node scheduledPlayList = playList.item(i);
				
				if (scheduledPlayList.getNodeType() == Node.ELEMENT_NODE)
				{
					Element e = (Element) scheduledPlayList;	
					
					NodeList videos = e.getElementsByTagName("video");
					if (videos.getLength() == 0){
				 		log.info("No videos defined in stream");
						return;
					}
					
					String streamName = e.getAttribute("playOnStream");
					if (streamName.length()==0)
						continue;
					
					Playlist playlist = new Playlist(streamName);
					playlist.setRepeat((e.getAttribute("repeat")=="false")?false:true);
					
					app.getAppInstance("_definst_").getProperties().put(e.getAttribute("name"), playlist);
					
					for (int j = 0; j < videos.getLength(); j++)
					{
						Node video = videos.item(j);				
						if (video.getNodeType() == Node.ELEMENT_NODE)
						{
							Element e2 = (Element) video;
							String src = e2.getAttribute("src");
							Integer start = Integer.parseInt(e2.getAttribute("start"));
							Integer length = Integer.parseInt(e2.getAttribute("length"));
							playlist.addItem(src, start, length);
						}
					}
					String scheduled = e.getAttribute("scheduled");
					SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					Date startTime = parser.parse(scheduled);
					Stream stream = (Stream)app.getAppInstance("_definst_").getProperties().get(streamName);
					ScheduledItem item = new ScheduledItem(startTime, playlist, stream);
					item.start();
					
					IStreamActionNotify actionNotify = new StreamListener(app.getAppInstance("_definst_"));
					stream.addListener(actionNotify);
					
					log.info("Scheduled: " + stream.getName() + " for: " + scheduled);
				}	
			}
		}
		catch(Exception ex)
		{
		}
	}
	
private class ScheduledItem {
		public Timer mTimer;
		public TimerTask mTask;
		public Date mStart;
		public Playlist mPL;
		public Stream mStream;
		public ScheduledItem(Date d, Playlist pl, Stream s){
			mStart = d;
			mPL = pl;
			mStream = s;
			mTask = new TimerTask(){
				public void run() {
					mPL.open(mStream);
					log.info("Scheduled stream is now live: " + mStream.getName());
				}
			};
			mTimer = new Timer();		
		}
		
		public void start(){
			
			if (mTimer==null)
				mTimer = new Timer();
			mTimer.schedule(mTask, mStart);
			log.info("scheduled playlist: "+mPL.getName()+
						" on stream: "+mStream.getName()+
						" for:"+mStart.toString());
		}
		
		public void stop(){
			if (mTimer != null){
				mTimer.cancel();
				mTimer=null;
				log.info("cancelled playlist: "+mPL.getName()+
						" on stream: "+mStream.getName()+
						" for:"+mStart.toString());
			}
		}
	}
	public void onServerCreate(IServer server)
	{
	}
	public void onServerShutdownComplete(IServer server)
	{
	}

	public void onServerShutdownStart(IServer server)
	{
	}	

	class StreamListener implements IStreamActionNotify
		{
			StreamListener(IApplicationInstance appInstance)
			{
			}
			public void onPlaylistItemStop(Stream stream, PlaylistItem item)
			{
				
			}
			public void onPlaylistItemStart(Stream stream, PlaylistItem item) 
			{
				
			}
		}
}

```

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [February 5, 2010, 4:22pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/11 "2010-02-05T16:22:12Z")

</div>

The smil file from the scheduler example is read once, not involved in anything after that.

openPlaylistOnStream() is a function in that controller example. Which is separate application, no smil file involved.

[https://www.wowza.com/forums/showthread.php?p=32659](https://www.wowza.com/forums/showthread.php?p=32659)

Server-side, openPlaylistOnStream is just doing this:

```auto
playlist.open(stream);

```

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [February 5, 2010, 4:30pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/12 "2010-02-05T16:30:26Z")

</div>

Also, to your 1st question: yes, you can remove a PlaylistItem like this:

```auto
Boolean success = stream.removeFromPlaylist("Extremists.flv");

```

Note that this will not work if it is playing.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [February 5, 2010, 4:33pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/13 "2010-02-05T16:33:22Z")

</div>

Right, no smil in the controller, it’s acting on running objects. The source code is at the top of this thread. It’s short, simple, not much to it really.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [February 5, 2010, 5:03pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/14 "2010-02-05T17:03:41Z")

</div>

It is getting repetitive, I think it’s all in that post already. Try it out, there’s a little Flash front end.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [June 11, 2010, 3:55pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/15 "2010-06-11T15:55:27Z")

</div>

It’s a server-side switch that is not dependent on the client.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [June 12, 2010, 11:53am UTC](https://community.wowza.com/t/stream-class-stream-controller/244/16 "2010-06-12T11:53:05Z")

</div>

New info: The iphone/ipad is sensitive to encoding changes and will freeze. So server-side playlists may not work in those situations.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [June 16, 2010, 7:15pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/17 "2010-06-16T19:15:44Z")

</div>

It’s a matter of knowing that there is a stream name, e.g., “Stream1” created by the scheduler. That controller will create a Stream from scratch too.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [June 22, 2010, 3:41am UTC](https://community.wowza.com/t/stream-class-stream-controller/244/18 "2010-06-22T03:41:04Z")

</div>

You can use HTTProviders. See this example:

[http://community.wowza.com/t/-/245](http://community.wowza.com/t/-/245)

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [July 1, 2010, 8:21pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/19 "2010-07-01T20:21:01Z")

</div>

Not familiar with that player, but usually need Flash CS or Flex/Flash Builder to compile.

Richard

---

<div class="post-metadata">

**Author:** ![Richard\_Lanham](https://avatars.discourse-cdn.com/v4/letter/r/c68b51/32.png) [@Richard\_Lanham](https://community.wowza.com/u/Richard_Lanham)\
**Post date:** [July 8, 2010, 11:22pm UTC](https://community.wowza.com/t/stream-class-stream-controller/244/20 "2010-07-08T23:22:41Z")

</div>

Yes it is.

Richard

[Next page](https://community.wowza.com/t/stream-class-stream-controller/244.md?page=2)
