/**
  * Send VOD seek control message
  *
  * @param msgIn Message input
  * @param position New timestamp to play from
  */
 private void sendVODSeekCM(IMessageInput msgIn, int position) {
   OOBControlMessage oobCtrlMsg = new OOBControlMessage();
   oobCtrlMsg.setTarget(ISeekableProvider.KEY);
   oobCtrlMsg.setServiceName("seek");
   Map<String, Object> paramMap = new HashMap<>(1);
   paramMap.put("position", Integer.valueOf(position));
   oobCtrlMsg.setServiceParamMap(paramMap);
   msgIn.sendOOBControlMessage(this, oobCtrlMsg);
   // Reset properties
   vodStartTS = 0;
   serverStartTS = System.currentTimeMillis();
   if (nextRTMPMessage != null) {
     try {
       pushMessage(nextRTMPMessage);
     } catch (IOException err) {
       log.error("Error while sending message.", err);
     }
     nextRTMPMessage.getBody().release();
     nextRTMPMessage = null;
   }
   ResetMessage reset = new ResetMessage();
   try {
     pushMessage(reset);
   } catch (IOException err) {
     log.error("Error while sending message.", err);
   }
   scheduleNextMessage();
 }
 /**
  * Send VOD initialization control message
  *
  * @param msgIn Message input
  * @param start Start timestamp
  */
 private void sendVODInitCM(IMessageInput msgIn, int start) {
   if (msgIn != null) {
     // Create new out-of-band control message
     OOBControlMessage oobCtrlMsg = new OOBControlMessage();
     // Set passive type
     oobCtrlMsg.setTarget(IPassive.KEY);
     // Set service name of init
     oobCtrlMsg.setServiceName("init");
     // Create map for parameters
     Map<String, Object> paramMap = new HashMap<>(1);
     // Put start timestamp into Map of params
     paramMap.put("startTS", start);
     // Attach to OOB control message and send it
     oobCtrlMsg.setServiceParamMap(paramMap);
     msgIn.sendOOBControlMessage(this, oobCtrlMsg);
   }
 }
 /** {@inheritDoc} */
 public void onOOBControlMessage(
     IMessageComponent source, IPipe pipe, OOBControlMessage oobCtrlMsg) {
   if (IPassive.KEY.equals(oobCtrlMsg.getTarget())) {
     if (oobCtrlMsg.getServiceName().equals("init")) {
       Integer startTS = (Integer) oobCtrlMsg.getServiceParamMap().get("startTS");
       setStart(startTS);
     }
   } else if (ISeekableProvider.KEY.equals(oobCtrlMsg.getTarget())) {
     if (oobCtrlMsg.getServiceName().equals("seek")) {
       Integer position = (Integer) oobCtrlMsg.getServiceParamMap().get("position");
       int seekPos = seek(position.intValue());
       // Return position we seeked to
       oobCtrlMsg.setResult(seekPos);
     }
   } else if (IStreamTypeAwareProvider.KEY.equals(oobCtrlMsg.getTarget())) {
     if (oobCtrlMsg.getServiceName().equals("hasVideo")) {
       oobCtrlMsg.setResult(hasVideo());
     }
   }
 }