Selecting Simulcast Layers

Overview

This quick tutorial will demonstrate how to select between the different simulcast layers when subscribing to a stream with simulcast enabled.

Implementing a callback script

We need to write a script that will be used as a callback whenever a subscriber receives simulcast information. The method needs to have the following signature:

void OnSimulcastCallback(McSubscriber subscriber, SimulcastInfo info) {...}

where SimulcastInfo contains the following information:


    public partial class SimulcastInfo
    {
        public SimulcastData[] Active { get; set; }

        public SimulcastData[] Inactive { get; set; }

        public Layer[] Layers { get; set; }
    }

    public partial class Layer
    {
        public long SimulcastIdx { get; set; }

        public long SpatialLayerId { get; set; }

        public long TemporalLayerId { get; set; }

        public long Bitrate { get; set; }

        public string EncodingId { get; set; }
    }

We will be concerned with the Layer class in this tutorial. Let us implement a script called SimulcastListener which has an implementation of this callback

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

using Dolby.Millicast;

public class SimulcastListener : MonoBehaviour
{
    private Layer _highestLayer;

    public void OnSimulcastCallback(McSubscriber subscriber, SimulcastInfo info)
    {
        // We will select the layer with the highest bitrate

        // Fetch the highest layer
        var highestLayerNow = info.Layers.Aggregate((x, y) => x.Bitrate > y.Bitrate ? x : y);

        // Only assign the layer if it is higher, or we are initially null.
        if (_highestLayer == null || highestLayerNow.Bitrate > _highestLayer.Bitrate)
        {
            _highestLayer = highestLayerNow;
            // Select the layer on the subscriber
            subscriber.SetSimulcastLayer(highestLayerNow);
        }
    }
}

Now, we can add this component to to a GameObject, and select it in the McSubscriber:

So in that example above, both the McSubscriber & SimulcastListener scripts were added to an empty object called Subscriber, which is the one selected under Runtime Only

You can also assign the callback using the McSubscriber script directly like so

{
  McSubscriber subscriber = gameObject.AddComponent<McSubscriber>();
  subscriber.OnSimulcastlayerInfo += OnSimulcastCallback; // Assuming we are inside the SimulcastListener class
}