# Can't get live captioning and/or metadata working

**URL:** <https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622>\
**Category:** Wowza Streaming Engine\
**Created:** [August 12, 2014, 10:16am UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622 "2014-08-12T10:16:04Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_McHugh](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@James\_McHugh](https://community.wowza.com/u/James_McHugh)\
**Post date:** [August 12, 2014, 10:16am UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622/1 "2014-08-12T10:16:04Z")

</div>

We are trying to setup a scenario where we use Wowza to stream live video to clients, but inject captioning and metadata into the stream from an external source at various points in time. As such I have implemented the following module following guides found here:

```auto
public class CaptioningInjectionModule extends HTTProvider2Base {
	private IServer server;
	public void onServerInit(IServer server) {
		this.server = server;
	}
	@Override
	public void onHTTPRequest(IVHost ivHost, IHTTPRequest ihttpRequest, IHTTPResponse ihttpResponse) {
		String appName = ihttpRequest.getParameter("appName");
		String appInstanceName = ihttpRequest.getParameter("appInstanceName");
		appInstanceName = appInstanceName == null ? "_definst_" : appInstanceName;
		String streamName = ihttpRequest.getParameter("streamName");
		BufferedReader reader = new BufferedReader(new InputStreamReader(ihttpRequest.getInputStream()));
		String text = null;
		try {
			text = reader.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
		String language = ihttpRequest.getParameter("language");
		String trackId = ihttpRequest.getParameter("trackId");
		IMediaStream stream = ivHost.getApplication(appName).getAppInstance(appInstanceName).getStreams()
				.getStream(streamName);
		setCaption(stream, text, language, trackId);
	}
	private void setCaption(final IMediaStream stream, final String text, final String language, final String trackId) {
		if (stream != null) {
			AMFDataObj data = new AMFDataObj();
			data.put("text", new AMFDataItem(text));
			data.put("language", new AMFDataItem(language));
			data.put("trackid", new AMFDataItem(trackId));
			stream.sendDirect("onTextData", data);
			((MediaStream) stream).processSendDirectMessages();
		}
	}
}

```

and

```auto
public class MetadataInjectionModule extends HTTProvider2Base {
	private IServer server;
	public void onServerInit(IServer server) {
		this.server = server;
	}
	@Override
	public void onHTTPRequest(IVHost ivHost, IHTTPRequest ihttpRequest, IHTTPResponse ihttpResponse) {
		String appName = ihttpRequest.getParameter("appName");
		String appInstanceName = ihttpRequest.getParameter("appInstanceName");
		appInstanceName = appInstanceName == null ? "_definst_" : appInstanceName;
		String streamName = ihttpRequest.getParameter("streamName");
		BufferedReader reader = new BufferedReader(new InputStreamReader(ihttpRequest.getInputStream()));
		StringBuilder data = new StringBuilder();
		try {
			String line;
			while((line = reader.readLine()) != null) {
				data.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		IMediaStream stream = ivHost.getApplication(appName).getAppInstance(appInstanceName).getStreams()
				.getStream(streamName);
		injectMetadata(stream, data.toString());
	}
	private void injectMetadata(final IMediaStream stream, final String data) {
		if (stream != null) {
			AMFDataList amfList = new AMFDataList();
			amfList.add(new AMFDataItem("@setDataFrame"));
			amfList.add(new AMFDataItem("onMetaData"));
			AMFDataMixedArray metaData = new AMFDataMixedArray();
			metaData.put("param1", data);
			metaData.put("param2", new AMFDataItem("data2"));
			amfList.add(metaData);
			synchronized (stream) {
				byte[] dataData = amfList.serialize();
				int size = dataData.length;
				long timecode = Math.max(stream.getAudioTC(), stream.getVideoTC());
				stream.setDataTC(timecode);
				stream.setDataSize(size);
				stream.startDataPacket();
				stream.addDataData(dataData, 0, size);
			}
		}
	}
}

```

and set these up in my VHost.xml file:

```auto
<HTTPProvider>
	<BaseClass>gamesys.wowza.server.modules.CaptioningInjectionModule</BaseClass>
	<RequestFilters>caption*</RequestFilters>
	<AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>
<HTTPProvider>
	<BaseClass>gamesys.wowza.server.modules.MetadataInjectionModule</BaseClass>
	<RequestFilters>metadata*</RequestFilters>
	<AuthenticationMethod>none</AuthenticationMethod>
</HTTPProvider>

```

Both endpoints work and I don’t see any exceptions in the Wowza server logs. My question is how can I get hold of this data on the client. I have tried various players like flowplayer and jwplayer by binding to their onMetadata or onCuepoint etc. events but I never seem to get anything come through. Is there a stage in the middle I am missing?

---

<div class="post-metadata">

**Author:** ![Paul\_Shields](https://sea2.discourse-cdn.com/flex002/user_avatar/community.wowza.com/paul_shields/32/390_2.png) [@Paul\_Shields](https://community.wowza.com/u/Paul_Shields)\
**Post date:** [August 12, 2014, 12:21pm UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622/2 "2014-08-12T12:21:33Z")

</div>

Hi,

Apologies if you have seen this already or if it’s not directly relevant but we do have [an article](https://www.wowza.com/docs/how-to-configure-closed-captioning-for-live-streaming) covering live closed captioning which also includes a [sample module](https://www.wowza.com/downloads/forums/closedcaptionlive/ClosedCaptionLive.zip) including source for writing live captions using AMF onTextData events, which can be used with Flowplayer, JW Player etc.

Paul

---

<div class="post-metadata">

**Author:** ![Paul\_Shields](https://sea2.discourse-cdn.com/flex002/user_avatar/community.wowza.com/paul_shields/32/390_2.png) [@Paul\_Shields](https://community.wowza.com/u/Paul_Shields)\
**Post date:** [August 12, 2014, 12:57pm UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622/3 "2014-08-12T12:57:45Z")

</div>

Hi James,

Good to hear you’re progressing. We’ve [the following article](https://www.wowza.com/docs/how-to-inject-cue-points-or-metadata) covering injecting metadata into RTMP (or HLS if converted to id3 tags). There may be others more relevant to you. I’d also suggest a look at our [articles list](https://www.wowza.com/forums/content.php) or search the forum. I think these questions do pop up now and again.

Paul

---

<div class="post-metadata">

**Author:** ![James\_McHugh](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@James\_McHugh](https://community.wowza.com/u/James_McHugh)\
**Post date:** [August 12, 2014, 12:26pm UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622/4 "2014-08-12T12:26:55Z")

</div>

> Hi,
> 
> Apologies if you have seen this already or if it’s not directly relevant but we do have [an article](https://www.wowza.com/docs/how-to-configure-closed-captioning-for-live-streaming) covering live closed captioning which also includes a [sample module](https://www.wowza.com/downloads/forums/closedcaptionlive/ClosedCaptionLive.zip) including source for writing live captions using AMF onTextData events, which can be used with Flowplayer, JW Player etc.
> 
> Paul

Thanks Paul,

This section: [https://www.wowza.com/docs/how-to-configure-closed-captioning-for-live-streaming#ontextdata](https://www.wowza.com/docs/how-to-configure-closed-captioning-for-live-streaming#ontextdata) resolved my issue. Are there similar sample modules etc. for streaming live metadata?

---

<div class="post-metadata">

**Author:** ![James\_McHugh](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@James\_McHugh](https://community.wowza.com/u/James_McHugh)\
**Post date:** [August 12, 2014, 1:49pm UTC](https://community.wowza.com/t/cant-get-live-captioning-and-or-metadata-working/43622/5 "2014-08-12T13:49:10Z")

</div>

Hi Paul,

I did have a read of the article you posted. I am just getting confused as some of the articles seem to be contradictory (although maybe it is my lack of understanding) i.e.

This article suggests that captions be injected by calling stream.sendDirect(“onTextData”…) and metadata be injected by calling stream.addDataData(…)

[https://www.wowza.com/docs/how-to-inject-cue-points-or-metadata](https://www.wowza.com/docs/how-to-inject-cue-points-or-metadata)

But then this article is talking about converting “onTextData” events to ID3 metadata, even though the prior one says to use this for captioning:

[https://www.wowza.com/docs/how-to-convert-ontextdata-events-in-a-live-or-vod-stream-to-timed-events-id3-tags-in-an-apple-hls-stream](https://www.wowza.com/docs/how-to-convert-ontextdata-events-in-a-live-or-vod-stream-to-timed-events-id3-tags-in-an-apple-hls-stream)

Maybe there is more than one way to do this but as a novice its quite confusing.
