Transcoder API

Is there a way to specify which qualities to encode on a per stream level? I was looking through the java docs and I’m not quite sure how to do this.

Yes, create a transcoder template in /transcoder/templates named myStream.xml (make it copy of transrate.xml), then enable transcoder in an Application, then publish a stream named “myStream” to that application, then /transcoder/templates/myStream.xml will be the template that is used. This is configured in the Applicationl.xml /Transcoder /Templates using environment variable ${SourceStreamName}

<Templates>${SourceStreamName}.xml,transrate.xml</Templates>

With the above in place, any time there is a template with the name of the stream that is being published, it will be the one that is used

Richard

Take a look at the ILiveStreamTranscoderNotify interface. You can register a listener with the an appInstance interface. Then from there you can register a ILiveStreamTranscoderActionNotify listener to get more detailed information during the live stream transcoder life cycle. If you listen for the event:

onInitAfterLoadTemplate(LiveStreamTranscoder liveStreamTranscoder);

this happens just after the template is loaded. You should be able to then manipulate the transcoding instructions through the TranscoderStream object.

We will most likely document this interface in more detail at a later time. This is all we have at this time.

Charlie

Here is more complete code:

package com.wowza.wms.plugin.test.module;
import java.util.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.stream.livetranscoder.*;
import com.wowza.wms.transcoder.model.*;
import com.wowza.wms.media.model.*;
import com.wowza.wms.module.*;
import com.wowza.wms.application.*;
public class ModuleLiveStreamTranscoderActionNotifyExample extends ModuleBase
{
	IApplicationInstance appInstance = null;
	
	class MyTranscoderCreateNotifier implements ILiveStreamTranscoderNotify
	{
		@Override
		public void onLiveStreamTranscoderCreate(ILiveStreamTranscoder liveStreamTranscoder, IMediaStream stream)
		{
			getLogger().info("ModuleLiveStreamTranscoderActionNotifyExample#MyTranscoderCreateNotifier.onLiveStreamTranscoderCreate["+appInstance.getContextStr()+"]: "+stream.getName());
			((LiveStreamTranscoder)liveStreamTranscoder).addActionListener(new MyTranscoderActionNotifier());
		}
		@Override
		public void onLiveStreamTranscoderDestroy(ILiveStreamTranscoder liveStreamTranscoder, IMediaStream stream)
		{
		}
		@Override
		public void onLiveStreamTranscoderInit(ILiveStreamTranscoder liveStreamTranscoder, IMediaStream stream)
		{
		}	
	}
	
