# Realize Live Interactive Streaming

This guide introduces how to implement live interactive voice streaming. The API call sequence of live interactive voice streaming is shown in the figure below:

../../../../_images_en/multiaudioworkflow.jpg

# Initialize

Extend the JCMediaChannelCallback (opens new window) object and JCMediaDeviceCallback (opens new window) object, and implement the pure virtual functions in these two objects.

class JCManager : public JCMediaDeviceCallback, public JCMediaChannelCallback
{
public:

    //The callback of MediaChannel state change
    virtual void onMediaChannelStateChange(JCMediaChannelState state, JCMediaChannelState oldState);
    //The callback of channel property change
    virtual void onMediaChannelPropertyChange(JCMediaChannelPropChangeParam propChangeParam);
    //The callback of joining ChannelReason
    virtual void onJoin(bool result, JCMediaChannelReason reason, const char* channelId);
    //The callback of leaving ChannelReason
    virtual void onLeave(JCMediaChannelReason reason, const char* channelId);
    //The callback of channel Stop result
    virtual void onStop(bool result, JCMediaChannelReason reason);
    //The callback of channel Query result
    virtual void onQuery(int operationId, bool result, JCMediaChannelReason reason, JCMediaChannelQueryInfo* queryInfo);
    //The callback of ParticipantJoin
    virtual void onParticipantJoin(JCMediaChannelParticipant* participant);
    //The callback of ParticipantLeft
    virtual void onParticipantLeft(JCMediaChannelParticipant* participant);
    //The callback of ParticipantUpdate
    virtual void onParticipantUpdate(JCMediaChannelParticipant* participant, JCMediaChannelParticipant::ChangeParam changeParam);
    //This callback triggers when messages are received in the channel
    virtual void onMessageReceive(const char* type, const char* content, const char* fromUserId);
    //The callback of InviteSipUserResult
    virtual void onInviteSipUserResult(int operationId, bool result, JCMediaChannelReason reason);
    //The volume change of Participants
    virtual void onParticipantVolumeChange(JCMediaChannelParticipant* participant);

public:
    //mediaDevice object
    JCMediaDevice* mediaDevice;
    //mediaChannel object
    JCMediaChannel* mediaChannel;
};

Call createJCMediaDevice (opens new window) and createJCCall (opens new window) to initialize the modules needed for group video calls:

//Initialize
bool JCManager::initialize()
{
    //1. Media class
    mediaDevice = createJCMediaDevice(client, this);
    //1. mediaChannel class
    mediaChannel = createJCMediaChannel(client, mediaDevice, this);
}

Among them:

  • This in the JCMediaDevice create method is a derived class of JCMediaDeviceCallback (opens new window) , which is used to notify the upper layer of media device-related events. Therefore, you need to create a derived class of JCMediaDeviceCallback, and then implement the pure virtual function of JCMediaDeviceCallback in the derived class.

  • This in the JCMediaChannel create method is a derived class of JCMediaChannelCallback (opens new window) , which is used to notify related events in the channel to the upper layer. Therefore, you need to create a derived class of JCMediaChannelCallback, and then implement the pure virtual function of JCMediaChannelCallback in the derived class.

TIP

The object in the callback can only be used in the callback and cannot be saved. The upper layer can obtain the call object through the corresponding method.

# Role setting

There are two roles for users in live streaming: the host and audience. The audience in the live sreaming can only hear the voice of the host, but cannot talk.

Before joining a channel, you must set the role at first. The host can upload local audio and video streams, and the audience can only see the image of the host and hear the voice of the host.

The role value can be customized according to the JCMediaChannelCustomRole (opens new window) enumeration value, such as:

//Customize the role of the host according to the CustomState enumeration value
JCMediaChannelCustomRole ROLE_BROASCASTER = JCMediaChannelCustomRole0;
//Customize the role of audiences according to the CustomState enumeration value
JCMediaChannelCustomRole ROLE_AUDIENCE = JCMediaChannelCustomRole1;

Call setCustomRole (opens new window) to set your own role to enter the channel:

// Set the role; the value of participant (the second parameter) is null, which means that you set your own role
JCManager::shared()->mediaChannel->setCustomRole(ROLE_BROASCASTER, NULL);

TIP

After joining a channel, if you want to switch user roles, you can also call the setCustomRole method.

# Join a channel

Before joining a channel, you need to control the upload of audio and video streams according to the role of the member.In the live interactive voice streaming, the host needs to upload the local audio stream, but the audience does not.

  1. Call enableUploadAudioStream (opens new window) to enable audio streaming:

    //Upload local audio and video streams according to roles
    JCManager::shared()->mediaChannel->enableUploadVideoStream(customRole == ROLE_BROASCASTER);
    

Since the SDK uploads video streams by default, you need to turn off the uploading video stream symbol before joining a channel for live interactive voice streamingSince the SDK uploads video streams by default, you need to turn off the uploading video stream logo before joining a channel for live interactive voice streaming:

//Turn off uploading video stream
JCManager::shared()->mediaChannel->enableUploadAudioStream(false);

TIP

  • These two interfaces can be called before or after joining a channel.

  • If called before joining a channel, it will only pre-open or close the “upload audio and video stream” symbol, and not send data. After joining a channel, the server will determine whether to upload audio and video according to the value passed in the parameter.

  • If the value passed in the enableUploadVideoStream method is false before joining a channel, the live interactive voice streaming mode will be automatically turned on after joining a channel.

  • In addition, calling the enableUploadVideoStream method to send local video stream data according to whether the camera has been opened.

  • After the interface is called, when joining a channel, other members in the channel will receive the status change callback (onParticipantUpdate) of the member “whether to upload audio and video”.

  1. After the role is set, call the join (opens new window) method to create and join a channel. You need to pass in the following parameters in the method:

    • channelIdOrUri: Channel ID or channel Uri. When uriMode in param is set to true, it means channel Uri, and others mean channel ID. Users with the same channel ID or Uri will enter the same channel.

    • joinParam: Join parameters, if not, fill in NULL. See JCMediaChannelJoinParam (opens new window) object for details.

    // Join a channel
    JCManager::shared()->mediaChannel->join("channel ID", NULL);
    
  2. The onJoin (opens new window) callback triggers after joining the channel:

    // The callback of joining ChannelReason
    void JCManager::onJoin(bool result, JCMediaChannelReason reason, const char* channelId)
    {
        if (result) {
        //the logic of successful joining in
        ...
        } else {
        //the logic of failed joining in
        ...
        }
    }
    

# Leave a channel

Call the leave (opens new window) method to leave the current channel:

JCManager::shared()->mediaChannel->leave();

After leaving the channel, they receive the onLeave (opens new window) callback, and other members receive the onParticipantLeft (opens new window) callback at the same time:

// The callback of leaving the channel
void JCManager::onLeave(JCMediaChannelReason reason, const char* channelId);
{
    //The logic of leaving a channel
}

# Destroy a channel

If you want to destroy a channel, you can call the following interface, and all members will be quit.

// End a channel
JCManager::shared()->mediaChannel->stop();

After the channel is stopped, the member that initiated the termination receives the onStop (opens new window) callback, and other members receive the onLeave (opens new window) callback at the same time. Please refer to JCMediaChannelReason (opens new window) for the enumeration value of the reason for failure.

void JCManager::onStop(bool result, JCMediaChannelReason reason)
{
    //The processing of ending a channel
}