Using the Wowza Stream Class

I mentioned in the previous post about using ffmpeg in a cron job to create Simulated Live events via Wowza. In this post, I’ll explain how to do it using the Wowza Stream Class module, which allows you to set a broadcast schedule to play a mix of recorded and live content.

Wowza has a pretty good document on how to add this module in to your server and do a test playlist.If you’re setting this up on Amazon EC2, you’ll need to update your startup package by putting the module in the wowza/lib directory and the playlist in the wowza/content directory

Unfortunately, the tutorial doesn’t really cover playlist creation beyond the example. This is especially tricky, given that the scheduling parameters don’t seem to conform to any known SMIL standard. Yes, it’s XML, so theoretically, it doesn’t matter, but there are extensions in SMIL 3.0 that are meant to deal with server-side playlists for automating programming.

Unless you specified a different application name in the Properties section of Server.xml, the automated playlist will publish to the live application.

The basic structure of the SMIL file body consists of <stream> and <playlist> statements.

Stream Element

The <stream> element defines one or more virtual stream names that the playlists will feed into:

<stream name="playlist-high"></stream>
<stream name="playlist-low"></stream>

In this example, I have a high and low bandwidth stream. In your player, you reference the stream name, rather than the streamshedule.smil file, like this:

Flash RTMP:

streamer: rtmp://wowza.server.address(:port)/live
file: playlist-high

Flash HTTP:

http://wowza.server.address/live/playlist-high/manifest.f4m

HLS:

http://wowza.server.address/live/playlist-high/playlist.m3u8

Silverlight

http://wowza.server.address/live/playlist-high/Manifest

Playlist element

The <playlist> element defines specific video sequences that go into the virtual stream. There are four key parameters to the playlist element:

  • name : This is a unique name for that particular sequence.
  • playOnStream : This tells the Stream Class module which of the previously defined streams this playlist is associated with.
  • repeat : Valid values are true/false. This defines whether this playlist loops when it gets to the end.
  • scheduled : When this playlist is scheduled, in the format “YYYY-MM-DD HH:MM:SS” (24-hour time)

Within the playlist element are one or more <video> statements that use the following parameters:

  • src: the video to be played. Can either be:
    • a stream within the same live application (use the stream name only)
    • an MP4 video file in the Wowza content directory (use mp4:filename.mp4)
    • A stream elsewhere (requires some additional modules)
  • start : The number of seconds into the video to start playing. If this is a live source, use the value -2.
  • length : The number of seconds to play the video. The value -1 indicates to play until it ends.

Using start/length is a useful way to introduce commercial breaks or intermissions into a stream. This example would show BigBuckBunny.mp4 from the start, for 60 seconds, then cut to a commercial for the duration of the advertisement-1.mp4 file. After the commercial, it would resume and play for 2 more minutes, play a 30-second commercial from advertisement-2.mp4 and then plays the rest of the BigBuckBunny.mp4 file. If the playlist set to repeat, this will loop.

<video src="mp4:BigBuckBunny.m4v" start="0" length="60"/>
<video src="mp4:advertisement-1.mp4 start="0" length="-1"/>
<video src="mp4:BigBuckBunny.m4v" start="60" length="120"/>
<video src="mp4:advertisement-2.mp4 start="0" length="30"/>
<video src="mp4:BigBuckBunny.m4v" start="180" length="-1"/>

When a particular playlist has ended, and there are no others currently scheduled, it will default to the last playlist, even if that playlist’s repeat is set to false.

Here’s an example for our weekly service replays, and live sunday events:

