Detailed steps and test demo of c# WPF program accessing voice network dll

Keywords: C# network Windows

Voice network is a video and audio chat tool. Because the official network only provides C++DLL, it can not be directly used in WPF programs. In order to facilitate the use of developers, I am further encapsulating the voice network DLL, encapsulating it into its own interface, and at the same time facilitating c# calls.

In the first step, agora_rtc_sdk.lib is encapsulated into its own DLL:

First import agora_rtc_sdk.lib and determine the header file pch.h

#ifndef _PCH_H_
#define _PCH_H_


#include <windows.h>
#include <IAgoraRtcEngine.h>
#include <IAgoraMediaEngine.h>
#include <string>


#define WINDOWS
#define EXPORT

#include <malloc.h>
#ifdef WINDOWS
#ifdef EXPORT
#define EXPORT_API __declspec(dllexport)
#else
#define EXPORT_API __declspec(dllimport)
#endif
#else
#include <stdlib.h>

#ifdef EXPORT
#define EXPORT_API __attribute__((visibility ("default")))
#else
#endif

#endif
#pragma comment(lib, "agora_rtc_sdk.lib")

#endif // !_PCH_H_

Next, define the event declaration required by the voice network

#include"pch.h"

using namespace agora::rtc;

class CAGEngineEventHandler :
    public IRtcEngineEventHandler
{
public:
    CAGEngineEventHandler(void);
    ~CAGEngineEventHandler(void);

    void SetMsgReceiver(HWND hWnd = NULL);
    HWND GetMsgReceiver() {return m_hMainWnd;};

    virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
    virtual void onRejoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
    virtual void onWarning(int warn, const char* msg);
    virtual void onError(int err, const char* msg);
    virtual void onAudioQuality(uid_t uid, int quality, unsigned short delay, unsigned short lost);
    virtual void onAudioVolumeIndication(const AudioVolumeInfo* speakers, unsigned int speakerNumber, int totalVolume);
    
    virtual void onLeaveChannel(const RtcStats& stat);
    virtual void onRtcStats(const RtcStats& stat);
    virtual void onMediaEngineEvent(int evt);

    virtual void onAudioDeviceStateChanged(const char* deviceId, int deviceType, int deviceState);
    virtual void onVideoDeviceStateChanged(const char* deviceId, int deviceType, int deviceState);

    virtual void onLastmileQuality(int quality);
    virtual void onFirstLocalVideoFrame(int width, int height, int elapsed);
    virtual void onFirstRemoteVideoDecoded(uid_t uid, int width, int height, int elapsed);
    virtual void onFirstRemoteVideoFrame(uid_t uid, int width, int height, int elapsed);
    virtual void onUserJoined(uid_t uid, int elapsed);
    virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);
    virtual void onUserMuteAudio(uid_t uid, bool muted);
    virtual void onUserMuteVideo(uid_t uid, bool muted);
    virtual void onApiCallExecuted(const char* api, int error);

    virtual void onStreamMessage(uid_t uid, int streamId, const char* data, size_t length);
    
    virtual void onLocalVideoStats(const LocalVideoStats& stats);
    virtual void onRemoteVideoStats(const RemoteVideoStats& stats);
    virtual void onCameraReady();
    virtual void onVideoStopped();
    virtual void onConnectionLost();
    virtual void onConnectionInterrupted();

    virtual void onUserEnableVideo(uid_t uid, bool enabled);

    virtual void onStartRecordingService(int error);
    virtual void onStopRecordingService(int error);
    virtual void onRefreshRecordingServiceStatus(int status);
private:
    HWND        m_hMainWnd;
};

Finally, it is encapsulated into its own interface.
Encapsulating createAgoraRtcEngine and initialize of Voice Network into an interface Init

EXPORT_API int Init() // Define the functions you need to use
{
    RtcEngineContext m_RtcEngineContext;

    m_RtcEngineContext.eventHandler = &m_EngineEventHandler;
    m_RtcEngineContext.appId = "input appid";

    m_lpAgoraEngine = (IRtcEngine *)createAgoraRtcEngine();

    int nRet=m_lpAgoraEngine->initialize(m_RtcEngineContext);

    
    return nRet;

}

Encapsulating Join Channel

EXPORT_API int JoinChannel(const char* ChannelName, HWND wnd)
{
    int nRet = 0;

    VideoCanvas vc;

    vc.uid = 0;
    vc.view = wnd;
    vc.renderMode = RENDER_MODE_TYPE::RENDER_MODE_FIT;

    int m_nVideoSolution = 100;
    m_lpAgoraEngine->setChannelProfile(CHANNEL_PROFILE_COMMUNICATION);
    m_lpAgoraEngine->setVideoProfile((VIDEO_PROFILE_TYPE)m_nVideoSolution, true);

    m_lpAgoraEngine->enableVideo();
    m_lpAgoraEngine->setupLocalVideo(vc);
    m_lpAgoraEngine->startPreview();
    

    nRet = m_lpAgoraEngine->joinChannel(NULL, ChannelName, NULL, 0);

    m_EngineEventHandler.SetMsgReceiver(wnd);

    return nRet;
}

The second step is to create a WPF program and call dll

Import dll

        [DllImport("VideoCommunicationDll.dll", EntryPoint = "Init", CharSet = CharSet.Auto, CallingConvention = 
         CallingConvention.Cdecl)]
        internal static extern int Init();

        [DllImport("VideoCommunicationDll.dll", EntryPoint = "JoinChannel", CharSet = CharSet.Auto, CallingConvention 
         = CallingConvention.Cdecl)]
        internal static extern int JoinChannel(string channel,IntPtr wnd);

        [DllImport("VideoCommunicationDll.dll", EntryPoint = "LeaverChannel", CharSet = CharSet.Auto, 
        CallingConvention = CallingConvention.Cdecl)]
        internal static extern int LeaverChannel();

Using dll

            int a = Init(); 
            IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(image)).Handle;
            int b = JoinChannel("ssss", hwnd);

Realization effect map

Project Source Code Please Privately Letter Author

Posted by michalurban on Tue, 08 Oct 2019 19:08:57 -0700