How-To

  • How to receive SAP packets and process them

    We were asked to look at SAP (Session Announcement Protocol) and how we could make it work with Wowza Streaming Engine. It turns out it is a relatively simple protocol but there are few gotchas which did trip us up however we have come up with an application module that should meet most needs along with a server listener to start applications when the server starts (so applications can listen for SAP packets). If you are not completely familiar with SAP, do have a Google, however it is possible that multiple addresses can be announced to, thus the simplest method was to provide properties at the application level so each application can listen for different addresses if needed. The SAP protocol also does not provide a ‘stream name’ so this presented a challenge, as in order for Wowza Streaming Engine to take in a stream it does need to have a name/filename. To ...

  • How to publish with WebRTC using H264

    This has been asked many times on how to get WebRTC to publish with H264 using the WebRTC publisher provided by Wowza. This code is extremely basic but by default publishes VP8. There are two ways to resolve this problem and we are going to choose one that requires no changes to the Wowza configuration/session interface. If you look at section function gotDescription(description) { console.log('gotDescription: '+JSON.stringify({'sdp': description})); peerConnection.setLocalDescription(description, function () { sendPost(postURL, '{"direction":"publish", "command":"sendOffer", "streamInfo":'+JSON.stringify(streamInfo)+', "sdp":'+JSON.stringify(description)+'}'); }, function() {console.log('set description error')}); } This is where we have the SDP information to publish a stream and is added to the local session with the peerConnection.setLocalDescription call. This presents an opportunity to change the SDP data. If you look through the SDP data, it is conveniently logged to the console in your browser, then you can see where the video codec is ...

  • How To – Do Stream Motion Detection

    We have been asked to look at several features relating to the transcoder, one being motion detection. We did a little digging and it appears Wowza Streaming Engine provides access to frames after they have been decoded. There are several posts such as Stack OverFlow and a somewhat more complete example Wowza Code Example This module demonstrates how to perform motion detection on an incoming stream. It does require the use of the Wowza Streaming Engine transcoder as it does require access to the decoded frames. It is only a proof of concept module so there is no doubt room for improvement. You will need to configure the module in the Application.xml, as the last module in the Modules section as follows Module setup: <Module> <Name>MotionDetection</Name> <Description>MotionDetection</Description> <Class>guru.thewowza.example.transcoder.MotionDetect</Class> </Module> You do also need to configure the Application.xml to use the transcoder as follows Set the the LiveStreamTranscoder so have ‘transcoder’ set, this can also be done in the Wowza Streaming Engine Manager <LiveStreamTranscoder>transcoder</LiveStreamTranscoder> You ...

  • How to set stream timecodes to absolute time

    We were recently asked to look at how to provide absolute timecodes in a stream, regardless of if the encoder sent them or not. This can be done and is extremely simple to do. package guru.thewowza.example.absolute; import com.wowza.wms.application.*; import com.wowza.wms.amf.*; import com.wowza.wms.module.*; import com.wowza.wms.stream.*; public class Timecode extends ModuleBase { public void onAppStart(IApplicationInstance appInstance) { String fullname = appInstance.getApplication().getName() + "/" + appInstance.getName(); getLogger().info("onAppStart: " + fullname); } public void onAppStop(IApplicationInstance appInstance) { String fullname = appInstance.getApplication().getName() + "/" + appInstance.getName(); getLogger().info("onAppStop: " + fullname); } public void onStreamCreate(IMediaStream stream) { stream.addLivePacketListener(new PacketListener()); } public void onStreamDestroy(IMediaStream stream) { } class PacketListener implements IMediaStreamLivePacketNotify { private boolean firstPacket = false; private long baseTimeCode = 0L; private long baseSystemTime = 0L; private long packetTimeCode = 0L; public PacketListener() { } public void onLivePacket(IMediaStream stream, AMFPacket thisPacket) { if ( this.firstPacket == false ) { this.firstPacket = true; this.baseTimeCode = thisPacket.getAbsTimecode(); this.baseSystemTime = System.currentTimeMillis(); } packetTimeCode = thisPacket.getAbsTimecode()-this.baseTimeCode; packetTimeCode = packetTimeCode + this.baseSystemTime; thisPacket.setAbsTimecode(packetTimeCode); } } The code simple determines if this is the first run, sets up a base time from the first packet, gets the current system time and then all packet timecodes are a delta ...

  • How To Get File Information – Codec/Bitrate

    We have been looking at how to do this for a while and finally came up with a reasonable method. This could be used in conjunction with the AMLST API and do note it does trigger some ‘cupertino’ messages although you may not be using cupertino to stream anything. private IMediaReaderCupertino mediaReader = null; private IApplicationInstance appIns = null; private IMediaStream stream = null; private String streamName = null; // Do something here to populate the above. If you look at the AMLST API these can be // determined quite easily. // Assume we have a 'streamName' of sample.mp4 // A little naughty here, but it works. try { IMediaReader reader = MediaReaderFactory.getInstance(appIns, appIns.getVHost().getMediaReaders(), "mp4cupertino"); if (reader != null) { String basePath = appIns.getStreamStoragePath(); reader.init(this.appIns, this.stream, "mp4cupertino", basePath, streamName); reader.open(basePath, streamName); mediaReader = (IMediaReaderCupertino)ret; } } catch (Exception e) { WMSLoggerFactory.getLogger(null).info("Broke it "+e.toString()); } IHTTPStreamerCupertinoIndex indexer = null; indexer = new HTTPStreamerCupertinoIndexFile(); mediaReader.indexFile(indexer); // You need to close the reader otherwise it leaves the file handle open mediaReader.close(); // We can now do int audioBitrate ...

  • How to create an IClient object

    There are occasions where code within Wowza requires an IClient object, however you find that either there are no connections or none available within the class space you are working within. You can create an IClient object with the following code IClient thisClient = new Client(appInstance.getVHost(),Server.getInstance().getClientIdGenerator().getNextId()); This will then allow you to pass the created object into code without the need to have a client connection.

  • Use ffmpeg for RTSP output

    A simple example of how to publish RTSP to your wowza server using ffmpeg.

  • REST API – get historic connection counts

    You can obtain historical connection & bandwidth information via Wowza’s REST API.

  • How To Add a MediaCache Source Dynamically

    One of things we have been asked to do many times is add a media cache source WITHOUT the need to restart Wowza Streaming Engine. If you use the Wowza Streaming Engine Manager then this is not possible as it will prompt for a server restart. It is possible to add a MediaCache source and below is a snippet of code which demonstrates this MediaCacheConfigSourceItem sourceItem = new MediaCacheConfigSourceItem(); sourceItem.setName("Test"); sourceItem.setBasePath("http://192.168.1.200/"); sourceItem.setPrefix("http/"); sourceItem.setBaseClass("com.wowza.wms.mediacache.impl.MediaCacheItemHTTPImpl"); //sourceItem.setReaderClass(""); sourceItem.setDefaultBlockSize(1024); sourceItem.setMaxTimeToLive(300000); sourceItem.setMinTimeToLive(100000); sourceItem.setReadAhead(true); sourceItem.setReadAheadThreshold(30); sourceItem.setPassThru(false); MediaCacheSourceBasic source = new MediaCacheSourceBasic(); sourceItem.configureMediaCacheSource(source); MediaCache mediaCache = MediaCacheImpl.getMediaCache(); mediaCache.addSource("Test", source); This has been tested with onAppStart but of course can be added anywhere.

  • Verify a VOD asset exists via HTTP Provider

    We’ve had recent requests for an http provider that will verify existence of a particular VOD asset.