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
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.