Red5 Documentation

Wowza to Red5 Pro SDK Migration Guide

Introduction

Purpose

This section serves as a guide for developers migrating from Wowza’s SDK, offering a clear path to maintain or enhance streaming functionalities across various platforms. It maps Wowza’s SDKs to Red5 Pro equivalents, highlighting their features and providing an integration roadmap. Whether you’re building a web application, native mobile app, or game engine, Red5 Pro offers low-latency streaming SDKs designed for high performance and flexibility. By following these steps, developers can seamlessly transition their applications and take advantage of Red5’s advanced tools and features to optimize their streaming solutions.

SDK Integration

This section will help map Wowza’s SDKs to their Red5 Pro equivalents and provide a roadmap for a smooth migration. Red5 Pro offers flexible, high-performance SDKs for streaming and playback

Environment/Platform Wowza SDK/Tool Red5 Pro SDK/Tool
Web (HTML) Wowza Flowplayer HTML SDK Red5 Pro HTML5 WebRTC SDK
iOS (Apple) Wowza Flowplayer Apple SDK Red5 Pro SDK for iOS
Android Wowza Flowplayer Android SDK Red5 Pro SDK for Android
Cross-Platform/Core Wowza SDK-equivalent not available Red5 Pro Core SDK (Windows, MacOS, Linux)
Game Engines Wowza SDK-equivalent not available Unreal Engine SDK, Unity SDK

From Wowza Flowplayer HTML SDK to Red5 Pro HTML5 WebRTC SDK

Wowza Flowplayer HTML SDK

Red5 Pro HTML5 WebRTC SDK

  • Dedicated for low-latency streaming using WebRTC that are ideal for browser-based applications
  • Supports WebRTC for both publishers and subscribers (streamers and viewers), offering sub-500ms latency.

Transition Steps

  1. Setup and Installation: Follow the Red5 Pro HTML5 WebRTC SDK Installation Guide . Download the required development files and host your frontend.
  2. WebRTC Integration: Replace Wowza’s implementation code with WebRTC client configuration settings.
  3. Authentication and Connection: If Wowza’s REST API is being used, map the server connection details to Red5 Pro’s Stream Manager 2.0 API.
  4. Testing

Red5 Pro WebRTC SDK Setup and Installation

The Red5 Pro WebRTC SDK is available for installation for frontend applications from NPM:
npm install --save-dev red5pro-webrtc-sdk
Additionally, it is publicly available on the unpkg.com CDN and can be defined as a script dependency in your HTML:
<script src="https://unpkg.com/red5pro-webrtc-sdk@latest/red5pro-sdk.min.js"></script>

WebRTC Integration

The Red5 Pro WebRTC SDK provides WebSocket and WHIP based publishers (RTCPublisher and WHIPClient, respectively) for broadcasting live WebRTC streams to the Red5 Pro Server, as well as WebSocket and WHEP base subscribers (RTCSubscriber and WHEPClient, respectively) for consuming and playback of live WebRTC Streams.

The Red5 Pro publisher and subscriber implementations are driven by an init configuration describing the Red5 Pro server endpoint and stream. For developers familiar with Wowza, this is similar to how one would define their flowplayer configuration.

Wowza Flowplayer configuration example:
flowplayer("#player", {
  src: {
    type: "wowza/webrtc",
    sdpUrl: "wss://[your-streamlock-domain].streamlock.net/webrtc-session.json",
    applicationName: "webrtc",
    streamName: "myStream",
    // Optional token for secure streaming
    token: "[your-secure-token]"
  },
  // Top-level product token
  token: "[your-player-token]"
})
Red5 Pro WebRTC configuration:
javascript
import {
  WHIPClient,
  WHEPClient
} from 'red5pro-webrtc-sdk'

const config = {
  protocol: 'wss',
  host: 'your-red5-domain.com',
  port: 443,
  app: 'live',
  streamName: 'mystream',
  rtcConfiguration: {
    iceServers: [{urls: 'stun:stun2.l.google.com:19302'}]
  }
}

