software developer

What Components Does the Android SDK Have?

In this article we’re going to review all the components that OpenSDK for Android offers, both from a front-end and a back-end perspective.

Please note that we do not provide the media streaming / CDN service. You need to subscribe to a RTMP media hosting service, like MUX.

OpenSDK Main Interface

The main interface is responsible for the initialization and configuration of the Android RMTP SDK. It provides information about the available features.

Important: Before using the publisher, the SDK must be properly initialized and configured.

Handlers and Listeners

Advice: To provide the best user experience, you must treat each state differently as per your application logic and desired UX.

RtmpHandler.RtmpListener

The rtmp listener interface represents all the states of the RTMP connection. It allows you to get notified about the latest connection state. You must create a new handler and implement the Rtmp Listener interface in your activity, then pass it over in the constructor as follows:

mStreamaxiaPublisher.setRtmpHandler(new RtmpHandler(this));

To provide the best user experience, you must treat each state differently.

The states are as follow:

  • onRtmpAuthenticating
  • onRtmpConnecting
  • onRtmpConnected
  • onRtmpVideoStreaming
  • onRtmpAudioStreaming
  • onRtmpStopped
  • onRtmpDisconnected
  • onRtmpOutputFps
  • onRtmpVideoBitrate
  • onRtmpAudioBitrate
  • onRtmpIOException
  • onRtmpIllegalArgumentException
  • onRtmpIllegalStateException
  • onRtmpSocketException

RecordHandler.RecordListener

The record listener interface represents all the states of the MP4 local recording/saving. It allows you to get notified about the state of the recording. You must create a new handler and implement the Rtmp Listener interface in your activity, then pass it over in the constructor as follows:

mStreamaxiaPublisher.setRecordEventHandler(new RecordHandler(this));        

The states are as follow:

  • onRecordPause
  • onRecordResume
  • onRecordStarted
  • onRecordFinished
  • onRecordIllegalArgumentException
  • onRecordIOException

EncoderHandler.EncoderListener

The network handler interface represents all the states of the network events that occur during the streaming process. You must create a new handler and implement the Encoder Listener interface in your activity, then pass it over in the constructor as follows:

mStreamaxiaPublisher.setEncoderHandler(new EncoderHandler(this));

The states are as follow:

  • onNetworkResume
  • onNetworkWeak
  • onEncoderIllegalArgumentException

 

 

Android RTMP OpenSDK Project Setup

  1. Open an existing project or create a new one.
  2. Add the .aar file provided, as a module to the main project
  3. Add the license.dat file in the /assets folder of the main project.

Initialize the SDK Main Interface

To initialize the SDK, you need to make sure that the license file is added to the assets folder.

Create a new StreamaxiaPublisher object as follows:

mStreamaxiaPublisher = new StreamaxiaPublisher(mCameraView, this);


The constructor needs the following parameters:

  1. The CameraView – a view where the frames from the camera are rendered
  2. The context – the activity’s context NOT the application context

In the activity XML file, you will need to create a CameraView. A view that will be used to render the actual frames that come from the camera.

<com.streamaxia.android.CameraPreview
     android:id="@+id/preview"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentBottom="true"
     android:layout_alignParentEnd="true"
     android:layout_alignParentLeft="true"
     android:layout_alignParentRight="true"
     android:layout_alignParentStart="true"
     android:layout_alignParentTop="true"
     android:adjustViewBounds="true"
     android:keepScreenOn="true"/>

Reference the view in your activity, to pass it over to the constructor of the main interface.

@BindView(R.id.preview)
 CameraPreview mCameraView;

or

mCameraView = (CameraView) findViewById(R.id.preview);

Handlers and Listeners set up

Some of the listeners will deliver a specific message, letting you know what is happening.

