Wowza Community

Logging HLS Chunk requests.

Hello,

In order to get the statistics that we want we need to log requested (Yes requested, not listned to. :)) chunks.

We have found out how to use onDestroy to get the the amount of data sent during the session, but that doesn’t really cut it.

Is there a way to trigger a custome module method on each chunk request?

Regards Martin

Hello Martin,

It sounds like you are just looking to get the totals by stream of data sent but more frequently than just when onDestroy is called. With that said, one approach you could take is to check (via separate thread) incrementally for the given streams data out. You could iterate through each stream and utilize IOPerformanceCounter to get the current bytes out total.

Karel,

onFillChunkEnd() fires for every chunk and has some data like stopTimecode, but I don’t see how to associate that with a session. There is an example here

I’m not sure if there a way to get what you want, exactly. There are totals in the logs per session, including sc-bytes (server to client bytes) and x-duration. For billing purposes that should be all you need.

Richard

You can use WMSProperties on the IHTTPStreamerCupertinoIndex. Like this:

package test;
import com.wowza.wms.httpstreamer.model.*;
import com.wowza.wms.logging.WMSLoggerFactory;
import com.wowza.wms.module.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.application.*;
import com.wowza.wms.httpstreamer.cupertinostreaming.file.*;
import com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.*;
import com.wowza.wms.httpstreamer.cupertinostreaming.livestreampacketizer.*;
import com.wowza.wms.httpstreamer.cupertinostreaming.util.CupertinoEncInfo;
import com.wowza.wms.media.mp3.model.idtags.*;
public class ModuleCupertinoVODOnTextToID3 extends ModuleBase
{
	class VODActionNotify implements IHTTPStreamerCupertinoVODActionNotify2
	{
		IApplicationInstance appInstance = null;
		
		public VODActionNotify(IApplicationInstance appInstance)
		{
			this.appInstance = appInstance;
		}
		
		public void onCreate(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerApplicationContext appContext, IHTTPStreamerSession httpStreamerSession, String rawStreamName, String streamExt, String streamName)
		{
			fileIndex.getProperties().setProperty("QueryStr", httpStreamerSession.getQueryStr());
		}
		public void onInit(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerApplicationContext appContext, IHTTPStreamerSession httpStreamerSession, String rawStreamName, String streamExt, String streamName)
		{
		}
		public void onOpen(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerApplicationContext appContext, IHTTPStreamerSession httpStreamerSession, String rawStreamName, String streamExt, String streamName)
		{
		}
		public void onIndex(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerApplicationContext appContext, IHTTPStreamerSession httpStreamerSession, String rawStreamName, String streamExt, String streamName)
		{	
		}
		public void onFillChunkStart(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerCupertinoIndexItem item, LiveStreamPacketizerCupertinoChunk chunk, boolean audioOnly)
		{
			WMSProperties props = fileIndex.getProperties();
			WMSLoggerFactory.getLogger(null).info("QueryStr: " + props.getPropertyStr("QueryStr"));
			
		}
		public void onFillChunkEnd(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerCupertinoIndexItem item, LiveStreamPacketizerCupertinoChunk chunk, boolean audioOnly)
		{
		}
		public void onDestroy(IHTTPStreamerCupertinoIndex fileIndex)
		{
		}
		public void onFillChunkDataPacket(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerCupertinoIndexItem item, LiveStreamPacketizerCupertinoChunk chunk, boolean audioOnly, AMFPacket packet, ID3Frames id3Frames)
		{
		}
	}
	public void onAppStart(IApplicationInstance appInstance)
	{
		while(true)
		{
			IHTTPStreamerApplicationContext appContext = appInstance.getHTTPStreamerApplicationContext("cupertinostreaming", true);
			if (appContext == null)
				break;
			
			if (!(appContext instanceof HTTPStreamerApplicationContextCupertinoStreamer))
				break;
			
			HTTPStreamerApplicationContextCupertinoStreamer cupertinoAppContext = (HTTPStreamerApplicationContextCupertinoStreamer)appContext;
			cupertinoAppContext.addVODActionListener(new VODActionNotify(appInstance));
			break;
		}
		
		getLogger().info("ModuleCupertinoVODOnTextToID3.onAppStart["+appInstance.getContextStr()+"]");
	}
}

Richard

The essential parts:

		public void onCreate(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerApplicationContext appContext, IHTTPStreamerSession httpStreamerSession, String rawStreamName, String streamExt, String streamName)
		{
			fileIndex.getProperties().setProperty("QueryStr", httpStreamerSession.getQueryStr());
		}
		public void onFillChunkStart(IHTTPStreamerCupertinoIndex fileIndex, IHTTPStreamerCupertinoIndexItem item, LiveStreamPacketizerCupertinoChunk chunk, boolean audioOnly)
		{
			WMSProperties props = fileIndex.getProperties();
			WMSLoggerFactory.getLogger(null).info("QueryStr: " + props.getPropertyStr("QueryStr"));
			
		}

Richard

Hello Matt, Martin

Could the IHTTPStreamerCupertinoVODActionNotify2 interface help in this matter?

Karel

Well, since the onCreate, onOpen, etc. methods have a reference to the IHTTPStreamerSession, I wondered if it somehow would be possible to tie this to the onFillChunkEnd() and find out which session the chunks were sent to. The most important data would be the httpStreamerSession.getQueryStr().

What we want to know is not only how many chunks or bytes were sent but also which part of the file.

Hey Martin,

Can you tell me more about what you are ultimately trying to achieve? Is it just more frequent updates of bytes out? Are you saving the information locally or remotely?

Matt

Hello Matt,

We are interested in knowing which part of the streams are played. And the requested chunks are a good enough approximation for this. We are really hoping to be able to do this from within Wowza instead of intercepting the http request outside of Wowza.

Regards Martin