const start = async () => {
  try {
    // Broadcast
    const publisher = new WHIPClient()
    publisher.on('*', onPublisherEvent)
    await publisher.init({
      ...config,
      mediaElementId: 'red5pro-publisher'
    })
    await publisher.publish()

    // Playback
    const subscriber = new WHEPClient()
    subscriber.on('*', onSubscriberEvent)
    await subscriber.init({
      ...config,
      mediaElementId: 'red5pro-subscriber'
    })
    await subscriber.subscribe()

  } catch (e) {
    console.error(e)
  }
}

start()

The above code assumes that two video elements are available on the corresponding DOM with id attributes: red5pro-publisher and red5pro-subscriber.

From the init configuration attributes, the Red5 Pro WebRTC SDK will construct a standalone Red5 Pro Server endpoint for the client to connect to:

const config = {
  protocol: 'wss',
  host: 'your-red5-domain.com',
  port: 443,
  app: 'live',
  streamName: 'mystream'
}

The attributes above will point to an Red5 Pro Server standalone endpoint of the following based on the client used:

Client Endpoint
WHIPClient https://your-red5-domain.com/live/whip/endpoint/mystream
WHEPClient https://your-red5-domain.com/live/whep/endpoint/mystream
RTCPublisher wss://your-red5-domain.com/live/?id=mystream
RTCSubscriber wss://your-red5-domain.com/live/?id=subscriber-id

Similarly, there is an optional endpoint init configuration attribute. If you know the endpoint construct, this attribute can be used to easily establish a connection with the Red5 Pro Server. In fact, it is the endpoint attribute that is used in properly proxying through the Stream Manager 2.0:

const config = {
  endpoint: 'https://your-red5-domain.com/as/v1/proxy/whip/live/mystream',
  streamName: 'mystream'
}`

For integration with the Red5 Pro Stream Manager 2.0, the init configuration endpoint attribute will look like the following:

Client Endpoint
WHIPClient https://your-red5-domain.com/as/v1/proxy/whip/live/mystream
WHEPClient https://your-red5-domain.com/as/v1/proxy/whep/live/mystream
RTCPublisher wss://your-red5-domain.com/as/v1/proxy/ws/publish/live/mystream
RTCSubscriber wss://your-red5-domain.com/as/v1/proxy/ws/subscribe/live/mystream
Client Authentication

Clients can provide authentication details to be passed to the Round Trip Authentication of the Red5 Pro Server using the connectionParams init configuration attribute:

const config = {
  // ...attributes
  connectionParams: {
    username: 'user',
    password: 'pass',
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJpYXQiOjE2ODYzNzY2NjAsImV4cCI6MTY4NjM4MDI2MH0.bM8aZ_Rb0qZqZkSYBGNXLHL-wKaOaKoR4F_RFKk9PUo
'
  }
}`

There are many more init configuration attributes that can be defined for fine tuning publishing and subscribing. Please refer to the documentation on Red5 Pro Publisher Configuration and Red5 Pro Subscriber Configuration.

From Wowza Flowplayer Apple SDK to Red5 Pro iOS SDK

Wowza Flowplayer Apple SDK Overview:

  • The Wowza Flowplayer Apple SDK includes a native media player written entirely in Swift. The SDK provides an easy-to-use API that enables developers to create iOS and tvOS applications that use the Wowza Flowplayer to play audio and video locally and over the internet, and utilizes AVPlayer for playback of content.

Red5 Pro iOS SDK Overview:

  • Built specifically for iOS to leverage RTSP-based live streaming, low latency publishing, and viewing.
  • Distributed as a framework that can be added to any iOS project and can integrated into applications using either Objective-C or Swift.
  • Does not provide a player specifically, but instead renders video frames of live streams to a view around with a player with UI controls can be developed.