@Override
public void onRtmpConnecting(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

RtmpHandler.RtmpListener

@Override
public void onRtmpConnecting(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

@Override
public void onRtmpConnected(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

@Override
public void onRtmpVideoStreaming() {
    Log.i(TAG“Video Streaming”);
}

@Override
public void onRtmpAudioStreaming() {
    Log.i(TAG“Audio Streaming”);
}

@Override
public void onRtmpStopped() {
    Toast.makeText(getApplicationContext()“Stopped”Toast.LENGTH_SHORT).show();
}

@Override
public void onRtmpDisconnected() {
    Toast.makeText(getApplicationContext()“Disconnected”Toast.LENGTH_SHORT).show();
}

@Override
public void onRtmpVideoFpsChanged(double fps) {
    Log.i(TAGString.format(“Output Fps: %f”fps));
}

@Override
public void onRtmpVideoBitrateChanged(double bitrate) {
    int rate = (int) bitrate;
    if (rate / 1000 0) {
        Log.i(TAGString.format(“Video bitrate: %f kbps”bitrate / 1000));
    else {
        Log.i(TAGString.format(“Video bitrate: %d bps”rate));
    }
}

@Override
public void onRtmpAudioBitrateChanged(double bitrate) {
    int rate = (int) bitrate;
    if (rate / 1000 0) {
        Log.i(TAGString.format(“Audio bitrate: %f kbps”bitrate / 1000));
    else {
        Log.i(TAGString.format(“Audio bitrate: %d bps”rate));
    }
}

@Override
public void onRtmpSocketException(SocketException e) {
    handleException(e);
}

@Override
public void onRtmpIOException(IOException e) {
    handleException(e);
}

@Override
public void onRtmpIllegalArgumentException(IllegalArgumentException e) {
    handleException(e);
}

@Override
public void onRtmpIllegalStateException(IllegalStateException e) {
    handleException(e);
}

@Override
public void onRtmpAuthenticationg(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

Recording Handlers

@Override
public void onRecordPause() {
    Toast.makeText(getApplicationContext()“Record pause”Toast.LENGTH_SHORT).show();
}

@Override
public void onRecordResume() {
    Toast.makeText(getApplicationContext()“Record resume”Toast.LENGTH_SHORT).show();
}

@Override
public void onRecordStarted(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

@Override
public void onRecordFinished(String msg) {
    Toast.makeText(getApplicationContext()msgToast.LENGTH_SHORT).show();
}

@Override
public void onRecordIllegalArgumentException(IllegalArgumentException e) {
    handleException(e);
}

@Override
public void onRecordIOException(IOException e) {
    handleException(e);
}

Network Handlers

@Override
public void onNetworkWeak() {
    Toast.makeText(getApplicationContext()“Network weak”Toast.LENGTH_SHORT).show();
}

@Override
public void onNetworkResume() {
    Toast.makeText(getApplicationContext()“Network resume”Toast.LENGTH_SHORT).show();
}

@Override
public void onEncodeIllegalArgumentException(IllegalArgumentException e) {
    handleException(e);
}

Example of Exception handling

Sometimes there may be some exception that you will need to be handled. Below you will find a way of how the demo app handles an exception.

Note: Your feedback regarding current issues and possible improvements is priceless! Help improve OpenSDK by submitting your feedback to [email protected]

private void handleException(Exception e) {
    try {
        Toast.makeText(getApplicationContext()e.getMessage()Toast.LENGTH_SHORT).show();
        mStreamaxiaPublisher.stopPublish();
        mStreamaxiaPublisher.stopRecord();
        btnPublish.setText(“publish”);
        btnRecord.setText(“record”);
        btnSwitchEncoder.setEnabled(true);
    catch (Exception e1) {
        //
    }
}

Life Cycle 

Don’t forget to handle the publisher functions also on the activities different lifecycle events.

@Override
 protected void onResume() {
     super.onResume();
     if (mStreamaxiaPublisher != null) {
         mCameraView.startCamera();
     }
 }
 
 @Override
 protected void onPause() {
     super.onPause();
     if (mStreamaxiaPublisher != null) {
         mCameraView.stopCamera();
         mStreamaxiaPublisher.pauseRecord();
     }
 }
 
 @Override
 protected void onDestroy() {
     super.onDestroy();
     if (mStreamaxiaPublisher != null) {
         mStreamaxiaPublisher.stopPublish();
         mStreamaxiaPublisher.stopRecord();
     }
 }
 
 @Override
 public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
     mStreamaxiaPublisher.setScreenOrientation(newConfig);
 }

Share This Story, Choose Your Platform!