Embed cue points in live-record.

hey im new to wowza.

i have followed the link https://www.wowza.com/docs/how-to-inject-cue-points-or-metadata

to inject cue points . im able to read data passed from flex app to wowza media server . but im unable to inject cue points in live stream and record it. please help

im working on an application where i need to inject cue points in live stream .

when i change my power point slide i would like to inject a cue point with timestamp in my video and record the same video . i followed the link “https://www.wowza.com/forums/showthread.php?5151-adding-event-to-while-recording&p=129534#post129534” . im able to read data sent from the client publisher to the server . but i cannot send the data to the subscribing clients .

i have written nc.call for publishing client.

this is my server side code

public void setCaption(IClient client, RequestFunction function,AMFDataList params) {

String streamname = params.getString(PARAM1);

AMFDataObj obj = params.getObject(PARAM2);

String caption = obj.getString(“caption”);

String timestamp = obj.getString(“timestamp”);

System.out.println("STREAM-NAME " + streamname);

System.out.println("CAPTION " + caption);

System.out.println("TIMESTAMP " + timestamp);

try {

IMediaStream stream = client.getAppInstance().getStreams().getStream(str eamname);

//long cuePointTime=stream.getMaxTimecode()+ new java.util.Date().getTime();

//System.out.println("CuePointTime ::::::: "+cuePointTime);

AMFDataList amfList = new AMFDataList();

AMFDataMixedArray data = new AMFDataMixedArray();

data.put(“caption”, new AMFDataItem(caption));

data.put(“timestamp”, new AMFDataItem(timestamp));

// amfList.add(new AMFDataItem(“onCuePoint”));

amfList.add(new AMFDataItem(“setCaption”));

amfList.add(data);

String streamtype = stream.getClient().getAppInstance()

.getStreamType().substring(0, 11);

System.out.println("StreamType :::::: " + streamtype);

if (streamtype.equalsIgnoreCase(“live-record”)) {

stream.send(“setCaption”, data); // this works on the live

// stream.

System.out.println("data :::: " + data.toString());

}

byte[] dataData = amfList.serialize();

int size = dataData.length;

synchronized (stream) {

long timecode = Math.max(stream.getAudioTC(),stream.getVideoTC());

stream.setDataTC(timecode);

stream.setDataSize(size);

stream.addDataData(dataData, 0, size);

}

} catch (Exception e) {

e.printStackTrace();

}

getLogger().info("Caption: " + caption);

}

can u please lemme know where im gng wrong . thanking you in anticipation .

aiman kazi

aiman,

Use IMediaStream.sendDirect() instead of .send() to record the cueponts

Change this:

stream.send("setCaption", data); // this works on the live 

To this:

stream.sendDirect("setCaption", data); 

Richard

You are mixing legacy method with current method. Take at the setCaption method in this example

The example at bottom shows the legacy method. Follow the example at top.

Richard

The easiest way is try to read them in a Flash application. For example if you inject a very simple cuepoint named “testCuepoint” that included AMFDataMixedDataArray that contained one element named “text”, like this:

String streamname = "myStream";
String cuepointName =  "testCuepoint";
String cuepointText = "cuepoint text test test;
IMediaStream stream = client.getAppInstance().getStreams().getStream(streamname);
AMFDataMixedArray data = new AMFDataMixedArray();
data.put("text", new AMFDataItem(cuepointText));
stream.sendDirect(cuepointName, data);

… you can read that in the live stream or the recorded file (if you recorded mySteam) like this:

var nsPlayClientObj:Object = new Object();
nsPlay.client = nsPlayClientObj;
			
nsPlayClientObj.testCuepoint = function(obj:Object):void
{
	alert(obj.text);
}
nsPlay.play(streamname);

Richard

Actually, an easier way is to open the video file in a text editor and search for the name of the cuepoint. Following each occurence you will see the data for that cuepoint

Richard

thanks richard . i will try the code and reply …

here is my java code for wowza server project .

package com.wowza.example.module;

import com.wowza.wms.amf.*;

import com.wowza.wms.client.*;

import com.wowza.wms.module.*;

import com.wowza.wms.request.*;

import com.wowza.wms.stream.*;

