Skip to content

Instantly share code, notes, and snippets.

@AntiMoron
Last active December 8, 2016 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AntiMoron/5c907a774003b2bca202f59f9770668d to your computer and use it in GitHub Desktop.
Save AntiMoron/5c907a774003b2bca202f59f9770668d to your computer and use it in GitHub Desktop.
腾讯LVB流推送SDK 测试样例
#include<iostream>
#include<string>
#include<exception>
#include<windows.h>
#include<avsdk/av_sdk.h>
using namespace tencent::av;
using namespace std;
#define ENABLE_CONSOLE
AVContext* context = NULL;
#define Log OutputDebugStringA
HINSTANCE g_hInst;
HWND g_hWnd;
//------------------------------------------------------
// Called every time the application receives a message
//------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
RECT rc;
UINT width;
UINT height;
switch( message )
{
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0;
}
HRESULT InitWindow(HINSTANCE hInstance, int nCmdShow)
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, NULL );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "aMazingWndClass";
wcex.hIconSm = LoadIcon( wcex.hInstance, NULL );
if( !RegisterClassEx( &wcex ) )
return E_FAIL;
// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindowA( "aMazingWndClass", "testtesttest", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
NULL );
if( !g_hWnd )
return E_FAIL;
ShowWindow( g_hWnd, true );
return S_OK;
}
class Handler:public AVRoomMulti::Delegate {
public:
/**
* 音频控制器
*/
AVAudioCtrl *m_pAudCtrl;
/**
* 视频控制器
*/
AVVideoCtrl *m_pVidCtrl;
/**
* 音频管理
**/
AVDeviceMgr *m_pAudMgr;
/**
* 视频管理
*/
AVDeviceMgr *m_pVidMgr;
/**
* 麦克风列表
*/
std::vector<std::pair<std::string/*id*/, std::string/*name*/> > m_micList;
/**
* 成员列表
*/
std::vector<std::pair<std::string/*id*/, std::string/*name*/> > m_playerList;
/**
* 相机列表
*/
std::vector<std::pair<std::string/*id*/, std::string/*name*/> > m_cameraList;
/**
* 当前选中相机的名称
*/
std::string m_selectedCameraId;
// 登录成功!
void OnStartContextComplete(int result) {
if (result != AV_OK)
{
cout << "Error On Start!" << endl;
return;
}
m_pAudCtrl = dynamic_cast<AVAudioCtrl*>(context->GetAudioCtrl());
m_pVidCtrl = dynamic_cast<AVVideoCtrl*>(context->GetVideoCtrl());
if(!m_pAudCtrl || !m_pVidCtrl)
{
cout << "Error On Start!" << endl;
return;
}
cout << "Start Succeed!" << endl;
}
static void OnStartContextCompleteCallback(int32 result, void *pCustomData) {
((Handler*)pCustomData)->OnStartContextComplete(result);
}
static void OnVideoDeviceOperationCallback(AVDeviceMgr *pVidMgr, AVDevice::DeviceOperation oper, const std::string &deviceId, int retCode, void *pCustomData) {
if(!pVidMgr)return;
AVDevice *pDev = pVidMgr->GetDeviceById(deviceId);
if(!pDev)return;
if(pDev->GetType() == DEVICE_CAMERA)
{
if(retCode == AV_OK)
{
Handler* pSdkWrapper = (Handler*)pCustomData;
// pSdkWrapper->SetDefaultCameraState(oper == AVDevice::DEVICE_OPERATION_OPEN);
}
cout << "摄像机运行中" << endl;
// ::PostMessage(GetMainHWnd(), WM_ON_CAMERA_OPERATION, (WPARAM)retCode, oper);
}
//else if(pDev->GetType() == DEVICE_REMOTE_VIDEO)
//{
// //TODO
//}
else if(pDev->GetType() == DEVICE_LOCAL_SCREEN_VIDEO)
{
if(retCode == AV_OK)
{
Handler *pSdkWrapper = (Handler*)pCustomData;
//pSdkWrapper->SetDefaultScreenShareSendState(oper == AVDevice::DEVICE_OPERATION_OPEN);
}
//::PostMessage(GetMainHWnd(), WM_ON_SCREEN_SHARE_SEND_OPERATION, (WPARAM)retCode, oper);
}
//else if(pDev->GetType() == DEVICE_REMOTE_SCREEN_VIDEO)
//{
// //TODO
//}
//else
//{
// //TODO
//}
}
static void OnVideoDeviceChangeCallback(AVDeviceMgr *pVidMgr, void *pCustomData)
{
if(!pVidMgr)return;
Handler *pSdkWrapper = (Handler*)pCustomData;
int retCode = AV_OK;
retCode = pSdkWrapper->GetCameraList(pSdkWrapper->m_cameraList);
if (pSdkWrapper->m_selectedCameraId == "")
{
pSdkWrapper->m_selectedCameraId = retCode == AV_OK ? pSdkWrapper->m_cameraList[0].first : "";
}
//::PostMessage(GetMainHWnd(), WM_ON_CAMERA_CHANGE, NULL, NULL);
}
virtual void OnEnterRoomComplete(int result) {
m_pAudMgr = static_cast<AVDeviceMgr*>(context->GetAudioDeviceMgr());
m_pVidMgr = static_cast<AVDeviceMgr*>(context->GetVideoDeviceMgr());
m_pVidMgr->SetDeviceOperationCallback(OnVideoDeviceOperationCallback, this);
m_pVidMgr->SetDeviceChangeCallback(OnVideoDeviceChangeCallback, this);
//创建房间后,设置远程视频回调
AVRemoteVideoDevice *pVideoDevice = (AVRemoteVideoDevice*)m_pVidMgr->GetDeviceById(DEVICE_REMOTE_VIDEO);
if (pVideoDevice)
{
//视频渲染前,先设定渲染画面大小和颜色格式。这些参数设置只影响到渲染,不影响到编解码。
m_pVidMgr->SelectOutputDevice(DEVICE_REMOTE_VIDEO, true);
//
//AVSupportVideoPreview::PreviewParam m_remoteVideoParam;
//pVideoDevice->SetPreviewParam(m_remoteVideoParam.device_id, m_remoteVideoParam.width, m_remoteVideoParam.height, m_remoteVideoParam.color_format);
//pVideoDevice->SetPreviewCallback(&Handler::OnRemoteVideo, this);
}
//AVRemoteScreenVideoDevice *pScreenShareRecvDevice = (AVRemoteScreenVideoDevice*)m_pVidMgr->GetDeviceById(DEVICE_REMOTE_SCREEN_VIDEO);
//if (pScreenShareRecvDevice)
//{
// //视频渲染前,先设定渲染画面大小和颜色格式。这些参数设置只影响到渲染,不影响到编解码。
// m_pVidMgr->SelectOutputDevice(DEVICE_REMOTE_SCREEN_VIDEO, true);
// pScreenShareRecvDevice->SetPreviewParam(m_screenRecvParam.device_id, m_screenRecvParam.width, m_screenRecvParam.height, m_screenRecvParam.color_format);
// pScreenShareRecvDevice->SetPreviewCallback(&SdkWrapper::OnRemoteVideo, this);
//}
/*
int retCode = AV_OK;
retCode = GetCameraList(m_cameraList);
if (m_selectedCameraId == "")
{
m_selectedCameraId = retCode == AV_OK ? m_cameraList[0].first : "";
}
m_pAudMgr->SetDeviceOperationCallback(OnAudioDeviceOperationCallback, this);
m_pAudMgr->SetDeviceDetectNotify(OnAudioDeviveDetectNotify,this);
retCode = GetMicList(m_micList);
m_selectedMicId = retCode == AV_OK ? m_micList[0].first : "";
retCode = GetPlayerList(m_playerList);
m_selectedPlayerId = retCode == AV_OK ? m_playerList[0].first : "";
m_pRoom = dynamic_cast<AVRoomMulti*>(m_pContext->GetRoom());
if(!m_pRoom)
{
::PostMessage(GetMainHWnd(), WM_ON_ENTER_ROOM, (WPARAM)AV_ERR_FAILED, 0);
return;
}
::PostMessage(GetMainHWnd(), WM_ON_ENTER_ROOM, (WPARAM)result, 0);
*/
}
virtual void OnExitRoomComplete() {
std::cout << "Exit Room! " << std::endl; }
virtual void OnRoomDisconnect(int32 reason) {
std::cout << "Leave! " << reason << std::endl;
}
virtual void OnEndpointsUpdateInfo(AVRoomMulti::EndpointEventId event_id, std::vector<std::string> identifier_list){}
virtual void OnPrivilegeDiffNotify(int32 privilege){}
virtual void OnSemiAutoRecvCameraVideo(std::vector<std::string> identifier_list){}
virtual void OnCameraSettingNotify(int32 width, int32 height, int32 fps){}
/**
* 拿到摄像头设备列表
*/
virtual int GetCameraList(std::vector<std::pair<std::string/*id*/, std::string/*name*/> > &cameraList)
{
if(!context || !m_pAudCtrl || !m_pVidCtrl || !m_pVidMgr) return AV_ERR_FAILED;
AVDevice **ppCameraList = NULL;
int cameraCount = m_pVidMgr->GetDeviceByType(DEVICE_CAMERA, &ppCameraList);
if(ppCameraList == NULL || cameraCount == 0)
{
return AV_ERR_DEVICE_NOT_EXIST;
}
for(int i = 0; i < cameraCount; i++)
{
std::pair<std::string/*id*/, std::string/*name*/> camera;
camera.first = ppCameraList[i]->GetId();
camera.second = ppCameraList[i]->GetInfo().name;
cameraList.push_back(camera);
}
if(ppCameraList)delete []ppCameraList;//业务侧负责释放这个数组。
return AV_OK;
}
};
static Handler* fuckingHandler = new Handler;
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
#ifdef ENABLE_CONSOLE
AllocConsole();
FILE * m_new_stdout_file = nullptr;
freopen_s(&m_new_stdout_file, "CONOUT$", "w+t", stdout);
#endif
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
HMODULE m_hMoude = ::LoadLibraryA("qavsdk.dll");
// 拿到版本号
auto getVersionProc = (PROC_AVAPI_GetVersion)::GetProcAddress(m_hMoude, "AVAPI_GetVersion");
cout << "当前版本号是" << getVersionProc() << endl;
// 登录
// 开启崩溃报告
auto enableCrashReportProc = (PROC_AVAPI_EnableCrashReport)::GetProcAddress(m_hMoude, "AVAPI_EnableCrashReport");
enableCrashReportProc(true, false);
// 创建context
auto createContext = (PROC_AVAPI_CreateContext)::GetProcAddress(m_hMoude, "AVAPI_CreateContext");
context = (AVContext*)(*createContext)();
// 设置对应context属性
context->SetSpearEngineMode(SPEAR_EGINE_MODE_CUSTOM); //开启Spear是SPEAR_EGINE_MODE_WEBCLOUD
// 初始化参数
AVContext::StartParam startParam;
startParam.sdk_app_id = 1104062745;
startParam.account_type = "107";
startParam.app_id_at3rd = "1104062745";
startParam.identifier = "antimoron_123123123"; // 瞎jb测试
// 据说是start context
//context->Start(param, &SdkWrapper::OnStartContextCompleteCallback, this);
int startError = context->Start(startParam, &Handler::OnStartContextCompleteCallback, fuckingHandler);
if(startError != AV_OK) {
return 0;
}
Sleep(5000);
// 选择一个房间
AVRoomMulti::EnterParam enterRoomParam;
string relationId = "123123"; // 拿到群组id (relationId)
string avControlRole = ""; // 流控制角色名
enterRoomParam.relation_id = atoi(relationId.c_str());
enterRoomParam.control_role = avControlRole; //
/*if( 0 != m_btnCheckHasVideoSendAuth.GetCheck() &&
0 != m_btnCheckHasAudioSendAuth.GetCheck() &&
0 != m_btnCheckHasVideoRevAuth.GetCheck() &&
0 != m_btnCheckHasAudioRevAuth.GetCheck() )*/
{
enterRoomParam.auth_bits = AUTH_BITS_DEFAULT; //权限位;默认值是拥有所有权限。TODO:请业务侧填根据自己的情况填上权限位。
}
/*else
{
enterRoomParam.auth_bits = AUTH_BITS_CREATE_ROOM | AUTH_BITS_JOIN_ROOM | AUTH_BITS_RECV_SCREEN_VIDEO;
if( 0 != m_btnCheckHasVideoSendAuth.GetCheck() )
enterRoomParam.auth_bits |= AUTH_BITS_SEND_CAMERA_VIDEO;
if( 0 != m_btnCheckHasAudioSendAuth.GetCheck() )
enterRoomParam.auth_bits |= AUTH_BITS_SEND_AUDIO;
if( 0 != m_btnCheckHasVideoRevAuth.GetCheck() )
enterRoomParam.auth_bits |= AUTH_BITS_RECV_CAMERA_VIDEO;
if( 0 != m_btnCheckHasAudioRevAuth.GetCheck() )
enterRoomParam.auth_bits |= AUTH_BITS_RECV_AUDIO;
}*/
//设置音视频编解码参数。如果需要设定特定的音视频参数,请在创建房间前设置好。
//主播场景,支持设置自定义音视频参数。
// 做一层校验
if((startParam.account_type == "107" && startParam.app_id_at3rd == "1104062745" && startParam.sdk_app_id == 1104062745)) {
//音频场景策略;有三种取值:实时通信场景,直播场景中的主播人员,直播场景中的听众;TODO:请业务侧根据自己的情况填这个值。
enterRoomParam.audio_category = AUDIO_CATEGORY_MEDIA_PLAY_AND_RECORD;//直播场景
} else {
//音频场景策略;有三种取值:实时通信场景,直播场景中的主播人员,直播场景中的听众;TODO:请业务侧根据自己的情况填这个值。
enterRoomParam.audio_category = AUDIO_CATEGORY_VOICECHAT;//实时通信场景
}
// 这个控制是否音视频服务器自动创建房间
bool isAutoCreateSDKRoom = true;
enterRoomParam.create_room = isAutoCreateSDKRoom;
if (isAutoCreateSDKRoom) {
enterRoomParam.video_recv_mode = VIDEO_RECV_MODE_SEMI_AUTO_RECV_CAMERA_VIDEO;
} else {
enterRoomParam.video_recv_mode = VIDEO_RECV_MODE_MANUAL;
}
int enterRoomResponse = context->EnterRoom(fuckingHandler, enterRoomParam);
cout << enterRoomResponse << endl;
if(enterRoomResponse != AV_OK) {
cout << "进入房间失败" << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment