WebRTC Android by Stream

repository·main·Indexed 21 days ago

https://github.com/getstream/webrtc-android

A pre-compiled WebRTC core library for Android that serves as a modern replacement for the deprecated Google WebRTC Android library. It provides updated WebRTC commits and includes support for Kotlin extensions (KTX), Jetpack Compose components (VideoRenderer, FloatingVideoRenderer), and custom UI components like VideoTextureViewRenderer. The library exposes the org.webrtc package and includes utilities for audio buffer management via WebRtcAudioManager and hardware-accelerated video decoding via MediaCodecVideoDecoderFactory.

Tokens
4.6K
Snippets
22
Records
25
Agent score
75%

What's inside webrtc-android

  1. Include WebRTC Android SNAPSHOT versions

    main

    If you need to use the latest development snapshots, you must first add the Sonatype Maven snapshots repository to your repositories block, then add the specific SNAPSHOT dependency to your module's build.gradle file.

    repositories {
       maven(url="https://central.sonatype.com/repository/maven-snapshots/")
    }
    
    dependencies {
        implementation("io.getstream:stream-webrtc-android:1.3.11-SNAPSHOT")
    }
  2. Build WebRTC AAR using build_aar.py

    main

    The simplest way to compile the source code for all supported CPU types (arm64-v8a, armeabi-v7a, x86, x86_64) into a single .aar file is to use the provided AAR build tool.

    Steps:

    1. Ensure your current working directory is webrtc_android/src/.
    2. Run the build script:
    tools_webrtc/android/build_aar.py

    This will generate libwebrtc.aar in the webrtc_android/src/ directory.

  3. Install Stream WebRTC Android UI components

    main

    To use custom UI components like VideoTextureViewRenderer for complex video layouts (e.g., overlaying video frames), add the following dependency to your module's build.gradle file:

    dependencies {
        implementation "io.getstream:stream-webrtc-android-ui:$version"
    }
  4. Install WebRTC Android via Gradle

    main

    To use the pre-compiled WebRTC core library in your Android project, add the dependency to your module's build.gradle file. This library provides the org.webrtc package, including essential classes for real-time video and audio communication.

    dependencies {
        implementation("io.getstream:stream-webrtc-android:1.3.9")
    }
  5. Compile WebRTC core library manually

    main

    To compile the WebRTC core library yourself, you must use a Linux OS (Ubuntu 14.04 LTS recommended) with at least 8GB RAM and 50GB storage. You must first set up depot_tools and fetch the Chromium WebRTC repository.

    Manual Compilation Steps:

    1. Set up depot_tools and fetch the repository.
    2. Ensure you are on the origin/master branch to resolve compilation issues.
    3. Generate projects using gn and compile using ninja.

    Generate Projects (GN): Run these from webrtc_android/src/:

    gn gen out/Debug --args='target_os="android" target_cpu="arm"'
    gn gen out/Release --args='is_debug=false is_component_build=false rtc_include_tests=false target_os="android" target_cpu="arm"'

    Note: Use target_cpu="arm64" for ARM64, target_cpu="x86" for 32-bit x86, and target_cpu="x64" for 64-bit x64.

    Compile (Ninja):

    ninja -C out/Debug
    ninja -C out/Release
    gn gen out/Debug --args='target_os="android" target_cpu="arm"'
    gn gen out/Release --args='is_debug=false is_component_build=false rtc_include_tests=false target_os="android" target_cpu="arm"'
    ninja -C out/Debug
    ninja -C out/Release
  6. Install Stream WebRTC Android Jetpack Compose components

    main

    To use Jetpack Compose components like VideoRenderer and FloatingVideoRenderer, add the following dependency to your module's build.gradle file:

    dependencies {
        implementation "io.getstream:stream-webrtc-android-compose:$version"
    }
  7. Use VideoTextureViewRenderer for complex video layouts

    main

    The VideoTextureViewRenderer is a custom TextureView that implements VideoSink and SurfaceTextureListener. It is recommended over SurfaceViewRenderer when you need to design complex video call screens where one video layout must overlay another.

    XML Usage:

    <io.getstream.webrtc.android.ui.VideoTextureViewRenderer
        android:id="@+id/participantVideoRenderer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
     />

    Adding/Removing Video Tracks in Kotlin:

    videoTrack.video.addSink(participantVideoRenderer)
    videoTrack.video.removeSink(participantVideoRenderer)
  8. Use WebRTC KTX Coroutine extensions

    main

    The KTX library provides suspend functions to replace callback-style WebRTC operations with Coroutines.

    addRtcIceCandidate: A suspend function to add an IceCandidate to a PeerConnection using Coroutines style.

    pendingIceMutex.withLock {
        pendingIceCandidates.forEach { iceCandidate ->
            connection.addRtcIceCandidate(iceCandidate)
        }
        pendingIceCandidates.clear()
    }

    createSessionDescription: A way to create a SessionDescription that delegates SdpObserver using Coroutines style.

    suspend fun createAnswer(): Result<SessionDescription> {
      return createSessionDescription { sdpObserver -> connection.createAnswer(sdpObserver, mediaConstraints) }
    }
  9. Use VideoRenderer in Jetpack Compose

    main

    VideoRenderer is a composable function that renders a single video track. You can observe rendering state changes using the RendererEvents interface.

    Usage Example:

    VideoRenderer(
        videoTrack = remoteVideoTrack,
        modifier = Modifier.fillMaxSize(),
        eglBaseContext = eglBaseContext,
        rendererEvents = rendererEvents
    )

    Implementing RendererEvents:

    val rendererEvents = object : RendererEvents {
          override fun onFirstFrameRendered() { .. }
          override fun onFrameResolutionChanged(videoWidth: Int, videoHeight: Int, rotation: Int) { .. }
    }
  10. Use FloatingVideoRenderer in Jetpack Compose

    main

    FloatingVideoRenderer is a composable function used to overlay a single video track (typically the local participant) on top of another. It allows users to move the floating video track via interactions.

    Usage Example (Overlaying Local Video on Remote Video):

    var parentSize: IntSize by remember { mutableStateOf(IntSize(0, 0)) }
    
    if (remoteVideoTrack != null) {
      VideoRenderer(
        videoTrack = remoteVideoTrack,
        modifier = Modifier
          .fillMaxSize()
          .onSizeChanged { parentSize = it },
        eglBaseContext = eglBaseContext,
        rendererEvents = rendererEvents
      )
    }
    
    if (localVideoTrack != null) {
      FloatingVideoRenderer(
        modifier = Modifier
          .size(width = 150.dp, height = 210.dp)
          .clip(RoundedCornerShape(16.dp))
          .align(Alignment.TopEnd),
        videoTrack = localVideoTrack,
        parentBounds = parentSize,
        paddingValues = PaddingValues(0.dp),
        eglBaseContext = eglBaseContext,
        rendererEvents = rendererEvents
      )
    }
  11. Reference common WebRTC Android APIs

    main

    The library exposes the org.webrtc package. Key classes for building WebRTC applications include:

    • PeerConnection: Manages SDP offers/answers, ICE candidates, and connection monitoring.
    • PeerConnectionFactory: Used to create PeerConnection instances.
    • EglBase: Handles EGL state (EGLContext, EGLDisplay, EGLSurface).
    • VideoTrack: Manages VideoSink objects to receive real-time video frames.
    • VideoSource: Used to create video tracks and add VideoProcessor instances.
    • AudioTrack: Manages AudioSink objects for real-time audio.
    • AudioSource: Used to create audio tracks.
    • MediaStreamTrack: Java wrapper for the C++ MediaStreamTrackInterface.
    • IceCandidate: Represents a single ICE Candidate.
    • SessionDescription: Represents an RFC 4566 Session (SDP).
    • SurfaceViewRenderer: A SurfaceView used to display video streams.
    • Camera2Capturer: Provides video frames for a VideoTrack from a specific cameraId (requires API level 21+).
    • Camera2Enumerator: Enumerates available cameras.