public class ModuleInjectData1 extends ModuleBase {

public void setTag (IClient client, RequestFunction function, AMFDataList params)

{

String streamname = params.getString(PARAM1);

String caption = params.getString(PARAM2);

System.out.println("StreamName:: " +streamname);

System.out.println("Caption :: " +caption);

IMediaStream stream = client.getAppInstance().getStreams().getStream(streamname);

System.out.println("Stream :: " +streamname.toString()) ;

AMFDataList amfList = new AMFDataList();

AMFDataMixedArray data = new AMFDataMixedArray();

data.put(“caption”, new AMFDataItem(caption));

amfList.add(new AMFDataItem(“setCaption”));

amfList.add(data);

String streamtype = stream.getClient().getAppInstance().getStreamType();

System.out.println("Stream Type :: " + streamtype);

if (streamtype.equals(“live”))

{

stream.send(“setCaption”, caption); // this works on the live stream.

stream.sendDirect(“setCaption”, caption);

System.out.println("Live Record Caption :: " + caption);

}

byte[] dataData = amfList.serialize();

int size = dataData.length;

synchronized(stream)

{

long timecode = Math.max(stream.getAudioTC(), stream.getVideoTC());

System.out.println("timecode :: " + timecode);

stream.setDataTC(timecode);

stream.setDataSize(size);

stream.addDataData(dataData, 0, size);

stream.sendDirect(“setCaption”, caption);

}

// System.out.println(“Before Thread…”);

// try{

//

// Thread.sleep(1000);

// }catch(Exception e){

// e.printStackTrace();

// }

// System.out.println(“After Thread…”);

//

injectMetaData(client , function , params);

getLogger().info("Caption: " + caption);

}

public void injectMetaData(IClient client, RequestFunction function, AMFDataList params)

{

System.out.println("Inside injectMetaData ::: AIMAN ");

String streamName = params.getString(PARAM1);

String data = params.getString(PARAM2);

IMediaStream stream = client.getAppInstance().getStreams().getStream(streamName);

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();

System.out.println(“dataData ::” +dataData.toString());

int size = dataData.length;

System.out.println("size :: " + size);

long timecode = Math.max(stream.getAudioTC(), stream.getVideoTC());

System.out.println(“timecode ::” +timecode);

stream.setDataTC(timecode);

stream.setDataSize(size);

stream.startDataPacket();

stream.addDataData(dataData, 0, size);

stream.sendDirect(“streaming”, amfList );

}

}

}

}

as3 code from flex app

protected function sendData_clickHandler(event:MouseEvent):void

{

// TODO Auto-generated method stub

_nc.call(“setTag”,null,“livefeed”,“hello room”,“eng”,“0”);

}

private function streaming(obj:Object):void

{

var a:String = obj.toString();

textbox.text = a + “\n” ;

}

i get error message . i have used stream.sendDirect();

please let me know where im gng wrong.

my error in java :

INFO session connect-pending 127.0.0.1 -

INFO session connect 127.0.0.1 -

INFO stream create - -

INFO stream play livefeed -

StreamName:: livefeed

Caption :: hello room

Stream :: livefeed

Stream Type :: live

Live Record Caption :: hello room

timecode :: 8508

Inside injectMetaData ::: AIMAN

dataData ::[B@6b543e44

size :: 74

timecode ::8508

WARN server comment - LiveReceiver.startDataPacket[test/definst/livefeed]: Data packet sync issue.

ERROR server comment - addDataA[this.size:26 this.dataA.length:26 this.startDataLoc:0 this.dataLoc:0 data.length:74 offset:0 size:74 missing:26 ]: java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException

INFO server comment - Caption: hello room

WARN server comment - LiveReceiver.startDataPacket[test/definst/livefeed]: Data packet sync issue.

at java.lang.System.arraycopy(Native Method)

at com.wowza.wms.amf.AMFPacket.addData(Unknown Source)

at com.wowza.wms.stream.live.LiveReceiver.addDataData(Unknown Source)

at com.wowza.wms.stream.live.MediaStreamLive.addDataData(Unknown Source)

at com.wowza.example.module.ModuleInjectData1.injectMetaData(ModuleInjectData1.java:94)

at com.wowza.example.module.ModuleInjectData1.setTag(ModuleInjectData1.java:59)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at com.wowza.wms.module.ModuleFunction.invoke(Unknown Source)

at com.wowza.wms.module.ModuleFunctions.invoke(Unknown Source)

at com.wowza.wms.request.RequestProcessFunctions.processFunctions(Unknown Source)

at com.wowza.wms.request.RequestProcessData.flushFunction(Unknown Source)

at com.wowza.wms.request.RequestProcessData.processNextRequest(Unknown Source)

at com.wowza.wms.client.ClientWorker.processNextReq(Unknown Source)

at com.wowza.wms.request.RTMPRequestAdapter.service(Unknown Source)

at com.wowza.wms.server.ServerHandler.a(Unknown Source)

at com.wowza.wms.server.ServerHandler.a(Unknown Source)

at com.wowza.wms.server.ServerHandler.messageReceived(Unknown Source)

at com.wowza.wms.server.ServerHandlerThreadedSession.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

INFO stream stop livefeed -

INFO stream destroy livefeed -

INFO session disconnect 2131692034 -

how will i come to know if i have embedded cue points in my live-record video file