<smil>
 <head>
 </head>
 <body>

  <stream name="playlist-high"></stream>
  <stream name="playlist-low"></stream>

  <playlist name="mon-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-17 07:45:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-17 07:45:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-17 09:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="mon-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-17 09:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-18 12:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-18 12:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-18 14:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="tue-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-18 14:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-19 21:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-19 21:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-19 23:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="wed-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-19 23:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-20 03:15:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-20 03:15:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-20 05:00:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="thu-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-20 05:00:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-21 07:45:00">
   <video src="mp4:traditions-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-21 07:45:00">
   <video src="mp4:traditions-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-21 09:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="fri-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-21 09:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-l" playOnStream="playlist-low" repeat="false" scheduled="2011-01-22 02:45:00">
   <video src="mp4:praise-l.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-h" playOnStream="playlist-high" repeat="false" scheduled="2011-01-22 02:45:00">
   <video src="mp4:praise-h.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-22 04:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sat-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-22 04:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-am-high" playOnStream="playlist-high" repeat="false" scheduled="2011-01-23 11:30:00">
   <video src="mobile-2" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-am-low" playOnStream="playlist-low" repeat="false" scheduled="2011-01-23 11:30:00">
   <video src="mobile-1" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-am-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-23 13:15:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-am-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-23 13:15:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-pm-high" playOnStream="playlist-high" repeat="false" scheduled="2011-01-23 17:45:00">
   <video src="mobile-2" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-pm-low" playOnStream="playlist-low" repeat="false" scheduled="2011-01-23 17:45:00">
   <video src="mobile-1" start="-2" length="6300"/>
  </playlist>

  <playlist name="sun-pm-loop-h" playOnStream="playlist-high" repeat="true" scheduled="2011-01-23 19:30:00">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="sun-pm-loop-l" playOnStream="playlist-low" repeat="true" scheduled="2011-01-23 19:30:00">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="default-high" playOnStream="playlist-high" repeat="true" scheduled="2011-01-01 00:00:01">
   <video src="mp4:1-16-Loop-H.mp4" start="0" length="-1"/>
  </playlist>

  <playlist name="default-low" playOnStream="playlist-low" repeat="true" scheduled="2011-01-01 00:00:01">
   <video src="mp4:1-16-Loop-L.mp4" start="0" length="-1"/>
  </playlist>

 </body>
</smil>

Video files can either be uploaded, or recorded on the server using a live-record application type.

Once your playlist is built, you’ll need to restart the Wowza service for it to read the new playlist in and schedule it internally.

Update(July 18, 2001) : I’ve added a post about my Excel playlist generator.

16 Comments On “Using the Wowza Stream Class”

  1. Hey i need help setting the playlist on my server! i have not sleep for two days trying to figure this out. step by step instruction, where to put the file to which folder.
    thanks kevin

    Reply

    • The playlist belongs into the content folder. Make sure you have modified the Server.xml and added the StreamListener

      Reply

  2. Hi, I need to use the same concept to achieve  the following, i have live streaming video i record them to specific files using Flash Midea Live Encoder or  wowza server, I want to make playlist on the fly from recorded media and show it to users using time and calender to playback recorded video file
    how can i ado that
    thanks

    Reply

  3. hi – i wonder if anyone could point me to any kind of SMIL file generator with user interface where non-technical user would be able to create a playlist with schedule.
    many thanks!

    Reply

  4. Pingback: Wowza Stream Class Playlist Generator | Streaming My Consciousness

  5. Thank you for this post. It took a while but I was able to set up a perfectly working stimulated live stream that works very well except for one thing.  Do you ever experience buffering issues?  My source file is about 300MB and I would not think buffering would be an issue since the source is on the server.  On the client side I’m using JWPlayer.  I’m not sure if it is the size of the file or some other setting that I might be able to adjust. Any advice? Thanks.

    Reply

    • Nope, 300MB isn’t a very big file, and I’ve used streamclass with much larger files than that – buffering is usually a bandwidth issue on the client end. It’s also possible that your disk I/O is insufficient on the server end. 

      Reply

      • Thanks Ian. I think the source file was the issue.  Took a 24GB 1920×1080 MPG compressed to same resolution 300 MB MP4 with Handbrake.  I changed it to a 640×360, 89 MB file and, presto, no buffering issues.  I still need to find the right balance of quality and size, but I think I’m on the right track now and don’t have the skills to address the I/O on the server end.  I appreciate the help.

        Reply

  6. Hi lan

    This post is really awesome and its working well for me. I have one more doubt, how can i create a dynamic playlist without restarting   the wowza server. I want to add the stream name, playlist name and video src name dynamically without editing the streamschedule.smil file manually. I tried with StreamClassControl( a modified flash player by wowza ) but i cant create a new playlist dynamically. Please help me 

    Thanks in advance
    Sathish

    Reply

  7. How could I make this work using Wowza on Amazon EC2 with .mov files hosted on Amazon S3 bucket?

    Reply

    • Use a vods3 application and reference the file in the playlist using the vods3 syntax: mp4:amazons3/bucket/filename

      Reply

      • Hello Ian, I have to use this  in the /conf/Server.xml /Properties? and what change I have to do in vods3 Aplication.xml?

        PublishToApplicationMyLiveApp

        Reply

        • There’s nothing you should have to do in your vods3 application – if you’re able to use vods3 already, then you should simply need to reference the stream as above. In effect, “amazons3” is a virtual path. Make sure you use _definst_ when using s3 paths. 

          Reply

  8. Hello
    We want to record ts( m3u8, http wowza live stream)
    -Record 1 second per ts and play ( some time or ts file segment)
    -How can generate playlist?

    Any body can advise us?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *