• How to monitor live streams using IMediaStreamActionNotify2

    This Module monitors live streams. Stream stats are sent to Flash clients.

    Code:
    package com.wowza.wms.plugin.collection.module;
    
    import java.util.*;
    import com.wowza.wms.application.*; 
    import com.wowza.wms.amf.*;
    import com.wowza.wms.application.WMSProperties;
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.IMediaStream;
    import com.wowza.wms.stream.IMediaStreamActionNotify2;
    import com.wowza.wms.stream.MediaStreamMap;
    import java.util.Timer;
    import java.util.List;
    
    public class ModuleStreamWatchDog extends ModuleBase {
    	
    	public void onStreamCreate(IMediaStream stream) {
    		getLogger().info("onStreamCreate by: " + stream.getClientId());
    		IMediaStreamActionNotify2 actionNotify  = new StreamListener();
    		
    		WMSProperties props = stream.getProperties();
    		synchronized(props)
    		{
    			props.put("streamActionNotifier", actionNotify);
    		}
    		stream.addClientListener(actionNotify);
    	}
    	public void onStreamDestroy(IMediaStream stream) {
    		getLogger().info("onStreamDestroy by: " + stream.getClientId());
    		
    		IMediaStreamActionNotify2 actionNotify = null;
    		WMSProperties props = stream.getProperties();
    		synchronized(props)
    		{
    			actionNotify = (IMediaStreamActionNotify2)stream.getProperties().get("streamActionNotifier");
    		}
    		if (actionNotify != null)
    		{
    			stream.removeClientListener(actionNotify);
    			getLogger().info("removeClientListener: "+stream.getSrc());
    		}
    	}
    	
    	class StreamListener  implements IMediaStreamActionNotify2 
    	{
    		public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset) 
    		{
    			streamName = stream.getName();
    			getLogger().info("Stream Name: " + streamName);
    		}
    		
    		public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) 
    		{
    			getLogger().info("onMetaData By: " + stream.getClientId());
    		}
    		
    		public void onPauseRaw(IMediaStream stream, boolean isPause, double location) 
    		{
    			getLogger().info("onPauseRaw By: " + stream.getClientId());
    		}
    
    		public void onSeek(IMediaStream stream, double location)
    		{
    			getLogger().info("onSeek");
    		}
    		
    		public void onStop(IMediaStream stream)
    		{
    			getLogger().info("onStop By: " + stream.getClientId());
    		}
    		
    		public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
    		{
    			getLogger().info("onUNPublish");
    			StreamWatchDog watchdog = (StreamWatchDog)stream.getClient().getAppInstance().getProperties().getProperty(streamName);
    			if (watchdog != null)
    				watchdog.stop();		
    		}
    
    		public  void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
    		{
    			getLogger().info("onPublish - stream name: " + stream.getName());
    			getLogger().info("query string: " + stream.getQueryStr());
    			getLogger().info("video codec: " + stream.getPublishVideoCodecId());
    			StreamWatchDog watchdog = new StreamWatchDog();
    			IApplicationInstance appInstance;
    			try
    			{
    				try
    				{
    					appInstance = stream.getClient().getAppInstance();
    				}
    				catch(Exception ex)
    				{
    					appInstance = stream.getRTPStream().getAppInstance();
    				}
    				
    				watchdog.appInstance = appInstance;
    				watchdog.streamName = streamName;
    				watchdog.start();
    				appInstance.getProperties().setProperty(streamName, watchdog);
    			}
    			catch(Exception ex)
    			{
    			}
    		}
    		public void onPause(IMediaStream stream, boolean isPause, double location)
    		{
    			getLogger().info("onPause");
    		}
    	}
    	
    	private class StreamWatchDog
    	{
    		public Timer mTimer;
    		public TimerTask mTask;
    		public String streamName;
    		public IApplicationInstance appInstance;
    		long streamLastSeq;
    		boolean isMissing = false;
    		long currSeq = 0;
    		String msg;
    		public StreamWatchDog(){
    			mTask = new TimerTask()
    			{
    				public void run() 
    				{
    					getLogger().info("Run StreamWatchDog");
    					MediaStreamMap mediamap = appInstance.getStreams();
                        IMediaStream stream = mediamap.getStream(streamName);
                    	
                    	List packets = stream.getPlayPackets();
                    	if (packets.size() == 0)
                        {
                    		msg = "Stream not started";
                        }
                        else
                        {
                      	  AMFPacket packet = (AMFPacket)packets.get(packets.size()-1);
                          currSeq = packet.getSeq();
                          if (currSeq != streamLastSeq)
                          {
                             streamLastSeq = currSeq;
                             msg = "Stream OK";
                          }
                          else
                          {
                             msg = "Stream Appears Stalled";
                          }
                        }
                        appInstance.broadcastMsg("streamStats", streamName,currSeq,msg,new Date());
    				}
    			};
    		}
    		
    		public void start(){
    			
    			if (mTimer==null)
    				mTimer = new Timer();
    			mTimer.schedule(mTask, 10000, 10000);
    			getLogger().info("Start StreamWatchDog");
    		}
    		
    		public void stop(){
    			if (mTimer != null){
    				mTimer.cancel();
    				mTimer=null;
    				getLogger().info("Stop StreamWatchDog");				
    			}
    		}
    	}
    }
    To see the results in Flash, add this callback to the NetConnection object:
    Actionscript:
    Code:
    var netconnection:NetConnection = new NetConnection();
    var clientObj:Object = new Object();
    clientObj.streamStats = function(streamName:String,currSeq:String,msg:String,date:String):void
    {
    	trace("Stream stats. Name: " + streamName + " currSeq: " + currSeq + " msg: " + msg + " date: " + date);
    }
    netconnection.client = clientObj;
    netconnection.connect("rtmp://[wowza-address]/live");

    Comments 25 Comments
    1. daslicht -
      In the example above you are Listening for MetaData :

      class StreamListener implements IMediaStreamActionNotify2
      {
      public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket)
      {
      getLogger().info("onMetaData By: " + stream.getClientId());
      }
      ...

      Is there also a way to Listen to CuePoints ?

      I cant find anything cuePoint Related in the API:
      http://80.250.162.180/2010/Andrey.Bu...onNotify2.html
    1. rrlanham -
      Daslicht,

      I was looking at this over the weekend, and meaning to postback to one of your previous threads on this subject. Sorry I didn't respond sooner, but I wasn't sure. I still haven't completed testing, but I did learn that IMediaStreamCallback onCallBack only works with cuepoints added with NetStream.send in Flash, and therefore limited to the encoder built-in to Flash. I was testing with the server-side IMediaStream.sendDirect.

      I'll try to finish some tests today.

      Richard
    1. daslicht -
      Thank you very much for your feedback !
    1. daslicht -
      Hello Richard,
      I asked the same question at the FMS Forum, and someone pointed me to a issue which I wasn't aware of. Interesting!

      http://forums.adobe.com/thread/765640?tstart=0
    1. rrlanham -
      The response in that forum post is server-side Actionscript for FMS. It's not relevant to Wowza.

      The Wowza solution is using IMediaStreamOnCallback, but it only works with cuepoints that have been added to the stream by a Flash client that is publishing a stream with NetStream using Netstream.send

      If you are injecting cuepoints server-side, because you are using a stand-alone encoder (Wirecast, FMLE, VLC or a hardware encoder), it won't work.

      What is the requirement? Maybe there is another way.

      Richard
    1. daslicht -
      Hello,
      I like to use prerecorded DJ Mixes as source for a Radio Station.

      Once a user connect the station (and during playback),
      he should be provided with song information like artist name, song title, dj name , mix title.

      How would you solve this ?
    1. rrlanham -
      First, do this:

      Code:
      Stream.setSendOnMetadata(true);
      Then metadata from each Playlist item is included in the Stream class stream, and can be read by Flash client onMetaData handler on each switch.

      Richard
    1. ertu22 -
      I'm stuck!
      public void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      {
      StreamWatchDog watchdog = new StreamWatchDog();
      IApplicationInstance appInstance;
      try {
      try {
      appInstance = stream.getClient().getAppInstance(); // here I get the exception
      }
      catch(Exception ex) {
      appInstance = stream.getRTPStream().getAppInstance();
      }

      watchdog.appInstance = appInstance;
      watchdog.streamName = streamName;
      watchdog.start();
      appInstance.getProperties().setProperty(streamName , watchdog);
      }
      catch(Exception ex){}
      }
      I'm getting an exception at appInstance = stream.getClient().getAppInstance();
      stream.getClientId() is -1

      Is there a way to get the application instance when there is no client?
    1. rrlanham -
      Yes, you can do this:

      Code:
      IApplicationInstance appInstance = stream.getStreams().getAppInstance();
      Richard
    1. mekman -
      Hi, i am trying to write a handler incase the live stream stops or cuts off.

      i am not sure if i should create a listener on the client or server side module

      I already have a working scheduler that starts off playing the smil file and switches when the live come back on but i can't seem to get it to switch back to the smil file when the live stops.

      I get the error "Failed to play myStream; stream not found." and then i would have to restart wowza to get the smil file to work again.

      I presume i put a handler on the onUnpublish to help switch me pack to the playlist smil but i have not managed to achieve this

      Code:
      public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      		{
      			getLogger().info("onUNPublish");
      			Stream streams = (Stream)stream.getProperties().getProperty(streamName);
      			String name = streams.getCurrentItem().getName();
                  streams.getPublisher().getAppInstance().broadcastMsg("PlaylistItemStart", name);
      
      
      		}
      I have search all over the forum but i am new to wowza ide and i don't seem to understand it

      Thank you
    1. rrlanham -
      I don't think this will work in onUnPublish. The stream.getCurrentItem() for a Stream class stream will probably return null then, and getName is probably throwing error.

      Use IStreamActionNotify.onPlaylistItemStart() as in this example:

      http://www.wowza.com/forums/content....rver-listener)

      Richard
    1. mekman -
      yes i already have a ServerListenerStreamPublisher with a scheduledItem class and like you said a onPlaylistItemStart(Stream stream, PlaylistItem item)

      My main problem is where do i put a handler to listen to the live to check where it is off or on. I current have a module called ModuleLoopUntilLive also added to my wowza standalone.

      Code:
      package com.mod.wms.modules;
      
      import com.wowza.wms.amf.*;
      import com.wowza.wms.application.*;
      import com.wowza.wms.logging.WMSLoggerFactory;
      import com.wowza.wms.module.*;
      import com.wowza.wms.server.IServer;
      import com.wowza.wms.server.Server;
      import com.wowza.wms.stream.*;
      import com.wowza.wms.stream.publish.Playlist;
      import com.wowza.wms.stream.publish.Stream;
      import com.wowza.wms.media.model.*;
      
      public class ModuleLoopUntilLive extends ModuleBase
      {
      	String liveStreamName ="myStream";
      	String outStreamName = "Stream1";
      	
      	public void onAppStart(IApplicationInstance appInstance) {
      	getLogger().info("loop1...............................................................");
      		liveStreamName = appInstance.getProperties().getPropertyStr("loopUntilLiveStream", "myStream");
      		outStreamName = appInstance.getProperties().getPropertyStr("loopUntilLiveOutStream", "Stream1");
      	}
      	public void onStreamCreate(IMediaStream stream) {
      		getLogger().info("onStreamCreate by: " + stream.getClientId());
      		IMediaStreamActionNotify2 actionNotify  = new StreamListener();
      		
      		WMSProperties props = stream.getProperties();
      		synchronized(props)
      		{
      			props.put("streamActionNotifier", actionNotify);
      		}
      		stream.addClientListener(actionNotify);
      	}
      	public void onStreamDestroy(IMediaStream stream) {
      		getLogger().info("onStreamDestroy by: " + stream.getClientId());
      		
      		IMediaStreamActionNotify2 actionNotify = null;
      		WMSProperties props = stream.getProperties();
      		synchronized(props)
      		{
      			actionNotify = (IMediaStreamActionNotify2)stream.getProperties().get("streamActionNotifier");
      		}
      		if (actionNotify != null)
      		{
      			stream.removeClientListener(actionNotify);
      			getLogger().info("removeClientListener: "+stream.getSrc());
      		}
      	}
      	
      	class StreamListener  implements IMediaStreamActionNotify2 
      	{
      		public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset) 
      		{
      			streamName = stream.getName();
      			getLogger().info("Stream Name: " + streamName);
      		}
      		
      		public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) 
      		{
      			getLogger().info("onMetaData By: " + stream.getClientId());
      		}
      		
      		public void onPauseRaw(IMediaStream stream, boolean isPause, double location) 
      		{
      			getLogger().info("onPauseRaw By: " + stream.getClientId());
      		}
      
      		public void onSeek(IMediaStream stream, double location)
      		{
      			getLogger().info("onSeek");
      		}
      		
      		public void onStop(IMediaStream stream)
      		{
      			getLogger().info("onStop By: " + stream.getClientId());
      			//stream
      		}
      		
      		public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      		{
      			try
                  {
                  String name = streamName;
                  Stream streams = (Stream)stream.getProperties().getProperty(streamName);
                  streams.getPublisher().getAppInstance().broadcastMsg("PlaylistItemStart", name);
                  WMSLoggerFactory.getLogger(null).info("ServerListenerStreamPublisher PlayList Item Start: " + name);
                  }
                  catch(Exception ex)
                  {
                      WMSLoggerFactory.getLogger(null).info("ServerListenerStreamPublisher Get Item error: " + ex.getMessage());
                  }
      			getLogger().info("onUNPublish");
      //			Stream streams = (Stream)stream.getProperties().getProperty(streamName);
      //			String name = streams.getCurrentItem().getName();
      //            streams.getPublisher().getAppInstance().broadcastMsg("PlaylistItemStart", name);
      
      //
      		}
      
      		public  void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      		{
      			getLogger().info("onPublish");
      		}
      		public void onPause(IMediaStream stream, boolean isPause, double location)
      		{
      			getLogger().info("onPause");
      		}
      	}
      }
      i just need to know where to add a live listener server or client side of the modules and why.

      Also Please clarify for me the server and the Client side, How do i know where to add codes, handler etc. I mean whats the role of thumb.

      Thank you for your help so far
    1. rrlanham -
      There is a way, stand by...
    1. rrlanham -
      Here it is, add these lines to onUnPublish:

      Code:
      public void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      {
      	Stream outStream = (Stream)stream.getClient().getAppInstance().getProperties().getProperty(outStreamName);
      	getLogger().info("CurrentListItemName: " + CurrentListItemName);
      	outStream.play(CurrentListItemName,0,-1,true);
      }
      Richard
    1. mekman -
      thank you but this doesnt work. it looks like the streamdestroy is called and the scheduled smil is unable to be called back to play and then i get the "Failed to play myStream; stream not found." I dont know what i am doing wrong
    1. rrlanham -
      I don't understand. How are you setting this up, and how are you testing?

      The streamschedule.smil file is only read once, when the server starts.

      It works for me with simple setup using the scheduler and ModuleLoopUntilLive, with this added to IMediaStreamActionNotify3.onUnPublish()

      Richard
    1. mekman -
      Code:
      public class ModuleLoopUntilLive extends ModuleBase
      {
      	String liveStreamName ="myStream";
      	String outStreamName = "myStream";
      	IVHost vhost = null;
      	
      	public void onAppStart(IApplicationInstance appInstance) {
      	getLogger().info("loop1...............................................................");
      		liveStreamName = appInstance.getProperties().getPropertyStr("loopUntilLiveStream", "myStream");
      		outStreamName = appInstance.getProperties().getPropertyStr("loopUntilLiveOutStream", "Stream1");
      		getLogger().info("xxxxxxxxxxxx"+ liveStreamName+"/"+outStreamName);
      		
      	}
      	public void onConnect(IClient client, RequestFunction function,
      			AMFDataList params) {
      		getLogger().info("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"+client.getClientId());
      		//client.getProperties().setProperty("mp4:sample.mp4", "myStream");
      		
      	}
      	
      	
      	public void onStreamCreate(IMediaStream stream) {
      		
      		
      	}
      	public void onStreamDestroy(IMediaStream stream)
      	{
      		
      		
      	}
      	
      	class StreamListener  implements IMediaStreamActionNotify2 
      	{
      		public void onPlay(IMediaStream stream, String streamName, double playStart, double playLen, int playReset) 
      		{
      			streamName = stream.getName();
      			getLogger().info("Stream Name: " + streamName);
      		}
      		
      		public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) 
      		{
      			getLogger().info("onMetaData By: " + stream.getClientId());
      		}
      		
      		public void onPauseRaw(IMediaStream stream, boolean isPause, double location) 
      		{
      			getLogger().info("onPauseRaw By: " + stream.getClientId());
      		}
      
      		public void onSeek(IMediaStream stream, double location)
      		{
      			getLogger().info("onSeek");
      		}
      		
      		public void onStop(IMediaStream stream)
      		{
      			getLogger().info("onStop By: " + stream.getClientId());
      			//stream
      		}
      		
      	
      		public  void onUnPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      		{
      			try
      			{
      				IServer server=Server.getInstance();
      			getLogger().info("onononononononononononononon");
      			//IMediaStreamActionNotify2 actionNotify  = new StreamListener();
      			Stream outStream = (Stream)stream.getClient().getAppInstance().getProperties().getProperty(liveStreamName);
      			getLogger().info("CurrentListItemName: " + "flv:holding.flv");
      			outStream.play("mp4:sample.mp4",0,-1,true);
      			}
      			catch(Exception ex)
      			{
      				
      				getLogger().info("++++++++++++++++++++++++"+ex.toString());
      			}			
      			
      			
      		}
      
      		public  void onPublish(IMediaStream stream, String streamName, boolean isRecord, boolean isAppend)
      		{
      			
      			
      		}
      		public void onPause(IMediaStream stream, boolean isPause, double location)
      		{
      			getLogger().info("onPause");
      		}
      	}
      }
      Code:
      public class ServerListenerStreamPublisher implements IServerNotify { 
      	
      	 WMSLogger log = WMSLoggerFactory.getLogger(null); 
      	    
      	    Map<String, Stream> streamMap = new HashMap<String, Stream>();
      	    Map<String, Playlist> playlistMap = new HashMap<String, Playlist>();
      	    Publisher publisher;
      	    private String applicationName = "mod";
      	    private String publishStreamName = "myStream";
      	    
      	    public void onServerInit(IServer server)
      	    {
      	        log.info("03030303030303030303ServerListenerStreamPublisher Started.");
      	        
      	        IVHost vhost = null;
      	        IApplication app = null;
      	        
      	        
      	        try
      	            {
      	            vhost = VHostSingleton.getInstance(server.getProperties().getPropertyStr("PublishToVHost", "_defaultVHost_"));
      	            } catch (Exception evhost) {
      	                log.info("020202020202020202ServerListenerStreamPublisher: Failed to get Vhost can not run.");
      	                return;
      	            }
      
      	        try 
      	            {
      	            app = vhost.getApplication(server.getProperties().getPropertyStr("PublishToApplication", "live"));
      	            } catch (Exception eapp) {
      	                log.info("01010101010101ServerListenerStreamPublisher: Failed to get Application can not run.");
      	                return;
      	            }
      	        // publisher = Publisher.createInstance(vhost, applicationName);
      	         //publisher.publish(publishStreamName);
      	         //IPublishingProvider provider = new PublishingProviderMediaReader(publisher, 0, "mp4:sample.mp4");
      	         //provider.play(publisher);
      	            // Belt and Braces check for VHost and App
      	            if ( vhost == null || app == null )
      	                {
      	                log.info("0000000000000000000000000000000000000000000ServerListenerStreamPublisher: VHost or Application failed, not running.");
      	                return;
      	                }
      
      
      	            Boolean passThruMetaData = server.getProperties().getPropertyBoolean("PassthruMetaData", true);
      	            
      	            String storageDir = app.getAppInstance("_definst_").getStreamStorageDir();
      	            
      	        try
      	            {            
      	            String smilLoc = storageDir + "/streamschedule.smil";
      	            File playlistxml = new File(smilLoc);
      	                
      	            if (playlistxml.exists() == false){
      	                log.info("999999999999999999999999999999999999ServerListenerStreamPublisher: Could not find playlist file: " + smilLoc);
      	                return; 
      	            }
      	            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      	            
      	            
      	            DocumentBuilder db = null;
      	            Document document = null;
      	            try {
      	            
      	            db = dbf.newDocumentBuilder();
      	            document = db.parse("file:///" + smilLoc);
      	            
      	            } catch (Exception e ) { log.info("ServerListenerStreamPublisher: XML Parse failed"); return; }
      
      	            
      	            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");
      	                    
      	                    log.info("8888888888888888888888888888888888ServerListenerStreamPublisher: Streame name is '"+streamName+"'");
      	                    
      	                    Stream stream = Stream.createInstance(vhost, app.getName(), streamName);
      	                    streamMap.put(streamName, stream);
      	                    app.getAppInstance("_definst_").getProperties().setProperty(streamName, stream);
      	                }
      	            }
      	            
      	            NodeList playList = document.getElementsByTagName("playlist");
      	            if (playList.getLength() == 0){
      	                log.info("777777777777777777777777777777777777ServerListenerStreamPublisher: 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("66666666666666666666666ServerListenerStreamPublisher: 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").equals("false"))?false:true);
      	                    
      	                    playlistMap.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 = null;
      	                    try {
      	                    
      	                    startTime = parser.parse(scheduled);
      	                    } catch (Exception z ) { log.info("Parsing schedule time failed."); return ; }
      	                    Stream stream = streamMap.get(streamName);
      	                    stream.setSendOnMetadata(passThruMetaData);
      	                    ScheduledItem item = new ScheduledItem(startTime, playlist, stream);
      	                    item.start();
      	                    IStreamActionNotify actionNotify  = new StreamListener(app.getAppInstance("_definst_"));
      	                    stream.addListener(actionNotify);
      	                    log.info("5555555555555555555555555555555ServerListenerStreamPublisher Scheduled: " + stream.getName() + " for: " + scheduled);
      	                }    
      	            }
      	        }
      	        catch(Exception ex)
      	        {
      	            log.info("4444444444444444444444444444444ServerListenerStreamPublisher: Error from playlist manager is '"+ex.getMessage()+"'");
      	        }
      	    }
      	    
      	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() {
      	                   synchronized(mStream.getLock())
      	                    {
      	                        mPL.open(mStream);
      	                    }
      	                    log.info("3333333333333333333333333333ServerListenerStreamPublisher 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("111111111111111111111111111111scheduled playlist: "+mPL.getName()+
      	                        " on stream: "+mStream.getName()+
      	                        " for:"+mStart.toString());
      	        }
      	        
      	        public void stop(){
      	            if (mTimer != null){
      	                mTimer.cancel();
      	                mTimer=null;
      	                log.info("2222222222222222222222222222222222222cancelled playlist: "+mPL.getName()+
      	                        " on stream: "+mStream.getName()+
      	                        " for:"+mStart.toString());
      	            }
      	        }
      	    }
      	    public void onServerCreate(IServer server)
      	    {
      	    }
      	    public void onServerShutdownComplete(IServer server)
      	    {
      	        log.info("ServerListenerStreamPublisher: Shutdown server start");
      	        for (Map.Entry<String, Stream> entry : streamMap.entrySet())
      	        {
      	            try
      	            {
      	            Stream stream = entry.getValue();
      	            stream.close();
      	            stream = null;
      	            log.info("040404040404040404ServerListenerStreamPublisher Closed Stream: " + entry.getKey());
      	            }
      	            catch(Exception ex)
      	            {
      	                log.error(ex.getMessage());
      	            }
      	        }
      	        for (Map.Entry<String, Playlist> entry : playlistMap.entrySet())
      	        {
      	            try
      	            {
      	            Playlist pl = entry.getValue();
      	            pl = null;
      	            }
      	            catch(Exception ex)
      	            {
      	                log.error(ex.getMessage());
      	            }
      	        }
      	    }
      
      	    public void onServerShutdownStart(IServer server)
      	    {
      	        
      	    }
      	    
      	    class StreamListener implements IStreamActionNotify
      	    {
      	        StreamListener(IApplicationInstance appInstance)
      	        {
      	        }    
      	        public void onPlaylistItemStop(Stream stream, PlaylistItem item)
      	        {
      	        	/*if (item.getIndex() == (stream.getPlaylist().size() - 1))
      	        	{
      	        	if (! stream.getRepeat())
      	        	{
      	        	stream.close();
      	        	WMSLoggerFactory.getLogger(null).info("ServerListenerStreamPublisher: closing stream: " + stream.getName());
      	        	}
      	        	}*/
      	        }
      	        public void onPlaylistItemStart(Stream stream, PlaylistItem item) 
      	        {
      	           /* try
      	            {
      //	            String name = stream.getCurrentItem().getName();
      //	            stream.getPublisher().getAppInstance().broadcastMsg("PlaylistItemStart", name);
      //	            WMSLoggerFactory.getLogger(null).info("ServerListenerStreamPublisher PlayList Item Start: " + name);
      	            }
      	            catch(Exception ex)
      	            {
      	                WMSLoggerFactory.getLogger(null).info("ServerListenerStreamPublisher Get Item error: " + ex.getMessage());
      	            }*/
      	        }
      	    }
      	}
      Sorry for the messy code. I am still trying to get the hang of the ide.

      Basically, right now it switches from the smil to the live but doesnt switch back. and gives the error "Failed to play Stream1; stream not found." when i use this player page http://www.wowza.com/resources/3.5.0...er/player.html
    1. rrlanham -
      Try stepping through line by line in the IDE, and keep an eye on the console output. Are you hitting this line?

      Code:
      outStream.play("mp4:sample.mp4",0,-1,true);
      Try "false" for the reset arg (that might be the problem):
      Code:
      outStream.play("mp4:sample.mp4",0,-1, false);
      Richard
    1. mekman -
      thank you it is switching now but something strange is happening

      from the code i have
      String liveStreamName ="myStream";
      String outStreamName = "Stream1";

      When i publish to Stream1 using flash encoder and then unpublish. Stream 1 stops working and myStream switches from smil playlist to sample.mp4.

      the streamname is destroyed or something. cos it doesnt work till i restart wowza
    1. rrlanham -
      If you are publishing a stream named "Stream1" to this application using a live encoder, that won't work. "Stream1" in this example is the name of the server-side Stream class stream that Wowza is creating and that clients will playback. The source of Stream1 is the static file you specifiy, then the source switches to the live stream. In other words, Stream1 wraps "sample.mp4" and "myStream" (the published stream). Publishing an live stream from an encoder to this application with the same name as the server-side stream will break everything.

      Richard