Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This article is to help setting an Android project using PhenixRTS Android SDK along side alongside our API documentation (found here).

...

Android studio and development environment. Instructions Installation instructions can be found here.

\uD83D\uDCD8 InstructionsInstructions

To set up and build a project using our Android SDK, follow the instructions in this section.

  1. Open android studio and create a new project.

  2. Add the following dependency to app/build.gradle:

    Code Block
    implementation "com.phenixrts.android:phenix-sdk-android:2021.0.15"

    If you are using a different version of the Phenix Android SDK, use that version number in place of 2021.0.15.

  3. Add maven credentials and url to the project’s settings.gradle file (replace values with your own).

    Code Block
    maven {
                credentials {
                    username "YOUR_GIT_USERNAME"
                    password "YOUR_GIT_KEY"
                }
                url "https://maven.pkg.github.com/PhenixRTS/AndroidSDK"
            }


  4. Once you have added the dependency and git settings, be sure to sync the gradle settings. The project will not compile without synchronizing these settings.

  5. Add a surface view to activity_main.xml as soshown below:

    Code Block
    <SurfaceView
            android:id="@+id/surface"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:keepScreenOn="true"
            tools:layout_editor_absoluteX="52dp"
            tools:layout_editor_absoluteY="0dp"/>

  6. Add the following code to your MainActivity.kt, replacing the token and channel alias with actual values as indicated.

    Code Block
    package com.example.phenixrtsandroidviewer
    
    import android.os.Bundle
    import android.util.Log
    import android.view.SurfaceView
    import androidx.appcompat.app.AppCompatActivity
    import com.phenixrts.common.RequestStatus
    import com.phenixrts.environment.android.AndroidContext
    import com.phenixrts.express.*
    import com.phenixrts.pcast.AspectRatioMode
    import com.phenixrts.pcast.Renderer
    import com.phenixrts.pcast.RendererOptions
    import com.phenixrts.pcast.android.AndroidVideoRenderSurface
    import com.phenixrts.room.RoomService
    
    class MainActivity : AppCompatActivity() {
        private var currentRoomService: RoomService? = null
        private var currentRenderer: Renderer? = null
        private var currentSubscriber: ExpressSubscriber? = null;
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val surfaceView = findViewById<SurfaceView>(R.id.surface)
            // must set Context first
            AndroidContext.setContext(applicationContext)
            render(surfaceView)
        }
        private fun render(surfaceView: SurfaceView) {
            //Replace with your viewing token and channel alias:
            val token = "DIGEST:..."
            val channelAlias = "yourAlias"
    
            Log.e("StreamingApi", "Creating StreamingApi")
            Log.e("StreamingApi", "token: $token")
    
            val renderSurface = AndroidVideoRenderSurface(surfaceView.holder)
    
            val pcastExpressOptions = PCastExpressFactory.createPCastExpressOptionsBuilder()
                .withAuthenticationToken(token)
                .withMinimumConsoleLogLevel("info")
                .withUnrecoverableErrorCallback { status: RequestStatus?, description: String? ->
                    Log.e("StreamingApi", "Unrecoverable Error: $description")
                }
                .buildPCastExpressOptions()
    
            val roomExpressOptions = RoomExpressFactory.createRoomExpressOptionsBuilder()
                .withPCastExpressOptions(pcastExpressOptions)
                .buildRoomExpressOptions()
    
            val channelExpressOptions = ChannelExpressFactory.createChannelExpressOptionsBuilder()
                .withRoomExpressOptions(roomExpressOptions)
                .buildChannelExpressOptions()
    
            //channel express created with options
            val channelExpress = ChannelExpressFactory.createChannelExpress(channelExpressOptions)
    
            // Just an example (you can omit renderer options if defaults are ok)
            val rendererOptions = RendererOptions().apply {
                aspectRatioMode = AspectRatioMode.LETTERBOX
            }
    
            val joinRoomOptions = RoomExpressFactory.createJoinRoomOptionsBuilder()
                .withRoomAlias(channelAlias)
                .withCapabilities(arrayOf())
                .buildJoinRoomOptions()
    
            val joinChannelOptions = ChannelExpressFactory.createJoinChannelOptionsBuilder()
                .withJoinRoomOptions(joinRoomOptions)
                .withStreamToken(token)
                .withRenderer(renderSurface)
                .withRendererOptions(rendererOptions)
                .buildJoinChannelOptions()
    
            Log.e("StreamingApi", "joining channel")
    
            channelExpress.joinChannel(
                joinChannelOptions,
                { status: RequestStatus, roomService: RoomService? ->
                    if (status != RequestStatus.OK) {
                        Log.e(
                            "StreamingApi",
                            "Could not join room: ${status.name}, ${roomService?.toString()}"
                        )
                        // Handle room join error
                        return@joinChannel
                    }
    
                    Log.e("StreamingApi", "status is OK")
    
                    // Important: Store room service reference, otherwise we will leave channel again
                    // as soon as this RoomService instance is garbage collected:
                    currentRoomService = roomService
                }
            ) { status: RequestStatus?, subscriber: ExpressSubscriber?, renderer: Renderer? ->
                when (status) {
    
                    RequestStatus.OK -> {
                        Log.e("StreamingApi", "Stream connected")
                        currentSubscriber = subscriber;
                        currentRenderer = renderer;
                        // Successfully subscribed to a stream. No need to hold on to any references
                    }
                    RequestStatus.NO_STREAM_PLAYING -> {
                        Log.e("StreamingApi", "No streams currently playing")
                        // No stream playing in channel, update UI accordingy
                    }
                    else -> {
                        Log.e("StreamingApi", "Failed to join room")
                        // We failed to subscribe and retry attempts must have failed
                    }
                }
    
            }
    
        }
    }

  7. Run project to view stream (either on a device or an emulator).

Troubleshooting

...

  1. Be sure to have a stream published that corresponds to the alias and token that you used in the code snippet above.

  2. Double check that you have setup your github GitHub to use an access token.

  3. Confirm that you have android:keepScreenOn="true" on your SurfaceView object in the main_activity.xml.

More information

More information about the Phenix Android SDK and GitHub can be found at the following links.