Transition Steps:

  1. Download and Setup: Access the Red5 Pro iOS SDK Repository and clone the project files.
  2. Implement Publisher/Subscriber Flow:
    • Use the R5Stream object in Red5 Pro to handle publishing and subscribing to streams.
  3. Connection Handling: Update Wowza’s connection handling logic to use the Red5 Pro Stream Manager 2.0 API for dynamic stream allocation.

Implement Publisher/Subscriber Flow

Unlike the iOS Flowplayer from Wowza, the creation of an iOS Red5 Pro streaming client does not load external or OVP streams into a player wrapper. Instead, live streaming Red5 Pro clients (both publisher and subscriber) are made of composable objects used to connect and stream.

At the heart of the composition lies:

  • R5Configuration – Detailing connection attributes
  • R5Connection – Manages the connection to the Red5 Pro Server
  • R5Stream – Represents a publish or subscribe stream
  • R5VideoViewController – The view presenting the stream

With an R5Stream established for a publisher, Camera and Microphone can be attached to being sending out media packets on the stream; an R5Stream for a subscriber will sync the incoming media packets and render the video frames to a defined view.

Publisher Example
func getNewR5VideoViewController(rect : CGRect) -> R5VideoViewController {
    let view : UIView = UIView(frame: rect)
    var r5View : R5VideoViewController
    r5View = R5VideoViewController.init()
    r5View.view = view;
    return r5View;
}

func getConfig() -> R5Configuration {
    let config = R5Configuration()
    config.host = "your-red5-domain.com"
    config.port = 8554
    config.contextName = "live"
    config.protocol = 1;
    config.buffer_time = 0.5
    config.licenseKey = "YOUR_SDK_LICENSE_KEY"
    return config
}

let config = getConfig()
let connection = R5Connection(config: config)
let publishStream = R5Stream(connection: connection)

let videoDevice = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo).last as? AVCaptureDevice
let camera = R5Camera(device: videoDevice, andBitRate: 750)
let audioDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
let microphone = R5Microphone(device: audioDevice)

publishStream.attachVideo(camera)
publishStream.attachAudio(microphone)

let r5View : R5VideoViewController = getNewR5VideoViewController(self.view.frame)
r5View.attachStream(publishStream)

publishStream.publish("mystream", type: R5RecordTypeLive)
Subscriber Example
func getNewR5VideoViewController(rect : CGRect) -> R5VideoViewController {
    let view : UIView = UIView(frame: rect)
    var r5View : R5VideoViewController
    r5View = R5VideoViewController.init()
    r5View.view = view;
    return r5View;
}

func getConfig() -> R5Configuration {
    let config = R5Configuration()
    config.host = "your-red5-domain.com"
    config.port = 8554
    config.contextName = "live"
    config.protocol = 1;
    config.buffer_time = 0.5
    config.licenseKey = "YOUR_SDK_LICENSE_KEY"
    return config
}

let config = getConfig()
let connection = R5Connection(config: config)
let subscriberStream = R5Stream(connection: connection)

let r5View : R5VideoViewController = getNewR5VideoViewController(self.view.frame)
r5View.attachStream(subscriberStream)

subscriberStream.play("mystream", withHardwareAcceleration: true)
Stream Manager 2.0 Integration

While the WebRTC stream clients have an expose proxy on the Red5 Pro Stream Manager 2.0 – in order to securely stream on Origin and Edge nodes in a browser – the RTSP clients of iOS SDK do not have such a proxy. As such, use the Stream Manager 2.0 API to access the desired Origin or Edge node IP and use that as the host attribute of the R5Configuration:

