tencent cloud

实时音视频

动态与公告
产品动态
产品近期公告
关于 TRTC Live 正式上线的公告
关于TRTC Conference 正式版上线的公告
Conference 商业化版本即将推出
关于多人音视频 Conference 开启内测公告
关于音视频通话 Call 正式版上线的公告
关于腾讯云音视频终端 SDK 播放升级及新增授权校验的公告
关于 TRTC 应用订阅套餐服务上线的相关说明
产品简介
产品概述
基本概念
产品功能
产品优势
应用场景
性能数据
购买指南
计费概述
免费时长说明
月订阅
现收现付
TRTC 逾期与暂停政策
常见问题解答
退款说明
新手指引
Demo 体验
视频通话 SDK
组件介绍
开通服务
跑通 Demo
快速接入
离线唤醒
会话聊天
云端录制
AI 降噪
界面定制
Chat 集成通话能力
更多特性
无 UI 集成
服务端 API
客户端 API
解决方案
错误码表
发布日志
常见问题
视频会议 SDK
组件介绍(TUIRoomKit)
开通服务(TUIRoomKit)
跑通 Demo(TUIRoomKit)
快速接入(TUIRoomKit)
屏幕共享(TUIRoomKit)
预定会议(TUIRoomKit)
会中呼叫(TUIRoomKit)
界面定制(TUIRoomKit)
虚拟背景(TUIRoomKit)
会议控制(TUIRoomKit)
云端录制(TUIRoomKit)
AI 降噪(TUIRoomKit)
会中聊天(TUIRoomKit)
机器人推流(TUIRoomKit)
更多特性(TUIRoomKit)
客户端 API(TUIRoomKit)
服务端 API(TUIRoomKit)
常见问题(TUIRoomKit)
错误码 (TUIRoomKit)
SDK更新日志(TUIRoomKit)
直播与语聊 SDK
Live 视频直播计费说明
组件介绍
开通服务(TUILiveKit)
跑通 Demo
无 UI 集成
UI 自定义
直播监播
视频直播
语聊房
高级功能
客户端 API
服务端 API
错误码
发布日志
常见问题
RTC Engine
开通服务
SDK 下载
API-Example
接入指引
API-参考手册
高级功能
AI 集成
概述
MCP 配置
Skills 配置
集成指南
常见问题
RTC RESTFUL API
History
Introduction
API Category
Room Management APIs
Stream mixing and relay APIs
On-cloud recording APIs
Data Monitoring APIs
Pull stream Relay Related interface
Web Record APIs
AI Service APIs
Cloud Slicing APIs
Cloud Moderation APIs
Making API Requests
Call Quality Monitoring APIs
Usage Statistics APIs
Data Types
Appendix
Error Codes
控制台指南
应用管理
套餐包管理
用量统计
监控仪表盘
开发辅助
解决方案
实时合唱
常见问题
迁移指南
计费相关
功能相关
UserSig 相关
应对防火墙限制相关
缩减安装包体积相关
Andriod 与 iOS 相关
Web 端相关
Flutter 相关
Electron 相关
TRTCCalling Web 相关
音视频质量相关
其他问题
旧版文档
RTC RoomEngine SDK(旧)
集成 TUIRoom (Web)
集成 TUIRoom (Android)
集成 TUIRoom (iOS)
集成 TUIRoom (Flutter)
集成 TUIRoom (Electron)
TUIRoom API 查询
实现云端录制与回放(旧)
监控仪表盘计费(旧)
协议与策略
安全合规认证
安全白皮书
信息安全说明
服务等级协议
苹果隐私策略:PrivacyInfo.xcprivacy
TRTC 政策
隐私协议
数据处理和安全协议
词汇表
文档实时音视频

跑通直播模式(Windows)

聚焦模式
字号
最后更新时间: 2022-01-10 10:51:24

文档导读

本文主要介绍如何基于 TRTC SDK 实现一个既支持视频连麦,又支持上万人高并发观看的在线直播功能。本文仅罗列最常用的几个接口,如果您希望了解更多的接口函数,请参见 API 文档

示例代码

