Send and receive events with Wowza GoCoder SDK for iOS

Use the Wowza GoCoder™ SDK for iOS to send events to a Wowza Streaming Engine™ media server software module and, optionally, to receive responses using the WOWZData family of classes.

There are three primary ways to use WOWZData classes:

  • Pass data, such as AMF metadata, in a stream through Wowza Streaming Engine using the RTMP or WOWZ protocol.
  • Pass data in a stream through Wowza Streaming Engine to other formats, such as Apple HLS.
  • Send events from a Wowza Streaming Engine server to a Wowza GoCoder SDK-based app.

Contents


Create a Wowza Streaming Engine module
Configure an app to send events and receive responses
More resources

Create a Wowza Streaming Engine module


If you're using a protocol other than WOWZ or RTMP to deliver a stream to the player or you're sending responses from Wowza Streaming Engine to a Wowza GoCoder SDK-based app, you must create a module in Wowza Streaming Engine.

The following example creates a module that listens to the incoming stream for events named onTextData. If it receives an onTextData event, it reverses the event's data payload and sends it back to the GoCoder SDK-based app using another onTextData event.

  class goCoderTestDataHandler implements IMediaStreamCallback	
  {
    // Called for each onTextData event in the stream
    public void onCallback(IMediaStream stream, RequestFunction function, AMFDataList params)
    {	
    
      getLogger().info(CLASSNAME+".onCallback stream: "+stream.getName());

      if (params.size() <= 1)
        return;
        
      if (params.get(0).getType() != AMFData.DATA_TYPE_STRING && params.get(1).getType() != AMFData.DATA_TYPE_OBJECT)
        return;
    
      String metaDataStr = params.getString(0);
      AMFDataObj amfDataObj = params.getObject(1);
        
      getLogger().info(CLASSNAME+".onCallback metaDtaStr string: "+metaDataStr);

      // look for specific named value
      if (!metaDataStr.equalsIgnoreCase("onTextData"))
        return;
    
      AMFDataItem textData = (AMFDataItem)amfDataObj.get("textData");
    
      if (textData == null)
        return;
    
      String textStr = textData.toString();
                                                        
      // modify data
      String reverseText = new StringBuilder(textStr).reverse().toString();
      amfDataObj.put("textData", reverseText);

      // send data back to client via onMetaData call
      stream.sendDirect("onTextData", amfDataObj);
      getLogger().info(CLASSNAME+".sendDirect[call]");

    }
  }

Configure an app to send events and receive responses


Next, add the capability to send events to and receive responses from the Wowza Streaming Engine module to the app.

Send a module-level event without a callback.

- (IBAction) didTapPingButtonNoresponse:(id)sender {
  /*
   This version sends a ping to the server and doesn't listen for a response. The module that implements onSendPingTimeNoResponse 
   must exist in order to process the event.
   */
  if (self.goCoder.status.state == WZStateRunning) {
    WOWZDataMap *params = [WOWZDataMap new];
      [params setString:@"01/23/1999:00:00:00" forKey:@"pingTime"];

    [self.goCoder sendDataEvent:WOWZDataScopeModule eventName:@"onSendPingTimeNoResponse" params:params callback:nil];
  }
}
}

Send a module-level event with a callback.

- (IBAction) didTapPingButton:(id)sender {
/*
  The ping button shows how to make a server function call; in this case, the call
  is onGetPingTime. The server module that implements onGetPingTime must exist in order to receive
  a callback.
*/
if (self.goCoder.status.state == WZStateRunning) {
    WOWZDataMap *params = [WOWZDataMap new];
    [self.goCoder sendDataEvent:WOWZDataScopeModule eventName:@"onGetPingTime" params:params callback:^(WOWZDataMap * _Nullable result, BOOL isError) {
        if (!isError && result) {
            WOWZDataItem *item = [result.data valueForKey:@"pingTime"];
            if (item) {
                NSLog(@"onGetPingTime result - ping time = %0.2f", item.doubleValue);
            }
        }
    }];
}
}

Receive a response.

/* Register the event you're listening for 
*/
[self.goCoder registerDataSink:self eventName:@"onTextData"];

…
/* Implement the data sink protocol to handle the event 
*/
- (void) onData:(WOWZDataEvent *)dataEvent {
    NSLog(@"Got data - %@", dataEvent.description);
}

Send a stream-level event without a callback.

- (void) orientationChanged:(NSNotification *)notification {

  /*
   Orientation change events demonstrate how to send stream data to the server.
  */

  WOWZDataMap *params = [WOWZDataMap new];
  UIDevice * device = notification.object;
  switch(device.orientation) {
    case UIDeviceOrientationPortrait:
      [params setString:@"portrait" forKey:@"deviceOrientation"];
      [params setInteger:0 forKey:@"deviceRotation"];
      break;

    case UIDeviceOrientationPortraitUpsideDown:
      [params setString:@"portrait" forKey:@"deviceOrientation"];
      [params setInteger:180 forKey:@"deviceRotation"];
      break;

    case UIDeviceOrientationLandscapeLeft:
      [params setString:@"landscape" forKey:@"deviceOrientation"];
      [params setInteger:90 forKey:@"deviceRotation"];
      break;

    case UIDeviceOrientationLandscapeRight:
      [params setString:@"landscape" forKey:@"deviceOrientation"];
      [params setInteger:270 forKey:@"deviceRotation"];
      break;

    default:
      break;
  };

  if (params.data.count > 0) {
    [self.goCoder sendDataEvent:WZDataScopeStream eventName:@"onDeviceOrientation" params:params callback:nil];
  }
}

More resources