	class MyTranscoderActionNotifier implements ILiveStreamTranscoderActionNotify
	{
		@Override
		public void onInitStart(LiveStreamTranscoder liveStreamTranscoder, String streamName, String transcoderName, IApplicationInstance appInstance, LiveStreamTranscoderItem liveStreamTranscoderItem)
		{
		}
		@Override
		public void onInitBeforeLoadTemplate(LiveStreamTranscoder liveStreamTranscoder)
		{
		}
		@Override
		public void onInitAfterLoadTemplate(LiveStreamTranscoder liveStreamTranscoder)
		{
			getLogger().info("ModuleLiveStreamTranscoderActionNotifyExample#MyTranscoderActionNotifier.onInitAfterLoadTemplate["+appInstance.getContextStr()+"]");
			
			while(true)
			{
				TranscoderStream transcoderStream = liveStreamTranscoder.getTranscodingStream();
				if (transcoderStream == null)
					break;
				
				List<TranscoderStreamDestination> destinations = transcoderStream.getDestinations();
				Iterator<TranscoderStreamDestination> iter = destinations.iterator();
				while(iter.hasNext())
				{
					TranscoderStreamDestination destination = iter.next();
					getLogger().info("ModuleLiveStreamTranscoderActionNotifyExample#MyTranscoderActionNotifier.onInitAfterLoadTemplate["+appInstance.getContextStr()+"] destination:"+destination.getName()+" enable:"+destination.isEnable());
				}
				break;
			}
			
		}
		@Override
		public void onInitStop(LiveStreamTranscoder liveStreamTranscoder)
		{
		}
		@Override
		public void onCalculateSourceVideoBitrate(LiveStreamTranscoder liveStreamTranscoder, long bitrate)
		{
		}
		@Override
		public void onCalculateSourceAudioBitrate(LiveStreamTranscoder liveStreamTranscoder, long bitrate)
		{
		}
		@Override
		public void onSessionDestinationCreate(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionDestination sessionDestination)
		{
		}
		@Override
		public void onSessionVideoEncodeCreate(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionVideoEncode sessionVideoEncode)
		{
		}
		@Override
		public void onSessionAudioEncodeCreate(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionAudioEncode sessionAudioEncode)
		{
		}
		@Override
		public void onSessionDataEncodeCreate(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionDataEncode sessionDataEncode)
		{
		}
		@Override
		public void onSessionVideoEncodeInit(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionVideoEncode sessionVideoEncode)
		{
		}
		@Override
		public void onSessionAudioEncodeInit(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionAudioEncode sessionAudioEncode)
		{
		}
		@Override
		public void onSessionDataEncodeInit(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionDataEncode sessionDataEncode)
		{
		}
		@Override
		public void onSessionVideoEncodeSetup(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionVideoEncode sessionVideoEncode)
		{
		}
		@Override
		public void onSessionAudioEncodeSetup(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionAudioEncode sessionAudioEncode)
		{
		}
		@Override
		public void onSessionVideoEncodeCodecInfo(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionVideoEncode sessionVideoEncode, MediaCodecInfoVideo codecInfoVideo)
		{
		}
		@Override
		public void onSessionAudioEncodeCodecInfo(LiveStreamTranscoder liveStreamTranscoder, TranscoderSessionAudioEncode sessionAudioEncode, MediaCodecInfoAudio codecInfoAudio)
		{
		}
		@Override
		public void onSessionVideoDecodeCodecInfo(LiveStreamTranscoder liveStreamTranscoder, MediaCodecInfoVideo codecInfoVideo)
		{
		}
		@Override
		public void onSessionAudioDecodeCodecInfo(LiveStreamTranscoder liveStreamTranscoder, MediaCodecInfoAudio codecInfoAudio)
		{
		}
		@Override
		public void onRegisterStreamNameGroup(LiveStreamTranscoder liveStreamTranscoder, TranscoderStreamNameGroup streamNameGroup)
		{
		}
		@Override
		public void onUnregisterStreamNameGroup(LiveStreamTranscoder liveStreamTranscoder, TranscoderStreamNameGroup streamNameGroup)
		{
		}
		@Override
		public void onShutdownStart(LiveStreamTranscoder liveStreamTranscoder)
		{
		}
		@Override
		public void onShutdownStop(LiveStreamTranscoder liveStreamTranscoder)
		{
		}
		@Override
		public void onResetStream(LiveStreamTranscoder liveStreamTranscoder)
		{
		}
		
	}
	
	public void onAppStart(IApplicationInstance appInstance)
	{
		this.appInstance = appInstance;
		
		appInstance.addLiveStreamTranscoderListener(new MyTranscoderCreateNotifier());
		
		getLogger().info("ModuleLiveStreamTranscoderActionNotifyExample.onAppStart["+appInstance.getContextStr()+"]");
	}
}

This code does require a patch. I messed up and a few of these methods were not marked as public. I will post a patch that fixes this later today or tomorrow.

Charlie

Here is the patch that should enable the above code:

WowzaMediaServer3.0.3-patch3.zip

Charlie

Take a look at this article:

https://www.wowza.com/docs/how-to-control-which-streams-get-transcoded-using-server-side-api

Richard

I’m not sure at this time how to do that, or if there is an API that can.

Richard

I don’t want to have a per-stream xml file. I want to be able to do it in the code ala say querying a database and setting variables for the stream on a per stream basis. Specifying this stream needs to be encoded in these specific qualities while another stream needs to be encoded in different qualities.

I’ve already seen that tutorial but that allow me to specify the individual qualities just whether to enable or disable the transcoder on the stream as a whole.

Thanks for the info Charlie. One last question. I’ve looked through the docs and I’m unsure of when I should register the ILiveStreamTranscoderActionNotify. I understand I need to add it to LiveStreamTranscoder but I can’t seem to figure out how to access it since the stream object only allows access to ILiveStreamTranscoder.

Thank you very much for the sample code and patch.