Send and receive events with Wowza GoCoder SDK for Android

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

There are three primary ways to use the WOWZData classes. The steps required to implement each vary. The three primary uses are:

  • 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 server module
Configure an app to send events and receive responses
Add metadata to outgoing streams
More resources

Create a Wowza Streaming Engine server 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 back to a Wowza GoCoder SDK-based app, you must create a module in Wowza Streaming Engine.

The following module example 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.

The following example sends a module-scope event without a callback:

public boolean onTouchEvent(MotionEvent event) {
    //
    // Sending an event to a server module method (without a result callback)
    //
    // If a broadcast is active and the user presses on the screen,
    // send a client data event to the server with the coordinates
    // and time
    //
    if (event.getAction() == MotionEvent.ACTION_DOWN &&
            mWZBroadcast != null && mWZBroadcast.getStatus().isRunning()) {

        WOWZDataMap dataEventParams = new WOWZDataMap();
        dataEventParams.put("x", event.getX());
        dataEventParams.put("y", event.getY());
        dataEventParams.put("occurred", event.getEventTime());

        mWZBroadcast.sendDataEvent(WOWZDataScope.MODULE, "onScreenPress", dataEventParams);
        Toast.makeText(this, "onScreenPress() event sent to server module", Toast.LENGTH_LONG).show();

        return true;
    } else
        return super.onTouchEvent(event);
}

The following example sends a module-scope event with a callback:

public void onPing(View v) {
    //
    // Sending an event to a server module method (with a result callback)
    //
    if (mWZBroadcast != null && mWZBroadcast.getStatus().isRunning()) {
        mBtnPing.setEnabled(false);

        mWZBroadcast.sendDataEvent(WOWZDataScope.MODULE, "onGetPingTime", new WOWZDataEvent.ResultCallback() {
            @Override
            public void onWOWZDataEventResult(final WOWZDataMap resultParams, boolean isError) {
                if(resultParams!=null) {
                    final String result = isError ? "Ping attempt failed (" + resultParams.get("code").toString() + ")" : "Ping time: " + resultParams.get("pingTime") + "ms";
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(EventActivity.this, result, Toast.LENGTH_LONG).show();
                            mBtnPing.setEnabled(true);
                        }
                    });
                }
            }
        });
    }
}

The following example receives a response:

mWZBroadcast.registerDataEventListener("onClientConnected", new WOWZDataEvent.EventListener() {
    @Override
    public WOWZDataMap onWOWZDataEvent(String eventName, WOWZDataMap eventParams) {
        WZLog.info(TAG, "onClientConnected data event received:\n" + eventParams.toString(true));

        final String result = "A client connected with the IP address " + eventParams.get("clientIp");
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(EventActivity.this, result, Toast.LENGTH_LONG).show();
            }
        });

        // Return a function result back to the original Wowza Streaming Engine
        // function call request
        WOWZDataMap functionResult = new WOWZDataMap();
        functionResult.put("greeting", "Hello New Client!");

        return functionResult;
    }
});

The following example sends a stream-scope event without a callback:

 public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //
    // Sending an event to all stream subscribers
    //
    // If a broadcast is active and the device orientation changes,
    // send a stream data event containing the device orientation
    // and rotation
    //
    if (mWZBroadcast != null && mWZBroadcast.getStatus().isRunning()) {

        WOWZDataMap dataEventParams = new WOWZDataMap();
        dataEventParams.put("deviceOrientation",
                newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? "landscape" : "portrait");

        Display display = ((WindowManager)
                getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int displayRotation = display.getRotation();

        switch (displayRotation) {
            case Surface.ROTATION_0:
                dataEventParams.put("deviceRotation", 0);
                break;
            case Surface.ROTATION_90:
                dataEventParams.put("deviceRotation", 90);
                break;
            case Surface.ROTATION_180:
                dataEventParams.put("deviceRotation", 180);
                break;
            case Surface.ROTATION_270:
                dataEventParams.put("deviceRotation", 270);
                break;
        }

        mWZBroadcast.sendDataEvent(WOWZDataScope.STREAM, "onDeviceOrientation", dataEventParams);
        Toast.makeText(this, "onDeviceOrientation() event sent to stream subscribers", Toast.LENGTH_LONG).show();
    }
}

Add metadata to outgoing streams


Metadata events can be sent and received by using the setMetadata() method of the WOWZStreamConfig class. The following example adds metadata properties to an outgoing stream:

WOWZDataMap streamMetadata = new WOWZDataMap();
streamMetadata.put("appName", new WOWZDataItem("Wowza GoCoder"));
streamMetadata.put("appVersion", new WOWZDataItem("1.1"));
streamMetadata.put("platform", new WOWZDataItem("android"));
streamMetadata.put("platformVersion", new WOWZDataItem(6.1));
streamMetadata.put("deviceBrand", new WOWZDataItem("samsung"));
streamMetadata.put("deviceModel", new WOWZDataItem("galaxy s5"));
mWZBroadcastConfig.setStreamMetadata(streamMetadata);

More resources



If you're having problems or want to discuss this article, post in our forum.