Wowza Community

Detect if a stream goes online or offline

If I want to start a webcam platform with multiple cams, is there a module or which module can I use to detect if a stream goes online or offline, so I can save the status to a database? Is something possible or is there a module that can do this?

Take a look at IMediaStreamActionNotify.onUnPublish():

https://www.wowza.com/docs/how-to-use-imediastreamactionnotify3-interface-to-listen-for-rtmp-stream-events-includes-codec-info

Refer to this post for database connectivity in Wowza:

https://www.wowza.com/docs/how-to-do-user-authentication-for-flash-rtmp-client-using-jdbc-connection-to-mysql-database

Don’t over-use JDBC connections in Wowza. A quick connect in the onUnPublish handler should be okay.

And take a look at the IOPerformanceCounter in the Wowza API.

Richard

Take a look at the HTTPUtils api in the Wowza api. Use with caution, http calls are not recommended. It would be best if you not make Wowza wait, make the call and, if necessary, process a response in its own thread. If you must process a response to proceed, that is where things get dicey with http calls.

Richard

You can use IMediaStreamActionNotify3 events (including .onPublish and .onUnPublish):

https://www.wowza.com/docs/how-to-use-imediastreamactionnotify3-interface-to-listen-for-rtmp-stream-events-includes-codec-info

Richard

There is something else to add to this, a ThreadPoolExecutor, but I have not yet.

Richard

Actually, I am not sure about this. I am going to delete it for now.

Richard

I’m unsure. I’ll get back to you.

Richard

What is the best method to call an url, for example: http://domainname/online?streamname=name in the onPublish and onUnpublish methods? Is this possible in that module? I need to ping a node js server to notify it if a cam is online or not.

Something like the following would do, without problems? I don’t have to process the response.

try {

URL url = new URL(“http://www.example.com”);

try {

HttpURLConnection con = (HttpURLConnection) url.openConnection();

} catch(IOException e) {

System.out.println("IOException: " + e.getMessage());

}

} catch(MalformedURLException e) {

System.out.println("MalformedURLException: " + e.getMessage());

} }

The above doesn’t seem to work and the following also doesn’t work":

HTTPUtils.HTTPRequestToByteArray(“http://www.example.com/test.php",“GET”,"wowza=”+streamName,null);

If i use the post method:

HTTPUtils.HTTPRequestToByteArray(“http://www.example.com/test.php",“POST”,"wowza=”+streamName,null);

it is working like a charm!

Well, this looks very good, but is it possible to open a new thread in the IMediaStreamActionNotify onUnpublish and unPublish events, because then the stream is published and unpublished for sure.

I mean what happens if the publish function is invoked (the HTTPWorker is also invoked), but it returns an error. Now the stream isn’t working but the stream in the database is set to being live.

Can I be sure that when publish is invoked, the stream is really wokring?

What function can I use for unPublish? I couldn’t find an unPublish function, only something like deleteStream or closeStream?

Ok thanks, now I see how it works, just have to add the following class: public class HTTPWorker implements Runnable to the Module base where the actionnotifier also is. Many thanks!

What is the solution then?

Hi,

Here is a more complete example that Richard was trying to show in the previously removed post.

package com.wowza.wms.test;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.wowza.util.HTTPUtils;
import com.wowza.wms.amf.AMFDataList;
import com.wowza.wms.client.IClient;
import com.wowza.wms.module.*;
import com.wowza.wms.request.RequestFunction;
public class ModuleHTTPSafeCall extends ModuleBase {
	private interface IResponseListener {
		public void onResponse(byte[] response);
	}
	
	private class HTTPWorker implements Runnable {
		String url;
		IResponseListener listener = null;
		
		public HTTPWorker(String url, IResponseListener listener) {
			this.url = url;
			this.listener = listener;
		}
		@Override
		public void run() {
			byte[] response = HTTPUtils.HTTPRequestToByteArray(url, "get", null, null);
			if(listener != null) {
				listener.onResponse(response);
			}
			
			getLogger().info("ModuleHTTPSafeCall url: " + url);
		}
		
	}
	
	private class ResponseListener implements IResponseListener {
		private IClient client;
		public ResponseListener(IClient client)
		{
			this.client = client;
		}
		@Override
		public void onResponse(byte[] response)
		{
			// do something here with response if needed.
			getLogger().info("Response: " + new String(response));
		}
		
	}
	private ThreadPoolExecutor runner = new ThreadPoolExecutor(1, 1, 3000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
	public void publish(IClient client, RequestFunction function, AMFDataList params) {
		runner.execute(new HTTPWorker("http://localhost/test.html", new ResponseListener(client)));
		invokePrevious(this, client, function, params);
	}
}

What Richard was trying to show is that it is important, when doing remote calls that could take a while to return, that you do not stall the current thread while waiting. It is best practice to use a separate thread pool to run the remote calls.

This example also adds a response listener to capture the response value from the remote call so you can work with it. If you do not need to use the response value then you can use

runner.execute(new HTTPWorker("http://localhost/test.html", null));

Roger.

I have a question regarding Disney plus streaming service, I just installed a few days back & now start facing the buffering issue, I know this service is ongoing with infancy period. Any thoughts?

https://getsolved.org/know-about-disney-plus-streaming-service/

1 Like