func requestOrigin(_ url: String, resolve: @escaping (_ ip: String?, _ streamGuid: String?, _ error: Error?) -> Void) {

      NSURLConnection.sendAsynchronousRequest(
          NSURLRequest( url: NSURL(string: url)! as URL ) as URLRequest,
          queue: OperationQueue(),
          completionHandler:{ (response: URLResponse?, data: Data?, error: Error?) -> Void in

            let dataAsString = NSString( data: data!, encoding: String.Encoding.utf8.rawValue)
            var json: [[String: AnyObject]]
            do {
              json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [[String: AnyObject]]
            } catch {
              print(error)
              return
            }

            if let origin = json.first {
                if let ip = origin["serverAddress"] as? String,
                    let guid = origin["streamGuid"] as? String {
                    resolve(ip, guid, nil)
                } else if let errorMessage = origin["errorMessage"] as? String {
                    resolve(nil, nil, AccessError.error(message: errorMessage))
                }
            }

        })

  }

let url = "https://your-red5-domain.com/as/v1/streams/stream/<nodeGroup>/publish/app/mystream"
requestOrigin(url, {(ip: String?, streamGuid: String?, error: Error?) -> Void in

    var paths = streamGuid?.split(separator: "/")
    let name = String((paths?.popLast())!)
    let scope = paths?.joined(separator: "/")

    let config = R5Configuration()
    config.host = ip
    config.port = 8554
    config.contextName = scope
    config.streamName = name
    config.protocol = 1;
    config.buffer_time = 0.5
    config.licenseKey = "YOUR_SDK_LICENSE_KEY"

    // Continue to set up stream.

})

The above code snippet details how to access an Origin IP address from the Stream Manager 2.0 REST API for a Publisher Stream. Similarly, an Edge IP address can be requested or a Subscriber Stream by replacing the publish URI of the url with subscribe.

There are many other features – such as background streaming – available using the Red5 Pro iOS SDK and you are invited to explore the publicly available testbeds for more examples.

From Wowza Flowplayer Android SDK to Red5 Pro Android SDK

Wowza Flowplayer Android SDK Overview

  • The Wowza Flowplayer Android SDK is a native media player written entirely in Kotlin
  • The SDK provides an easy-to-use API that enables developers to create Android applications that use the Wowza Flowplayer to play audio and video locally and over the internet, and utilizes ExoPlayer for playback of content.
  • Streaming and playback MPEG-DASH, HLS, SmoothStreaming, MP4, WebM, and MP3 formats.

Red5 Pro Android SDK Overview

  • Built specifically for Android to leverage RTSP-based live streaming, low latency publishing, and viewing.
  • Distributed as a framework that can be added to any Android project and can integrated into applications using either Java or Kotlin.
  • Does not provide a player specifically, but instead renders video frames of live streams to a view around with a player with UI controls can be developed.

Transition Steps

  1. Setup and Configuration: Download and integrate the Red5 Pro Android SDK into your project.
  2. Implement Publisher/Subscriber Flow:
    1. Use the R5Stream object in Red5 Pro to handle publishing and subscribing to streams.
  3. Connection Handling: Update Wowza’s connection handling logic to use the Red5 Pro Stream Manager 2.0 API for dynamic stream allocation.

Implement Publisher/Subscriber Flow

Unlike the Android Flowplayer from Wowza, the creation of an Android Red5 Pro streaming client does not load external or OVP streams into a player wrapper. Instead, live streaming Red5 Pro clients (both publisher and subscriber) are made of composable objects used to connect and stream.

At the heart of the composition lies:

  • R5Configuration – Detailing connection attributes
  • R5Connection – Manages the connection to the Red5 Pro Server
  • R5Stream – Represents a publish or subscribe stream
  • R5VideoView – The view presenting the stream

With an R5Stream established for a publisher, Camera and Microphone can be attached to being sending out media packets on the stream; an R5Stream for a subscriber will sync the incoming media packets and render the video frames to a defined view.

An example of a view resource to be used in an Android application:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<com.red5pro.streaming.view.R5VideoView
    android:id="@+id/videoView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true" />

</FrameLayout>
Publisher Example
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.publish_test, container, false);
    preview = (R5VideoView)rootView.findViewById(R.id.videoView);
    publish();

    return rootView;
}

protected void publish() {
    String b = getActivity().getPackageName();
    R5Configuration config = new R5Configuration(R5StreamProtocol.RTSP,
            "your-red5-domain.com",
            8554,
            "live",
            0.5);
    config.setLicenseKey("YOUR_SDK_LICENSE_KEY");
    config.setBundleID(b);

    R5Connection connection = new R5Connection(config);
    R5Stream publishStream = new R5Stream(connection);

    Camera cam = openFrontFacingCameraGingerbread(); // Camera access method
    R5Camera camera = new R5Camera(cam, 640, 480);
    R5Microphone mic = new R5Microphone();

    publishStream.attachCamera(camera);
    publishStream.attachMic(mic);

    preview.attachStream(publishStream);

    publishStream.publish("mystream", R5Stream.RecordType.Live);
}
Subscriber Example
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.publish_test, container, false);
    preview = (R5VideoView)rootView.findViewById(R.id.videoView);
    subscribe();

    return rootView;
}

protected void subscribe() {
    String b = getActivity().getPackageName();
    R5Configuration config = new R5Configuration(R5StreamProtocol.RTSP,
            "your-red5-domain.com",
            8554,
            "live",
            0.5);
    config.setLicenseKey("YOUR_SDK_LICENSE_KEY");
    config.setBundleID(b);

    R5Connection connection = new R5Connection(config);
    R5Stream subscriberStream = new R5Stream(connection);
    subscriberStream.audioController = new R5AudioController();
    subscriberStream.audioController.sampleRate = 44100;

    preview.attachStream(subscriberStream);

    subscriberStream.play("mystream", true);
}
Stream Manager 2.0 Integration

While the WebRTC stream clients have an expose proxy on the Red5 Pro Stream Manager 2.0 – in order to securely stream on Origin and Edge nodes in a browser – the RTSP clients of iOS SDK do not have such a proxy. As such, use the Stream Manager 2.0 API to access the desired Origin or Edge node IP and use that as the host attribute of the R5Configuration:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.publish_test, container, false);
    preview = (R5VideoView)rootView.findViewById(R.id.videoView);

    String url = "https://your-red5-domain.com/as/v1/streams/stream/<nodeGroup>/publish/app/mystream";
    requestOrigin(url);

    return rootView;
}

public void requestOrigin(String url) {
  new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(new HttpGet(url));
            StatusLine statusLine = response.getStatusLine();

            if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                String responseString = out.toString();
                out.close();

                JSONArray origins = new JSONArray(responseString);
                JSONObject data = origins.getJSONObject(0);
                final String originIP = data.getString("serverAddress");

                if ( !originIP.isEmpty() ){
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            publishToManager(originIP);
                        }
                    });
                } else {
                    System.out.println("Server address not returned");
                }
            } else {
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  }).start();
}

protected void publishToManager(String originIP) {
    String b = getActivity().getPackageName();
    R5Configuration config = new R5Configuration(R5StreamProtocol.RTSP,
            originIP,
            8554,
            "live",
            0.5);
    config.setLicenseKey("YOUR_SDK_LICENSE_KEY");
    config.setBundleID(b);

    R5Connection connection = new R5Connection(config);
    R5Stream publishStream = new R5Stream(connection);

    Camera cam = openFrontFacingCameraGingerbread(); // Camera access method
    R5Camera camera = new R5Camera(cam, 640, 480);
    R5Microphone mic = new R5Microphone();

    publishStream.attachCamera(camera);
    publishStream.attachMic(mic);

    preview.attachStream(publishStream);

    publishStream.publish("mystream", R5Stream.RecordType.Live);
}

The above code snippet details how to access an Origin IP address from the Stream Manager 2.0 REST API for a Publisher Stream. Similarly, an Edge IP address can be requested or a Subscriber Stream by replacing the publish URI of the url with subscribe.

There are many other features – such as background streaming – available using the Red5 Pro iOS SDK and you are invited to explore the publicly available testbeds for more examples.