# Dynamic Ads Insertion

**URL:** <https://community.wowza.com/t/dynamic-ads-insertion/52629>\
**Category:** Wowza Developer Dojo\
**Tags:** wowza-streaming-server-java-api\
**Created:** [January 10, 2019, 4:38pm UTC](https://community.wowza.com/t/dynamic-ads-insertion/52629 "2019-01-10T16:38:45Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![Iyus\_Dedi\_Putra](https://avatars.discourse-cdn.com/v4/letter/i/cab0a1/32.png) [@Iyus\_Dedi\_Putra](https://community.wowza.com/u/Iyus_Dedi_Putra)\
**Post date:** [January 10, 2019, 4:38pm UTC](https://community.wowza.com/t/dynamic-ads-insertion/52629/1 "2019-01-10T16:38:45Z")

</div>

Dear all,

I want to ask about how to get SCTE-35 markers on live streaming application. There is a documentation that we have to build java based code to get that file [Monitor MPEG-TS ingestion to process additional data streams (SCTE-35, KLV, etc.)](https://www.wowza.com/docs/how-to-monitor-mpeg-ts-ingestion-to-process-additional-data-streams-scte-35-klv-etc) .

```auto
import java.util.*;

import com.wowza.wms.amf.*;
import com.wowza.wms.logging.*;
import com.wowza.wms.rtp.model.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.transport.mpeg2.*;
import com.wowza.wms.transport.mpeg2.ProgramMapTable.*;
import com.wowza.wms.transport.mpeg2.section.cue.*;

public class RTPDePacketizerMPEGTSMonitorCUE extends RTPDePacketizerMPEGTSNotifyBase
{
	private static final Class<RTPDePacketizerMPEGTSMonitorCUE> CLASS = RTPDePacketizerMPEGTSMonitorCUE.class;
	private static final String CLASSNAME = "RTPDePacketizerMPEGTSMonitorCUE";

	private IMediaStream stream = null;
	private RTPDePacketizerMPEGTS rtDePacketizerMPEGTS = null;
	private boolean isTimecodeReady = false;
	private RTPTrack rtpTrack = null;
	private boolean debugLog = false;

	class MPEGTSMonitorCUE implements IMPEG2UserMonitorSectionNotify
	{
		@Override
		public void onMonitorStart()
		{
		}

		@Override
		public void onMonitorStop()
		{
		}

		@Override
		public void onDataSection(int pid, AdaptationField field, MPEG2Section section)
		{
			if (section.getTableID() == SpliceInformationTable.SIT_TABLE_ID)
			{
				try
				{
					SpliceInformationTable spliceInformationTable = new SpliceInformationTable(section);
					if (spliceInformationTable != null)
					{
						if (debugLog)
							WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME + ".onDataSection: " + spliceInformationTable.toString());

						SpliceInformationTableSerializeAMFContext serializeContext = new SpliceInformationTableSerializeAMFContext();

						serializeContext.timeReference = rtDePacketizerMPEGTS.getVideoTC();
						serializeContext.rtpTrack = rtpTrack;

						AMFDataObj amfData = spliceInformationTable.serializeAMF(serializeContext);
						if (amfData != null)
							stream.sendDirect("onCUE", amfData);
					}
				}
				catch(Exception e)
				{
					WMSLoggerFactory.getLogger(CLASS).error(CLASSNAME+".onDataSection: ", e);
				}
			}
		}
	}

	@Override
	public void onInit(RTPDePacketizerMPEGTS rtDePacketizerMPEGTS, RTPContext rtpContext, RTPDePacketizerItem rtpDePacketizerItem)
	{
		this.debugLog = rtDePacketizerMPEGTS.getProperties().getPropertyBoolean("rtpDePacketizerMPEGTSMonitorKLVDebugLog", this.debugLog);
	}

	@Override
	public void onStartup(RTPDePacketizerMPEGTS rtDePacketizerMPEGTS, RTPTrack rtpTrack)
	{
		WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onStartup");

		this.rtDePacketizerMPEGTS = rtDePacketizerMPEGTS;
		this.rtpTrack = rtpTrack;

		RTPStream rtpStream = rtpTrack.getRTPStream();
		if (rtpStream != null)
			this.stream = rtpStream.getStream();
	}

	@Override
	public void onTimecodeReady(RTPDePacketizerMPEGTS rtDePacketizerMPEGTS)
	{
		WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onTimecodeReady");

		this.isTimecodeReady = true;
	}

	@Override
	public void onPMT(RTPDePacketizerMPEGTS rtDePacketizerMPEGTS, ProgramMapTable newPMT)
	{
		WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onPMT");

		boolean SCTE35RegDescFound = false;

		ArrayList<Descriptor> regDescriptors = newPMT.programDescriptors.get(Descriptor.DESCRIPTOR_TAG_REGISTRATION);

		if (regDescriptors != null && regDescriptors.size() > 0)
		{
			for (Descriptor desc : regDescriptors)
			{
				SCTE35RegDescFound |= ((RegistrationDescriptor)desc).formatIdentifier == RegistrationDescriptor.REG_IDENTIFICATION_SCTE_SPLICE_FORMAT;
			}
		}

		for (StreamInfo s : newPMT.streams.values())
		{
			if (SCTE35RegDescFound)
			{
				ArrayList<Descriptor> descriptors = null;

				if (descriptors == null)
					descriptors = s.descriptors.get(Descriptor.DESCRIPTOR_TAG_CUE_IDENTIFIER);

				if (descriptors == null)
					descriptors = s.descriptors.get(Descriptor.DESCRIPTOR_TAG_STREAM_IDENTIFIER);

				if (descriptors != null)
				{
					WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+".onPMT: Hit cue point PID: 0x"+Integer.toHexString(s.PID));

					if (!rtDePacketizerMPEGTS.containsPIDMonitorMap(s.PID))
					{
						rtDePacketizerMPEGTS.putPIDMonitorMap(s.PID, new MPEGTSMonitorCUE());
					}
				}
			}
		}
	}
}

```

The code example above as MPEG-TS listener and PID monitor for processing ad markers and inserting the onCUE AMF data event into the stream with the ad marker data.

The are some question i want to know about

- Where do put that code? do have to compile it become jar file?
- Do i still need to setup [Use generic Stream Target API to prepare Apple HLS streams for ad insertion (SCTE-35)](https://www.wowza.com/docs/how-to-use-generic-stream-target-api-to-prepare-apple-hls-streams-for-ad-insertion-scte-35) because our vendor just need to get the SCTE-35 markers.
- Do i need to put that code on all our wowza server?

note : our topology is camera --\> encoder --\> transcoder(ffmpeg) + wowza origin --\> edge server.

---

_[View the full topic](https://community.wowza.com/t/dynamic-ads-insertion/52629)._