所属平台
示例代码
Windows(MFC)
Windows(Duilib)
Windows(C#)

在线直播

1. 初始化 SDK

使用 TRTC SDK 的第一步,是先获取TRTCCloud的单例对象,并注册监听 SDK 事件的回调。
继承ITRTCCloudCallback事件回调接口类,重写关键事件的回调接口,包括本地用户进房/退房事件、远端用户加入/退出事件、错误事件和警告事件等。
调用addCallback接口注册监听 SDK 事件。
注意:
如果addCallback注册 N 次,同一个事件, SDK 就会触发 N 次回调,建议只调用一次 addCallback
C++版
C#版
// TRTCMainViewController.h

// 继承 ITRTCCloudCallback 事件回调接口类
class TRTCMainViewController : public ITRTCCloudCallback
{
public:
TRTCMainViewController();
virtual ~TRTCMainViewController();

virtual void onError(TXLiteAVError errCode, const char* errMsg, void* arg);
virtual void onWarning(TXLiteAVWarning warningCode, const char* warningMsg, void* arg);
virtual void onEnterRoom(uint64_t elapsed);
virtual void onExitRoom(int reason);
virtual void onRemoteUserEnterRoom(const char* userId);
virtual void onRemoteUserLeaveRoom(const char* userId, int reason);
virtual void onUserVideoAvailable(const char* userId, bool available);
virtual void onUserAudioAvailable(const char* userId, bool available);
...
private:
ITRTCCloud * m_pTRTCSDK = NULL;
...
}

// TRTCMainViewController.cpp

TRTCMainViewController::TRTCMainViewController()
{
// 创建 TRTCCloud 实例
m_pTRTCSDK = getTRTCShareInstance();

// 注册 SDK 回调事件
m_pTRTCSDK->addCallback(this);
}

TRTCMainViewController::~TRTCMainViewController()
{
// 取消监听 SDK 事件
if(m_pTRTCSDK) {
m_pTRTCSDK->removeCallback(this);
}

// 释放 TRTCCloud 实例
if(m_pTRTCSDK != NULL) {
destroyTRTCShareInstance();
m_pTRTCSDK = null;
}
}

// 错误通知是需要监听的,错误通知意味着 SDK 无法继续运行
virtual void TRTCMainViewController::onError(TXLiteAVError errCode, const char* errMsg, void* arg)
{
if (errCode == ERR_ROOM_ENTER_FAIL) {
LOGE(L"onError errorCode[%d], errorInfo[%s]", errCode, UTF82Wide(errMsg).c_str());
exitRoom();
}
}

// TRTCMainForm.cs

// 继承 ITRTCCloudCallback 事件回调接口类
public partial class TRTCMainForm : Form, ITRTCCloudCallback, ITRTCLogCallback
{
...
private ITRTCCloud mTRTCCloud;
...

public TRTCMainForm(TRTCLoginForm loginForm)
{
InitializeComponent();
this.Disposed += new EventHandler(OnDisposed);
// 创建 TRTCCloud 实例
mTRTCCloud = ITRTCCloud.getTRTCShareInstance();
// 注册 SDK 回调事件
mTRTCCloud.addCallback(this);
...
}

private void OnDisposed(object sender, EventArgs e)
{
if (mTRTCCloud != null)
{
// 取消监听 SDK 事件
mTRTCCloud.removeCallback(this);
// 释放 TRTCCloud 实例
ITRTCCloud.destroyTRTCShareInstance();
mTRTCCloud = null;
}
...
}
...
// 错误通知是需要监听的,错误通知意味着 SDK 无法继续运行
public void onError(TXLiteAVError errCode, string errMsg, IntPtr arg)
{
if (errCode == TXLiteAVError.ERR_ROOM_ENTER_FAIL) {
exitRoom();
}
...
}
...
}


2. 组装 TRTCParams

TRTCParams 是 SDK 最关键的一个参数,它包含如下四个必填的字段:sdkAppId、userId、userSig 和 roomId。
SDKAppID 进入腾讯云实时音视频 控制台,如果您还没有应用,请创建一个,即可看到 SDKAppID。
userId 您可以随意指定,由于是字符串类型,可以直接跟您现有的账号体系保持一致,但请注意,同一个音视频房间里不应该有两个同名的 userId
userSig 基于 SDKAppID 和 userId 可以计算出 userSig,计算方法请参见 如何计算及使用 UserSig
roomId 房间号是数字类型,您可以随意指定,但请注意,同一个应用里的两个音视频房间不能分配同一个 roomId。如果您想使用字符串形式的房间号,请使用 TRTCParams 中的 strRoomId。

3. 主播预览摄像头画面

TRTC SDK 并不会默认打开本地的摄像头采集,startLocalPreview 可以开启本地的摄像头并显示预览画面,stopLocalPreview 则会关闭。
启动本地预览前,可调用 setLocalViewFillMode 指定视频显示模式为 FillFit 模式。两种模式下视频尺寸都是等比缩放,区别在于:
Fill 模式优先保证视窗被填满。如果缩放后的视频尺寸与显示视窗尺寸不一致,多出的视频将被截掉。
Fit 模式则优先保证视频内容全部显示。如果缩放后的视频尺寸与显示视窗尺寸不一致,未被填满的视窗区域将使用黑色填充。
C++版
C#版
void TRTCMainViewController::onEnterRoom(uint64_t elapsed)
{
// 获取渲染窗口的句柄。
CWnd *pLocalVideoView = GetDlgItem(IDC_LOCAL_VIDEO_VIEW);
HWND hwnd = pLocalVideoView->GetSafeHwnd();

if(m_pTRTCSDK)
{
// 调用 SDK 接口设置渲染模式和渲染窗口。
m_pTRTCSDK->setLocalViewFillMode(TRTCVideoFillMode_Fit);
m_pTRTCSDK->startLocalPreview(hwnd);
}

}

// TRTCMainForm.cs
public void onEnterRoom(int result)
{
...
// 获取渲染窗口的句柄。
IntPtr ptr = GetHandle();
if (mTRTCCloud != null)
{
// 调用 SDK 接口设置渲染模式和渲染窗口。
mTRTCCloud.setLocalViewFillMode(TRTCVideoFillMode_Fit);
mTRTCCloud.startLocalPreview(ptr);
}
...
}


4. 主播开启麦克风采集

TRTC SDK 并不会默认打开本地的麦克风采集,主播调用 startLocalAudio 可以开启本地的声音采集并将音视频数据广播出去,stopLocalAudio 则会关闭。您可以在 startLocalPreview 之后继续调用 startLocalAudio
说明:
startLocalAudio 会检查麦克风使用权限,如果没有麦克风权限,SDK 会向用户申请开启。

5. 主播创建新房间开播

主播可以使用 enterRoom 创建一个音视频房间,参数 TRTCParams 中的 roomId 用于指定房间号,同时,我们还需要将 role 字段指定为 TRTCRoleAnchor(主播)。
appScene 参数指定 SDK 的应用场景,本文档中我们使用 TRTCAppSceneLIVE(在线直播)。
如果创建成功,SDK 会回调 onEnterRoom 接口,参数:elapsed 代表进入耗时,单位:ms。
如果创建失败,SDK 会回调 onError 接口,参数:errCode(错误码 ERR_ROOM_ENTER_FAIL,错误码可参考 TXLiteAVCode.h)、errMsg(错误原因)、extraInfo(保留参数)。
C++版
C#版
// TRTCMainViewController.cpp

void TRTCMainViewController::startBroadCasting()
{
// TRTCParams 定义参考头文件 TRTCCloudDef.h
TRTCParams params;
params.sdkAppId = sdkappid;
params.userId = userid;
params.userSig = usersig;
params.roomId = 908; // 输入您想进入的房间
params.role = TRTCRoleAnchor; //主播
if(m_pTRTCSDK)
{
m_pTRTCSDK->enterRoom(params, TRTCAppSceneLIVE);
}
}

void TRTCMainViewController::onError(TXLiteAVError errCode, const char* errMsg, void* arg)
{
if(errCode == ERR_ROOM_ENTER_FAIL)
{
LOGE(L"onError errorCode[%d], errorInfo[%s]", errCode, UTF82Wide(errMsg).c_str());
// 检查 userSig 是否合法、网络是否正常等
}
}

...

void TRTCMainViewController::onEnterRoom(uint64_t elapsed)
{
LOGI(L"onEnterRoom elapsed[%lld]", elapsed);

// 启动本地的视频预览,请参考下文设置视频编码参数和预览本地摄像头画面的内容
}

// TRTCMainForm.cs

public void createRoom()
{
// TRTCParams 定义参考头文件TRTCCloudDef.h
TRTCParams @params = new TRTCParams();
@params.sdkAppId = sdkappid;
@params.userId = userid;
@params.userSig = usersig;
@params.roomId = 908; // 输入您想进入的房间
@params.role = TRTCRoleAnchor; //主播
if(mTRTCCloud != null)
{
mTRTCCloud.enterRoom(@params, TRTCAppSceneLIVE);
}
}

...

public void onError(TXLiteAVError errCode, string errMsg, IntPtr arg)
{
if(errCode == TXLiteAVError.ERR_ROOM_ENTER_FAIL)
{
Log.E(String.Format("errCode : {0}, errMsg : {1}, arg = {2}", errCode, errMsg, arg));
// 检查 userSig 是否合法、网络是否正常等
}
}

...

public void onEnterRoom(int result)
{
// 启动本地的视频预览,请参考下文设置视频编码参数和预览本地摄像头画面的内容
}


6. 主播开关隐私模式

直播过程中,主播可能出于隐私目的希望屏蔽本地的音视频数据,可以调用 muteLocalVideo 屏蔽本地的视频采集,调用 muteLocalAudio 屏蔽本地的音频采集。

7. 观众加入房间观看

观众调用 enterRoom 可以进入一个音视频房间,参数 TRTCParams 中的 roomId 用于指定房间号。 appScene 同样填写 TRTCAppSceneLIVE(在线直播),但 role 字段需要指定为 TRTCRoleAudience(观众)。
C++版
C#版
void TRTCMainViewController::startPlaying()
{
// TRTCParams 定义参考头文件 TRTCCloudDef.h
TRTCParams params;
params.sdkAppId = sdkappid;
params.userId = userid;
params.userSig = usersig;
params.roomId = 908; // 输入您想进入的房间
params.role = TRTCRoleAudience; //观众
if(m_pTRTCSDK)
{
m_pTRTCSDK->enterRoom(params, TRTCAppSceneLIVE);
}
}

public void startPlaying()
{
// TRTCParams 定义参考头文件TRTCCloudDef.h
TRTCParams @params = new TRTCParams();
@params.sdkAppId = sdkappid;
@params.userId = userid;
@params.userSig = usersig;
@params.roomId = 908; // 输入您想进入的房间
@params.role = TRTCRoleAudience; //观众
if(mTRTCCloud != null)
{
mTRTCCloud.enterRoom(@params, TRTCAppSceneLIVE);
}
}

如果主播在房间里,观众会通过 TRTCCloudDelegate 中的 onUserVideoAvailable 回调获知主播的 userid。然后观众可以调用 startRemoteView 方法来显示主播的视频画面。
通过 setRemoteViewFillMode 可以指定视频显示模式为 FillFit 模式。两种模式下视频尺寸都是等比缩放,区别在于:
Fill 模式:优先保证视窗被填满。如果缩放后的视频尺寸与显示视窗尺寸不一致,多出的视频将被截掉。
Fit 模式:优先保证视频内容全部显示。如果缩放后的视频尺寸与显示视窗尺寸不一致,未被填满的视窗区域将使用黑色填充。
C++版
C#版
void TRTCMainViewController::onUserVideoAvailable(const char* userId, bool available){
if (available) {
// 获取渲染窗口的句柄。
CWnd *pRemoteVideoView = GetDlgItem(IDC_REMOTE_VIDEO_VIEW);
HWND hwnd = pRemoteVideoView->GetSafeHwnd();

// 设置远端用户视频的渲染模式。
m_pTRTCSDK->setRemoteViewFillMode(TRTCVideoFillMode_Fill);
// 调用 SDK 接口播放远端用户流。
m_pTRTCSDK->startRemoteView(userId, hwnd);
} else {
m_pTRTCSDK->stopRemoteView(userId);
}
}

public void onUserVideoAvailable(string userId, bool available)
{
if (available)
{
// 获取窗口句柄
IntPtr ptr = GetHandleAndSetUserId(pos, userId, false);
SetVisableInfoView(pos, false);
// 设置远端用户视频的渲染模式。
mTRTCCloud.setRemoteViewFillMode(userId, TRTCVideoFillMode.TRTCVideoFillMode_Fit);
// 调用 SDK 接口播放远端用户流。
mTRTCCloud.startRemoteView(userId, ptr);
}
else
{
mTRTCCloud.stopRemoteView(userId);
...
}
}

注意:
在 TRTCAppSceneLIVE 模式下,同一个房间中的观众(TRTCRoleAudience)人数没有限制。
每个端在应用场景 appScene 上必须要进行统一,否则会出现一些不可预料的问题。

8. 观众跟主播连麦

主播和观众都可以通过 TRTCCloud 提供的 switchRole 进行角色间的相互切换,最常见的场景是观众跟主播连麦:观众可以通过该接口切换成“小主播”,然后跟房间里原来的“大主播”进行连麦互动。

9. 退出房间

调用 exitRoom 方法退出房间。无论当前是否还在通话中,调用该方法会把视频通话相关的所有资源释放掉。在您调用 exitRoom 之后,SDK 会进入一个复杂的退房握手流程,当 SDK 回调 onExitRoom 方法时才算真正完成资源的释放。
C++版
C#版
// TRTCMainViewController.cpp

void TRTCMainViewController::exitRoom()
{
if(m_pTRTCSDK)
{
m_pTRTCSDK->exitRoom();
}
}
....
void TRTCMainViewController::onExitRoom(int reason)
{
// 退房成功,reason 参数保留,暂未使用。

}

// TRTCMainForm.cs

public void OnExit()
{
if(mTRTCCloud != null)
{
mTRTCCloud.exitRoom();
}
}
...
public void onExitRoom(int reason)
{
// 退房成功
...
}


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