Problem trying to choose transcoder template based on metadata.

Hello guys,

I would like to share an issue with you, and hope to get some help figuring out what’s going on.

So, in the project i’m working on, we’re using transcoder and we’re choosing the transcoder template based on metadata sent by encoders. To read metadata i’m setting a client listener to IMediaStream object once a stream is created:

public void onStreamCreate(IMediaStream stream) {
        stream.addClientListener(new MediaStreamActionNotify());
}

My MediaStreamActionNotify class is defined as follow

public class MediaStreamActionNotify implements IMediaStreamActionNotify2 {
	...
	@SuppressWarnings("unchecked")
    public void onMetaData(IMediaStream stream, AMFPacket metaDataPacket) {
        // get data sent by encoders.
        byte[] data = metaDataPacket.getData();
        AMFDataList metaDataList = new AMFDataList(data);
        ArrayList dataList = (ArrayList) metaDataList.getValue();
        for (int i = 0; i < dataList.size(); i++) {
            Object amfData = dataList.get(i);
            if (!(amfData instanceof AMFDataObj)) {
                continue;
            }
            AMFDataObj obj = (AMFDataObj) amfData;
            stream.getProperties().put("stream_width", obj.getInt("width"));
            stream.getProperties().put("stream_height", obj.getInt("height"));
            break;
        }
    }
    ...
}

So, onMetaData method is where i’m catching data sent by encoder, data like height is used to decide which template to use, this is handled in a TranscoderActionNotifier class

public class TranscoderActionNotifier extends
        LiveStreamTranscoderActionNotifyBase {
    ...
    @Override
    public void onInitBeforeLoadTemplate(LiveStreamTranscoder lsTranscoder) {
        IMediaStream stream = lsTranscoder.getStream();
        int height = stream.getProperties().getPropertyInt("stream_height", 0);
        ...
    }
    ...
}

By the way i’m using a web(flash-based) encoder, written in as3

private function netStreamStatusHandler(event:NetStatusEvent):void {
    switch (event.info.code) {
        case "NetStream.Publish.Start":
            stream.send("@setDataFrame", "onMetaData", broadcastInfo);
        ...
    }
}

So my issue is that on wowza server side the onMetaData method from MediaStreamActionNotify class sometimes is invoked after the onInitBeforeLoadTemplate method from TranscoderActionNotifier class, so the height is not set on time and we choose a wrong template for transcoder, this only happen when i sent stream from my web encoder, using FMLE or wirecast works ok, my question is somebody has got something similar? or what can i do to garantee this always works as expected.

Hi,

I think the problem you have is that you are starting to send the stream data too early. This is partly to do with the bad AS3 examples that are provided by Adobe.

The transcoder startup is triggered by the first lot of data that arrives on the stream so it is just a matter of making sure you send everything in the right order.

Most of the examples will create the NetStream, add a netStatus handler, attach the camera and mic and then publish the stream. In this scenario, The camera data will start sending as soon as the publish command is sent, before any acknowledgment comes back from the server. On the server side, we actually see the data arriving before we have a stream name to publish to so we have to buffer the data until we have the name. At the end of the publish event on the server, it sends back the NetStream.Publish.Start event. At this stage, the transcoder is well on it’s way to being running. This workflow makes it difficult to handle publishing problems.

Try changing your workflow to the following:

Create the NetStream

Add your NetStatus handler

publish the stream

In the NetStatus handler listen for NetStream.Publish.Start and then send you metadata packet before attaching the camera and mic. This should mean that your metadata should be the first packet to arrive.

This is basically how most of the commercial encoders work.

BTW, when you have finished publishing, you must set the NetStream object to null (or close the NetConnection) on the flash client end so that the transcoder will shut down properly.

Roger.